class _height_dragger(DelegatingInstanceOrExpr): # args #e coordsystem? for now let x/y be the way it spreads, z be the height height_ref = Arg(StateRef, doc="stateref to a height variable") # appearance/behavior #e should draw some "walls" too, and maybe limit the height # note: the following sets up a cyclic inter-Instance ref ( drag_handler -> delegate -> drag_handler); # it works since the actual refs are symbolic (getattr_Expr(_self, 'attr'), not evalled except when used). drag_handler = Instance( xxx_drag_behavior(_self._delegate, height_ref, Ray(ORIGIN, DX))) ### DX for initial test, then DZ # note: passing _self._delegate (not _self.delegate) fixed my "undiagnosed bug". delegate = DraggableObject( Image( "blueflake.png" ), ###e needs an option to be visible from both sides (default True, probably) ## constrain_delta = _self.constrain_delta, ###IMPLEM constrain_delta in DraggableObject ## delta_stateref = height_ref ###IMPLEM delta_stateref [done] (and rename it); and change this to make height_ref a number not vector; ##e and maybe include the constraint in that transform, since it seems implicit in it anyway. ####HOW in semantics? # ... = PropertyRef(DZ * height_ref.value, Set( height_ref.value, project_onto_unit_vector( _something, DZ )) # ... = TransformStateRef( height_ref, ... ) # funcs? or formula in terms of 1 or 2 vars? with a chance at solving it?? ##e _kluge_drag_handler=drag_handler) ## def constrain_delta(self, delta): ## not yet - called ## return project_onto_unit_vector( delta, DZ) pass
class _height_dragger_3(DelegatingInstanceOrExpr): # args height_ref = Arg(StateRef, doc = "stateref to a height variable") direction = Arg(Vector) sbar_text = Option(str, "_height_dragger_3") range = Option(tuple_Expr, None, doc = "range limit of height") # appearance/behavior #e should draw some "walls" too, and maybe limit the height drag_handler = Instance( DragBehavior_AlongLine( _self._delegate, height_ref, ## Ray(ORIGIN, DX) # works ## Ray(ORIGIN, DZ) # works, but only if you trackball it (as expected)... ## Ray(ORIGIN, direction) # fails -- Ray is an ordinary class, not an expr! ###FIX call_Expr(Ray, ORIGIN, direction), # this workaround fixes it for now. # (in prior commit it didn't fix it, but only because of a typo in the testexpr defs # in tests.py, which meant I passed DZ when I thought I passed DX.) range = range )) ### NOTE: drag_handler is also being used to compute the translation from the height, even between drags. delegate = Overlay( Highlightable( Translate( Image("blueflake.png"), ###e needs an option to be visible from both sides (default True, probably) drag_handler._translation ###k ok?? only if that thing hangs around even in between drags, i guess! #e #k not sure if this code-commoning is good, but it's tempting. hmm. ), sbar_text = sbar_text, behavior = drag_handler ), Translate(Rect(2), direction * -0.01), Line(ORIGIN, ORIGIN + direction * height_ref.value, white) ) pass
def _C__value(self): mt = self.mt # fails, recursion in self.delegate computation -- why? related to parent AttributeError: win? must be. ###e NEED BETTER ERROR MESSAGE from exception when computing self.mt by formula from caller. # It did have the attrerror, but buried under (and then followed by) too much other stuff (not stopping) to notice. node = self.node pixmap = mt.get_pixmap_for_dragging_nodes('move', [node]) # (drag_type, nodes); method defined in TreeWidget.py #e includes "moving n items", need to make it leave that out if I pass None for drag_type print pixmap # <constants.qt.QPixmap object at 0x10fbc2a0> #e make Image (texture) from pixmap -- how? # - pass the pixmap into ImageUtils somehow (won't be hard, could go in in place of the filename) # - worry about how it works in our texture-caching key (won't be hard) # - teach ImageUtils how to get a PIL image or equivalent data from it -- requires learning about QPixmap, image formats # MAYBE NOT WORTH IT FOR NOW, since I can get the icons anyway, and for text I'd rather have a Qt-independent path anyway, # if I can find one -- tho I predict I'll eventually want this one too, so we can make GL text look the same as Qt text. # Note: PixelGrabber shows how to go in the reverse direction, from GL to Qt image. # Guess: QPixmap or QImage docs will tell me a solution to this. So when I want nice text it might be the quickest way. # (Also worth trying PIL's builtin text-image makers, but I'm not sure if we have them in NE1 even tho we have PIL.) # The other way is to grab actual screenshots (of whatever) and make my own font-like images. Not ideal, re user-reconfig # of font or its size! # # Here are hints towards using Qt: turn it into QImage, which boasts # "The QImage class provides a hardware-independent pixmap representation with direct access to the pixel data." # and then extract the data -- not yet known how much of this PyQt can do. # # - QImage QPixmap::convertToImage () const # ##uchar * QImage::scanLine ( int i ) const ## ##Returns a pointer to the pixel data at the scanline with index i. The first ##scanline is at index 0. ## ##The scanline data is aligned on a 32-bit boundary. ## ##Warning: If you are accessing 32-bpp image data, cast the returned pointer ##to QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. ##You cannot use the uchar* pointer directly, because the pixel format depends ##on the byte order on the underlying platform. Hint: use qRed(), qGreen() and ##qBlue(), etc. (qcolor.h) to access the pixels. image = pixmap.convertToImage() print image # <constants.qt.QImage object at 0x10fe1900> print "scanlines 0 and 1 are", image.scanLine(0), image.scanLine(1) # <sip.voidptr object at 0x5f130> <sip.voidptr object at 0x5f130> -- hmm, same address print "image.bits() is",image.bits() # image.bits() is <sip.voidptr object at 0x5f130> -- also same address print "\n*** still same address when all collected at once?:" # no. good. objs = [image.scanLine(0), image.scanLine(1), image.bits()] for obj in objs: print obj print # but what can i do with a <sip.voidptr object>? Can Python buffers help?? Can PIL use it somehow?? # Or do I have to write a C routine? Or can I pass it directly to OpenGL as texture data, if I get the format right? # Hmm, maybe look for Qt/OpenGL example code doing this, even if in C. ##e _value = Image( "notfound") env = self.env ipath = self.ipath return _value._e_eval( env, ('v', ipath)) # 'v' is wrong, self.env is guess
class PixelTester( InstanceOrExpr, DelegatingMixin ): # ought to be InstanceMacro but trying this alternate style just to see it # args testexpr = Arg(Widget2D) # instantiated right here, hope that's ok testname = Arg(str) # required for now, used to form filename # value filename = format_Expr("/tmp/%s.jpg", testname) delegate = SimpleColumn( TextRect( "saved image from PRIOR session, in blue box" ), # kluge: execute this first, so we read file before writing it Boxed(bordercolor=blue)(Image(filename)), Spacer(0.3), TextRect("live widget, in purple box"), Boxed(bordercolor=purple)(PixelGrabber(testexpr, filename)), ##e and put current session image here, for comparison, or put top on in a tab control for flicker test ) pass # end of class PixelTester
pass # == # exprs for images # overlay image (command-specific icon) # This draws a 22 x 22 icon in the upper left corner of the glpane. # I need to be able to change the origin of the icon so it can be drawn at # a different location inside the confirmation corner, but I cannot # figure out how to do this. I will discuss with Bruce soon. -Mark 2008-03-23 _overlay_image = Image(convert = 'RGBA', decal = False, blend = True, #ideal_width = 22, #ideal_height = 22, size = Rect(22 * PIXELS)) from exprs.transforms import Translate from exprs.Exprs import V_expr from exprs.Rect import Spacer def _expr_for_overlay_imagename(imagename, dx = 0, dy = 0): # WARNING: this is not optimized (see comment for _expr_for_imagename()). image_expr = _overlay_image( imagename ) # NOTE: If the desired dx,dy depends on other settings, # like whether one or two CC buttons are shown, # then it's simplest to make more variants of this expr, # with dx, dy hardcoded differently in each one. # Or if that's not practical, let me know and I'll