Beispiel #1
0
    def on_drag_bg(self):
        # note: so far, anyway, called only for drag after click on empty space, not from drag after click on existing node
        point = self.current_event_mousepoint()
        lastnode = self.newnode  # btw nothing clears this on mouseup, so in theory it could be left from a prior drag
        ##        try:
        ##            lastipath = lastnode.ipath[0]
        ##        except:
        ##            lastipath = -1
        ##        # print "on_drag_bg %d" % lastipath, point###  # this shows no error in retaining correct lastnode -- that's not the bug
        ## print "on_drag_bg"
        newpos = point + DZ * DZFUZZ  # used for different things, depending

        what = kluge_dragtool_state()  ###IMPLEM better
        if what == 'draw':
            # make a blue dot showing the drag path, without moving the main new node (from the click)
            node_expr = Vertex(newpos, Center(Rect(0.1, 0.1, blue)))
            self.world.make_and_add(
                node_expr, type="dot"
            )  #070206 added type = "dot" -- note, not deducible from the expr!!
        elif what == 'polyline':
            if not lastnode:
                print "bug: no self.newnode!!!"
            else:
                if not isinstance(lastnode, polyline):
                    lastnode = self.newnode = self.world.make_and_add(
                        polyline(lastnode), type="polyline")
                lastnode.add_point(newpos)
        elif what == 'drag':
            # drag the new node made by the click
            if not lastnode:
                print "bug: no self.newnode!!!"
            else:
                lastnode.pos = newpos
            pass
        return
Beispiel #2
0
class NativeImage(
        DelegatingInstanceOrExpr
):  #070304 [works (imperfectly? see comments there) in testexpr_11u6]
    """
    Show an image in its native size and aspect ratio --
    that is, one image pixel == one texture pixel == one screen pixel,
    when the local coordsys is the standard viewing coordsys.
       Note: callers are advised to enclose this inside Highlightable, at least until
    we add local glnames to fix the bug of all bareMotion over non-Highlightable drawing
    causing redraws.
    """
    # args
    filename = Arg(str, "x")  #e better type, eg Filename?
    ###BUG: ought to take all options and pass them on to Image [070403 comment]
    # formulae [non-public in spite of the names]
    im1_expr = Image(filename,
                     use_mipmaps=True,
                     ideal_width=-1,
                     ideal_height=-1)
    # customize Image to use native texture size (but without controlling the aspect ratio for display)
    ###e consider also including the options that IconImage does, or options passed by caller
    # (but passing general opts (like python **kws syntax can do) is nim in the exprs language)
    im1 = Instance(
        im1_expr)  # grab an actual image so we can find out its native size
    th = im1._texture_holder  # gets its _texture_holder object
    imops = th._image  # get its nEImageOps object
    # appearance
    delegate = im1_expr(
        size=Center(Rect(imops.orig_width * PIXELS, imops.orig_height *
                         PIXELS)))
    # (implem note: this customizes im1_expr options even though its args (filename) are already supplied.
    #  That used to give a warning but apparently doesn't now. If it does again someday,
    #  it's easy to fix here -- just give filename in each instantation rather than in im1_expr.)
    pass
Beispiel #3
0
    def on_press(self):
        point = self.current_event_mousepoint()
        newpos = point + DZ * DZFUZZ  # kluge: move it slightly closer so we can see it in spite of bg
        ###e needs more principled fix -- not yet sure what that should be -- is it to *draw* closer? (in a perp dir from surface)
        #e or just to create spheres (or anything else with thickness in Z) instead? (that should not always be required)

        ###BUG: DZ is not always the right direction!
        #e maybe scrap it here, and instead change class polyline3d to always draw itself closer to the screen
        # than its stored coords, but store coords identical to those of the underlying model object --
        # use a globally available displist (nim) for translating closer to the user -- hmm, that has to be different
        # for each rotational environment you might be inside! So only the graphical env knows its name...

        node_expr = Vertex(newpos, Center(Rect(0.2, 0.2, red)))

        newnode = self.world.make_and_add(
            node_expr, type="Vertex")  #070206 added type = "Vertex"
        ###e may want to make, but not add... let it be a kid of the polyline3d

        self.newnode = newnode
        return
Beispiel #4
0
class test_connectWithState(State_preMixin, ExampleCommand):

    # class constants needed by mode API for example commands
    commandName = 'test_connectWithState-commandName'
    default_mode_status_text = "test_connectWithState"
    featurename = "Prototype: Test connectWithState"
    PM_class = test_connectWithState_PM

    # tracked state -- this initializes specially defined instance variables
    # which will track all their uses and changes so that connectWithState
    # works for them:
    cylinderVertical = State(bool, False)
    cylinderWidth = State(float, CYLINDER_WIDTH_DEFAULT_VALUE)
        # TODO: soon this will be the only use of this constant, so it can be inlined
    cylinderColor = State('color-stub', pink) # type should be Color (nim), but type is not yet used
    
        # note: you can add _e_debug = True to one or more of these State definitions
        # to see debug prints about some accesses to this state.

    GraphicsMode_class = _test_connectWithState_GM
    
    # init methods
    
    def __init__(self, glpane):
        # I don't know why this method is needed. ##### REVIEW (super semantics), FIX or clean up
        super(test_connectWithState, self).__init__(glpane) # State_preMixin.__init__
        ExampleCommand.__init__(self, glpane) # (especially this part)
        return

##    def __init__(self, glpane):
##        super(test_connectWithState, self).__init__(glpane)
####            # that only calls some mode's init method,
####            # so (for now) call this separately:
####        IorE_guest_mixin.__init__(self, glpane)
##        return

    # exprs-based formulae (and some compute methods)
    direction = If_expr( cylinderVertical, DY, DX )
    def _C_width_direction(self):
        """
        compute self.width_direction
        """
        # Note: to do this with a formula expr instead
        # would require cross_Expr to be defined,
        # and glpane.lineOfSight to be tracked.
        return cross( self.direction, self.env.glpane.lineOfSight )
    width_direction = _self.width_direction # so it can be used in formulae below

    # stub for handle test code [070912]
    
    widthHandleEnabled = True # stub
    ## widthHandle = Instance(Rect()) # stub
    h_offset = 0.5 + 0.2 # get it from handle? nah (not good if that changes with time); just make it fit.
        # or we could decide that handles ought to have useful fixed bounding boxes...
##    widthHandle = Instance(Translate(Center(Rect(0.5)),
##                                     width_direction * (cylinderWidth / 2.0 + h_offset) )) #stub
    widthHandle = Instance( DraggableHandle_AlongLine(
        appearance = Center(Rect(0.5, 0.5, white)),
        ### REVIEW:
        # Can't we just replace the following with something based on the formula for the position,
        #   width_direction * (cylinderWidth / 2.0 + h_offset)
        # ?
        # As it is, I have to manually solve that formula for origin and direction to pass in,
        # i.e. rewrite it as
        #   position = origin + direction * cylinderWidth
        ## height_ref = cylinderWidth, ###WRONG
##        height_ref = ObjAttr_StateRef( _self, 'cylinderWidth'),
##            ## AssertionError: ObjAttr_StateRef fallback is nim -- needed for S._self
        height_ref = call_Expr( ObjAttr_StateRef, _self, 'cylinderWidth'), # guess at workaround; #e we need a more principled way!
            ### REVIEW: efficient enough? (guess: overhead only happens once, so yes)
            # could we say instead something like: height_ref = Variable(cylinderWidth) ?? Or VariableRef? Or StateRef_to ?
        origin = width_direction * h_offset, # note: also includes cylinder center, but that's hardcoded at ORIGIN
        direction = width_direction / 2.0,
        sbar_text = "cylinder width", ### TODO: make it a formula, include printed value of width?
        range = (0.1, 10),
            ### TODO: DraggableHandle_AlongLine should take values from the stateref if this option is not provided;
            # meanwhile, we ought to pass a consistent value!
    ))
        # Note: the Instance is required; but I'm not sure if it would be
        # if we were using a fuller exprs superclass or init code. [bruce 070912]

    def cmd_Bigger(self):
        self.cylinderWidth += 0.5
        set_cylinder_height( cylinder_height() + 0.5)
        # TODO: enforce maxima
        return

    def cmd_Smaller(self):
        self.cylinderWidth -= 0.5
        set_cylinder_height( cylinder_height() - 0.5)
        # enforce minima (###BUG: not the same ones as declared in the PM)
        ### REVISE: min & max should be declared in State macro and (optionally) enforced by it
        if self.cylinderWidth < 0.1:
            self.cylinderWidth = 0.1
        if cylinder_height() < 0.1:
            set_cylinder_height(0.1)
        return
    
    pass
class DraggableHandle_AlongCircle(DelegatingInstanceOrExpr): 
    """
    A kind of draggable handle which can be dragged along a line
    to change the value of a single floating point parameter
    (representing position along the line, using a scale and origin
    determined by our arguments).

    ### TODO: add epydoc parameters to this docstring? not sure that will work for a class!
    Maybe we need to synthesize those (from the doc options below) into a fake __init__ method for its sake??
    """
    # == args and options
    
    # options for appearance of handle
    appearance = Option( Drawable,
                         Center(Rect(0.2, 0.2, white)),
                         doc = "appearance, when not highlighted") 
    
    appearance_highlighted = Option( Drawable,
                                     appearance,
                                     doc = "appearance, when highlighted")
    
    sbar_text = Option(str, 
                       "draggable handle along circle", 
                       doc = "statusbar text on mouseover")

    # state variable controlled by dragging
    rotationDistanceRef = Option(StateRef, 
                                doc = "stateref to a dragged disctance variable") 

    
    # action options, for Highlightable to do after the ones that come from
    # DragBehavior_AlongLine [new feature of this and Highlightable, 080129]
    on_press = Option(Action)
    on_drag = Option(Action)
    on_release = Option(Action)
    on_release_in = Option(Action, on_release)
    on_release_out = Option(Action, on_release)
    on_doubleclick = Option(Action)
    
    #origin of the handle itself
    origin = Option( Point, ORIGIN)
    
    # Center of the circle whose perimeter serves as a path along which to 
    # drag 
    center = Option( Point, ORIGIN)
    
    #Axis of the circle. 
    axis  = Option( Vector, DX, doc = "vector giving direction and scale")
    
    #radius Vector
    radiusVector = Option( Vector, 
                           DX, 
                           doc = "vector giving direction and scale")
    
    #angle range for the rotation 
    range_for_rotation = Option(tuple_Expr, 
                                None, 
                                doc = "range limit of angle (tuple)")
    

    # == internal instances and formulae (modified from test_statearray_3.py)
    
    _drag_handler = Instance( 
        DragBehavior_AlongCircle(
            _self._delegate,
            rotationDistanceRef,
            origin,
            center,
            axis,
            radiusVector,
            range_for_rotation = range_for_rotation))
    
    
    #QUESTION: Should the 'RotateTranslate' transform from exprs.transforms be 
    #used here? -- Ninad 2008-02-13
    delegate = \
        Highlightable(
            Translate(
                appearance,
                _drag_handler._rotation #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.
             ),
            highlighted = Translate(
                appearance_highlighted,
                _drag_handler._rotation
             ),
            sbar_text = sbar_text,
            behavior = _drag_handler,
            on_press = _self.on_press,
            on_drag = _self.on_drag,
            # (note: no need to pass on_release)
            on_release_in = _self.on_release_in,
            on_release_out = _self.on_release_out,
            on_doubleclick = _self.on_doubleclick,
         )
    
 
    pass # end of class
Beispiel #6
0
class DraggableHandle_AlongLine(DelegatingInstanceOrExpr): ### TODO: all options might need renaming! replace "height" everywhere.
    """
    A kind of draggable handle which can be dragged along a line
    to change the value of a single floating point parameter
    (representing position along the line, using a scale and origin
    determined by our arguments).

    ### TODO: add epydoc parameters to this docstring? not sure that will work for a class!
    Maybe we need to synthesize those (from the doc options below) into a fake __init__ method for its sake??
    """
    # == args and options
    
    # options for appearance of handle
    appearance = Option( Drawable,
                         Center(Rect(0.2, 0.2, white)),
                         doc = "our appearance, when not highlighted") ###e take other args of Highlightable?
    appearance_highlighted = Option( Drawable,
                                     appearance,
                                     doc = "our appearance, when highlighted")
    sbar_text = Option(str, "draggable handle", doc = "our statusbar text on mouseover")

    # state variable controlled by dragging
    height_ref = Option(StateRef, doc = "stateref to a height variable") # TODO: rename, redoc

    range = Option(tuple_Expr, None, doc = "range limit of height (tuple)")
        ### MAYBE: RENAME to avoid conflict with python range in this code
        ### TODO: take values from the stateref if this option is not provided

    # action options, for Highlightable to do after the ones that come from
    # DragBehavior_AlongLine [new feature of this and Highlightable, 080129]
    on_press = Option(Action)
    on_drag = Option(Action)
    on_release = Option(Action)
    on_release_in = Option(Action, on_release)
    on_release_out = Option(Action, on_release)
    on_doubleclick = Option(Action)
        
    # line along which to drag it, and how to interpret the state as a position along that line (origin and scale)
    origin = Option( Point, ORIGIN)
    direction = Option( Vector, DX, doc = "vector giving direction and scale")
        # providing a default value is mainly just for testing
        
    #If this is false, the 'highlightable' object i.e. this handle 
    #won't be drawn. The delegate (that defines a Highlightable) 
    #We define an If_expr to check whether to draw the highlightable object.
    #[by Ninad]
    # [this should probably be revised, with hasValidParamsForDrawing replaced
    #  with an overridable compute method, for robustness -- current implem
    #  is suspected of causing tracebacks from insufficient update of this
    #  state. Need to review whether methodname needs to be hasValidParamsForDrawing
    #  to conform with any API. -- bruce 080409 comment]
    should_draw = State(bool, True) 

    # == internal instances and formulae (modified from test_statearray_3.py)
    
    _drag_handler = Instance( DragBehavior_AlongLine(
        _self._delegate,
        height_ref,
        call_Expr(Ray, origin, direction),
            # note: we need call_Expr since Ray is an ordinary class, not an expr! ###FIX
        range = range
     ))
    # note: _drag_handler is also being used to compute the translation from the height, even between drags.
    #@see: DnaStrand_ResizeHandle.hasValidParamsForDrawing
    #@see: definition of State attr should_draw
    delegate = \
        If_expr(
            _self.should_draw,
            Highlightable(
                Translate(
                    appearance,
                    _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.
                 ),
                highlighted = Translate(
                    appearance_highlighted,
                    _drag_handler._translation
                 ),
                sbar_text = sbar_text,
                behavior = _drag_handler,
                on_press = _self.on_press,
                on_drag = _self.on_drag,
                # (note: no need to pass on_release)
                on_release_in = _self.on_release_in,
                on_release_out = _self.on_release_out,
                on_doubleclick = _self.on_doubleclick            
            ) #end of Highlightable
        ) #end of If_expr
    
    def hasValidParamsForDrawing(self):
        """
        Overridden in subclasses. Default implementation returns True
        if this object (the highlightable) can be drawn without any known
        issues
        @see: DnaStrand_ResizeHandle.hasValidParamsForDrawing for more notes.
        """
        self.should_draw = True
        return self.should_draw
 
    pass # end of class
Beispiel #7
0
class DraggablyBoxed(
        Boxed
):  # 070316; works 070317 [testexpr_36] before ww,hh State or resizable, and again (_36b) after them
    # inherit args, options, formulae from Boxed
    thing = _self.thing  ###k WONT WORK unless we kluge ExprsMeta to remove this assignment from the namespace -- which we did.
    ###e not sure this is best syntax though. attr = _super.attr implies it'd work inside larger formulae, but it can't;
    # attr = Boxed.attr might be ok, whether it can work is not reviewed; it too might imply what _super does, falsely I think.
    extra1 = _self.extra1
    borderthickness = _self.borderthickness
    rectframe = _self.rectframe  # a pure expr
    # new options
    resizable = Option(bool,
                       False,
                       doc="whether to make it resizable at lower right")
    # works 070317 10pm (testexpr_36b) except for a few ###BUGS [updated info 070318 7pm]:
    # + [fixed] the wrong corner resizes (top right) (logic bug)
    # + [fixed] resizer doesn't move (understood -- wrong expr for its posn; commented below)
    # - negative sizes allowed (missing feature - limit the drag - need new DragBehavior feature)
    # - no clipping to interior of rectframe (missing feature - draw something clipped)
    # - perspective view ought to work, but entirely ###UNTESTED.
    # also, cosmetic bugs:
    # - resizer doesn't follow mouse in rotated coordsys, even in ortho view (though it's still useable).
    #   (This is not surprising -- we're using the wrong kind of DragBehavior as a simple kluge.)
    # - the resizer is ugly, in shape & color.
    clipped = Option(
        bool, False,
        doc="###doc")  #070322 new feature ### make True default after testing?
    # state
    # WARNING: due to ipath persistence, if you revise dflt_expr you apparently need to restart ne1 to see the change.
    ##    ww = State(Width, thing.width  + 2 * extra1) # replaces non-state formula in superclass -- seems to work
    ##    hh = State(Width, thing.height + 2 * extra1)
    ##        # now we just need a way to get a stateref to, effectively, the 3-tuple (ww,hh,set-value-discarder) ... instead, use whj:
    whj = State(Vector,
                V_expr(thing.width + 2 * extra1, -thing.height - 2 * extra1,
                       0))  #e not sure this is sound in rotated coordsys
    translation = State(Vector, ORIGIN)
    # override super formulae
    ww = whj[0]  # seems to work
    hh = neg_Expr(
        whj[1]
    )  # negative is needed since drag down (negative Y direction) needs to increase height
    # (guess: neg_Expr wouldn't be needed if we used an appropriate new DragBehavior in resizer,
    #  rather than our current klugy use of SimpleDragBehavior)
    # appearance
    rectframe_h = Instance(
        Highlightable(
            ## rectframe(bordercolor=green),####### cust is just to see if it works -- it doesn't, i guess i sort of know why
            ##bug: __call__ of <getattr_Expr#8243: (S._self, <constant_Expr#8242: 'rectframe'>)> with: () {'bordercolor': (0.0, 1.0, 0.0)}
            ##AssertionError: getattr exprs are not callable
            TopLeft(rectframe),
            #e different colored hover-highlighted version?? for now, just use sbar_text to know you're there.
            sbar_text=
            "draggable box frame",  # this disappears on press -- is that intended? ###k
            behavior=SimpleDragBehavior(
                # arg1: the highlightable
                _self.rectframe_h,
                # arg2: a write-capable reference to _self.translation
                ## fails - evalled at compile time, not an expr: LvalueFromObjAndAttr( _self, 'translation'),
                ###BUG: why didn't anything complain when that bug caused the state value to be an add_Expr, not a number-array?
                call_Expr(LvalueFromObjAndAttr, _self, 'translation'),
                #e alternate forms for this that we might want to make work:
                #  - getattr_StateRef(_self, 'translation') # simple def of the above
                #  - StateRef_for( _self.translation ) # turns any lvalue into a stateref! Name is not good enough, though.
            )))
    resizer = Instance(
        Highlightable(
            Center(Rect(extra1, extra1)),  #e also try BottomRight
            highlighted=Center(Rect(extra1, extra1, white)),
            pressed=_my.highlighted,
            sbar_text="resize the box frame",
            behavior=SimpleDragBehavior(
                _self.resizer, call_Expr(LvalueFromObjAndAttr, _self, 'whj'))))
    ###BUG: in Boxed, rectframe comes first, so lbox attrs are delegated to it. We should do that too --
    # but right now we draw it later in order to obscure the thing if they overlap. With clipping we won't need that --
    # but without clipping we will. If the latter still matters, we need a version of Overlay with delegation != drawing order,
    # or, to delegate appearance and layout to different instances ourselves. (Or just to define new formulae for lbox -- easiest.) #e
    drawme = Instance(
        Overlay(
            If(
                clipped,
                Clipped(
                    thing,
                    planes=[
                        call_Expr(clip_to_right_of_x0, -thing.bleft - extra1 +
                                  ww - borderthickness),
                        # note: the (- borderthickness) term makes the clipping reach exactly
                        # to the inner rectframe edge. Without it, clipping would reach to the outer edge,
                        # which for 3d objects inside the frame can cause them to obscure it.
                        # (Other interesting values are (- extra1) and (- borderthickness/2.0),
                        #  but they both look worse, IMHO.)
                        call_Expr(clip_below_y0,
                                  thing.btop + extra1 - hh + borderthickness)
                    ]),
                thing,
            ),
            Translate(rectframe_h,
                      V_expr(-thing.bleft - extra1, thing.btop + extra1)),
            If(
                resizable,
                ## Translate( resizer, V_expr( thing.bright + extra1, - thing.bbottom - extra1))
                ###WRONG - this posn is fixed by thing's lbox dims, not affected by ww, hh;
                # will the fix be clearer if we use a TopLeft alignment expr?
                # It'd be hard to use it while maintaining thing's origin for use by external alignment --
                # but maybe there's no point in doing that.
                Translate(
                    resizer,
                    V_expr(-thing.bleft - extra1 + ww,
                           thing.btop + extra1 - hh)))))
    _value = Translate(
        drawme,  ## DisplayListChunk( drawme), ###k this DisplayListChunk might break the Highlightable in rectframe_h #####
        translation)
    pass  # end of class DraggablyBoxed
Beispiel #8
0
class _MT_try2_node_helper(DelegatingInstanceOrExpr):
    """
    [private helper expr class for MT_try2]
    One MT item view -- specific to one node, one whole MT, and one (possibly time-varying) position with it.
    """
    # args ####e REORDER THEM
    node = Arg(ModelNode, doc = "any node that needs to be displayed in this MT")
        ###e NOTE: type coercion to this is nim; while that's true, we use helper functions like node_name(node) below;
        # once type coercion is implemented
        # (or simulated by hand by wrapping this arg with a helper expr like ModelTreeNode_trivial_glue),
        #  we could instead use node.mt_name, etc.)
    mt = Arg(MT_try2, doc = "the whole MT view, in which we store MT items for nodes, and keep other central state or prefs if needed")
    name_suffix = Option(str, "")
    initial_open = Option(bool, False, doc = "initial value of boolean state 'open'; only used when this item is first created")
        ##e should ask the node itself for the initial value of open (e.g. so new groups, trying to start open, can do so),
        # and also advise it when we open/close it, in case it wants to make that state persistent in some manner
        
    # WARNING: compare to MT_try1 -- lots of copied code after this point
    # WARNING: the comments are also copied, and not yet reviewed much for their new context! (so they could be wrong or obs) ###k
    
    # state refs
    open = State(bool, initial_open)
    
    # other formulae
    ###e optim: some of these could have shared instances over this class, since they don't depend on _self; should autodetect this
    # Note, + means openable (ie closed), - means closable (ie open) -- this is the Windows convention (I guess; not sure about Linux)
    # and until now I had them reversed. This is defined in two files and in more than one place in one of them. [bruce 070123]
    open_icon   = Overlay(Rect(0.4), TextRect('-',1,1))
    closed_icon = Overlay(Rect(0.4), TextRect('+',1,1))
    openclose_spacer = Spacer(0.4)
        #e or Invisible(open_icon); otoh that's no simpler, since open_icon & closed_icon have to be same size anyway

    # the openclose icon, when open or close is visible (i.e. for openable nodes)
    openclose_visible = Highlightable(
        If( open, open_icon, closed_icon ),
        on_press = Set(open, not_Expr(open)),
        sbar_text = getattr_Expr( _self, '_e_serno') #070301 this permits finding out how often MT gets remade/shared
            # (results as of 070301: remade when main instance is, even if going back to a prior testexpr, out of _19i & _30i)
     )
    
    openclose_slot = If( call_Expr(node_openable, node), openclose_visible, openclose_spacer )


    if 0:
        # cross-highlighting experiment, 070210, but disabled since approach seems wrong (as explained in comment)
        yellow = DZ = 'need to import these'
        indicator_over_obj_center = Center(Rect(0.4, 0.4, yellow))
        position_over_obj_center = node.center + DZ * 3 ###BUG: DZ does not point towards screen if trackballing was done
            ###STUB:
            # - should be drawn in a fixed close-to-screen plane, or cov plane (if obscuring is not an issue),
            #   - so indicator size is constant in pixels, even in perspective view (I guess),
            #   - also so it's not obscured (especially by node itself) -- or, draw it in a way visible behind obscuring things (might be a better feature)
            # - what we draw here should depend on what node is
            # - we also want to draw a line from type icon to node indicator (requires transforming coords differently)
            # - needs to work if node.center is not defined (use getattr_Expr - but what dflt? or use some Ifs about it)
        pointer_to_obj = DrawInCenter( Translate( indicator_over_obj_center, position_over_obj_center))
            #bug: Translate gets neutralized by DrawInCorner [fixed now]
            ###BUG: fundamentally wrong -- wrong coord system. We wanted DrawInAbsCoords or really DrawInThingsCoords,
            # but this is not well-defined (if thing drawn multiply) or easy (see comments about the idea in projection.py).
    else:
        # What we want instead is to set a variable which affects how the obj is drawn.
        # If this was something all objs compared themselves to, then all objs would track its use (when they compared)
        # and therefore want to redraw when we changed it! Instead we need only the involved objs (old & new value) to redraw,
        # so we need a dict from obj to this flag (drawing prefs set by this MT). Maybe the app would pass this dict to MT_try2
        # as an argument. It would be a dict of individually trackable state elements. (Key could be node_id, I guess.)
        # ### TRY IT SOMETIME -- for now, cross-highlighting experiment is disabled.
        pointer_to_obj = None

    # selection indications can use this
    node_is_selected = call_Expr( mt_node_selected, node)
    kluge_icon_color = If( node_is_selected, blue, green)
    sbar_format_for_name = If( node_is_selected, "%s (selected)", "%s")
    
    ###STUB for the type_icon ##e the Highlightable would be useful on the label too
    icon = Highlightable(
        Rect(0.4, 0.4, kluge_icon_color), ##stub; btw, would be easy to make color show hiddenness or type, bfr real icons work
        Overlay( Rect(0.4, 0.4, ave_colors(0.1, white, kluge_icon_color)),
                 #070216 mix white into the color like DraggableObject does
                 pointer_to_obj ),
        sbar_text = format_Expr( sbar_format_for_name, call_Expr(node_name, node) )
     )
    
    ##e selection behavior too

    label = DisplayListChunk(
        # added DisplayListChunk 070213 late -- does it speed it up? not much; big new-item slowness bug remains. retain, since doesn't hurt.
        TextRect( call_Expr(node_name, node) + name_suffix )
     )
        ###e will need revision to Node or proxy for it, so node.name is usage/mod-tracked
        ##e selection behavior too --
        #e probably not in these items but in the surrounding Row (incl invis bg? maybe not, in case model appears behind it!)
        ##e italic for disabled nodes
        ##e support cmenu
    
    delegate = SimpleRow(
        CenterY(openclose_slot),
        SimpleColumn(
            SimpleRow(CenterY(icon), CenterY(label)),
                #070124 added CenterY, hoping to improve text pixel alignment (after drawfont2 improvements) -- doesn't work
            If( open,
                _MT_try2_kids_helper( call_Expr(node_kids, node) , _self.mt ), # 070218 added _self.mt -- always intended, first used now
                None
                    # Note: this None used to be Spacer(0), due to a bug mentioned in a comment in ToggleShow.py
                    # (but unfortunately not explained there -- it just says "I wanted None here, but it exposes a logic bug,
                    # not trivial to fix, discuss in If or Column" -- my recollected bug-theory is described just below).
                    # On 070302 I confirmed that None seems to work (even in testexpr_18i with a group of 2 chunks, plus two more below).
                    # I don't fully know why it works, since I thought the bug was that SimpleColumn's None specialcase
                    # didn't run, since the element was not None but the If, and then delegating lbox attrs to None didn't work.
                    # (Fixable by using the newer If that evals, but for some reason that's not yet standard, I guess just because
                    # I didn't have time to test it enough or think it through fully re ipath or instance caching or something.)
                    # But as long as it works, use it -- ask Qs later. A recent perhaps-related change: None is allowed in drawkid.
                    # (A memory scrap -- does instantiating None conceivably produce a spacer?? ###k)
             )
         )
     )
    pass # end of class _MT_try2_node_helper
Beispiel #9
0
    def on_press_bg(self):
        if 0:
            print "compare:"
            print self, self.delegate, self.delegate.delegate, self.delegate.delegate.plain  # the background
            print self.background
            print "hl.highlighted =", self.delegate.delegate.highlighted
            # self.background is the same as the .plain printed above, which means, as of 061208 941pm anyway,
            # instantiating an instance gives exactly that instance. (Reasonable for now...)

        point = self.current_event_mousepoint()
        #e note: current_event_mousepoint is defined only on Highlightable, for now (see comments there for how we need to fix that),
        # but works here because we delegate ultimately to a Highlightable, without changing local coords as we do.
        # note: lots of devel scratch & debug comments removed 061207; see cvs rev 1.5 for them.

        # for initial test, don't use those Command classes above, just do a side effect right here ###kluge

        newpos = point + DZ * DZFUZZ  # kluge: move it slightly closer so we can see it in spite of bg
        ###e needs more principled fix -- not yet sure what that should be -- is it to *draw* closer? (in a perp dir from surface)
        #e or just to create spheres (or anything else with thickness in Z) instead? (that should not always be required)

        ###BUG: DZ is not always the right direction! [more comment on that in demo_draw_on_surface.py]

        if not self.use_VertexView:
            # old code
            ## print "make node in old way (not using VertexView)" # still running as of 070115 at least in testexpr_19f
            node_expr = Vertex(
                newpos,
                Center(
                    Rect(
                        0.2,
                        0.2,
                        ## 'green', -- now we cycle through several colors: (colors,...)[counter % 6]
                        ## tuple_Expr(green,yellow,red,blue,white,black)[mod_Expr(_this(Vertex).ipath[0],6)]
                        red  # the above worked ok until tested 070121 morn -- ipath now starts with string.
                        # it was a kluge anyway, so disable it until we can rework it to be sensible.
                    )))
        else:
            # new code, being written 070105, just getting started -- mostly nim
            node_expr = Vertex_new(
                newpos,
                # cycle through several colors: (colors,...)[counter % 6]
                color=tuple_Expr(green, yellow, red, blue, white,
                                 black)[mod_Expr(_this(Vertex).ipath[0], 6)])
            pass

        ## draggable_node_expr = Highlightable(node_expr, on_drag = _self.on_drag_node, sbar_text = "dne")
        ###BUG: this breaks dragging of the new node; it fails to print the call message from on_drag_node;
        # if you try to drag an old node made this way, it doesn't work but says
        # debug fyi: len(names) == 2 (names = (268L, 269L))
        # Guess: limitation in current rendering code makes it not work for any nested glnames, but just print this instead...
        # (note: even after reload, the node objects in the world have their old Vertex class, and the old expr used to make them)
        #
        # [later 061213:] IIRC the status was: I made GLPane_overrider so I could fix that 2-glname issue in it,
        # but never got to that yet. Meanwhile I commented out the use of this expr, and thus on_drag_node is never used...
        # and Vertexes dragged directly do nothing -- they're highlightable but with no actions.
        # And World could probably draw them highlightable even if they weren't, but it doesn't.
        # BTW the disabled nonworking draggable_node_expr is not well-designed -- it does not add a Vertex to World, it adds a
        # draggable one -- but even World is not perfect, since it contains Vertexes (not just their data)
        # and they inherently have (a lack of) action bindings since they are Highlightable.
        # Probably better would be if World contained data-nodes and had access to (or had its own) display rules for them
        # which added commands/actions based on the currently active tools. That would help with tool-code-reloading too.
        # Probably some other comments here say this too.
        #
        # So does a World need a formula or function arg for how to map its data objects to display objects, at the moment?
        # Or is there some scheme of a global map for that, to be applied when "drawing" any data object?
        # And do some data objs have their own positions, or is that always supplied by the world or other data obj they're in?
        # In theory, we might display atoms at posns unrelated to atom.pos, e.g. as a row in a table which includes their coords.
        # So it's more like we have ways of "drawing a set of things" which can say "at posns given by func(thing)"
        # or "at successive posns in a column", corresponding to two display forms with different exprs,
        # with the map from thing to individual display form also needing to be specified.
        # So a World is more like a set of things, and it can have a display mode (or more than one), given a thing-display-function.
        # We can ask it or anything else how it recommends displaying itself given display style options,
        # but we can choose to use that display function (from it to a more directly displayable object) or use another one.
        # Or we can probably just "draw it" and have it pick up the current display style from the env (including the
        # currently active tools). Is there any reason not to permit both? (draw using current style, draw using given style,
        # give me function from you to drawables using given style, use specific function and draw the results -- all possible.)
        #
        # If a thing in a world has standard mouse actions of its own, can it also have "grabbable areas" for use in dragging it
        # when it has a posn as displayed in some world? Or did that world have to explicitly turn it into a draggable thing?
        # Answer: both. The world turns it into that by adding a drag binding for those "overall handles" the thing has.
        # It might draw them with glnames in some set it knows... ie as named subobjs of itself. The overall thing might also
        # have a single name. Then we have a sequence of two glnames meaning obj/subobj which we want to use to determine the action.
        # For some subobjs that's within the object and supplied by it (perhaps depending on tool); for others,
        # it's supplied by the World it's in (also dep on a tool) and handled by it (eg move the obj, select the obj).
        #
        # For the simple things we have there, there are no subobjects, and no actions except drag or later select the whole thing.
        # A simple model is "one thing was hit, but some things are specified by a specific series of two or more glnames".
        # In general the outer name decides how to interpret (or whether to ignore) the inner names.
        # It can map the inner ones somehow... not sure how. This will relate a lot to DisplayListChunk when we have that.
        # Mere nested Highlightables might push two names but both would be unique. Outer name might just defer to inner one then.

        if 0:
            ## MAKE THIS WORK:
            draggable_node_expr = 'define this'
            newnode = self.world.make_and_add(draggable_node_expr,
                                              type="Vertex")
        else:
            newnode = self.world.make_and_add(
                node_expr, type="Vertex")  #070206 added type = "Vertex"

        self.newnode = newnode  ###KLUGE that we store it directly in self; might work tho; we store it only for use by on_drag_bg
        return  # from on_press_bg