示例#1
0
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
示例#2
0
class Boxed(InstanceMacro):  # 070316 slightly revised
    """
    Boxed(widget) is a boxed version of widget -- it looks like widget, centered inside a rectangular frame.
    Default options are pixelgap = 4 (in pixels), borderwidth = 4 (in pixels), bordercolor = white.
    [#e These can be changed in the env in the usual way. [nim]]

    @warning: some deprecated but commonly used options are given in model units, not in pixels (probably a design flaw).
    """
    #e (Does Boxed want a clipped option, like DraggablyBoxed has? What about just Rect?)
    # WARNING: would not work if it inherited from Widget2D,
    # since it would pick up Widget2D default values for lbox attrs like btop. [unconfirmed but likely; 061127 comment]

    # args
    thing = Arg(Widget2D)

    # options
    borderwidth = Option(int, 4)  # 070305 new feature -- specified in pixels
    borderthickness = Option(Width, borderwidth * PIXELS)
    # old alternative (worse since caller has to multiply by PIXELS); commonly used, but deprecated as of 070305
    # (warning: borderthickness is still used as an internal formula when not supplied)
    # (WARNING: supplying both forms is an error, but is not detected;
    #  this might cause bugs that are hard for the user to figure out
    #  if the different option forms were used in successive customizations of the same expr)

    pixelgap = Option(
        int, 4
    )  # 070305 new feature [#e rename gap? bordergap? (change all gap options to being in pixels?)]
    # (maybe not yet tested with nonzero passed-in values)
    gap = Option(Width, pixelgap * PIXELS)
    # old alternative (worse since caller has to multiply by PIXELS), commonly used, but deprecated as of 070305
    # (see also the comments for borderthickness)
    # (warning: gap is still used as an internal formula when not supplied)

    bordercolor = Option(Color, white)

    # internal formulae
    extra1 = gap + borderthickness
    ww = thing.width + 2 * extra1  #k I'm not sure that all Widget2Ds have width -- if not, make it so ##e [061114]
    hh = thing.height + 2 * extra1
    rectframe = RectFrame(ww, hh, thickness=borderthickness, color=bordercolor)
    # appearance -- note, rectframe appearing first is significant, since lbox attrs are delegated to it.
    _value = Overlay(
        Translate(rectframe,
                  -V_expr(thing.bleft + extra1, thing.bbottom +
                          extra1)),  #e can't we clarify this somehow?
        thing)
    pass
示例#3
0
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
    # revise the code that draws this to accomodate that variability.
    # Also make sure to revise the code that calls each one
    # (i.e. a modified copy of _expr_instance_for_overlay_imagename)
    # to use a different "index" even when using the same imagename.
    # (For example, it could include dx,dy in the index.)
    # [bruce 080324]
    return DrawInCorner(corner=UPPER_RIGHT)(Overlay(
        Spacer(22 * PIXELS),
        Translate(image_expr, V_expr(dx * PIXELS, dy * PIXELS, 0)),
    ))
示例#4
0
class TestIterator_alsoobsnow_nevertried(InstanceMacro):
    """
    simple iterator which makes two instances of the same arg
    """
    #e for debug, we should make args to pass to this which show their ipaths as text!
    thing = Arg(Maker(Widget)) # Maker? ExprFor? ProducerOf? Producer? Expr?
    w1 = Instance(thing)
        #k is number of evals correct in principle? internal uses of Instance assumed the expr was literal, were they wrong?
        # analyzing the code: this calls _i_inst with (an arg that evaluated to) getattr_Expr(_self, 'thing'),
        # and to instantiate that, it evals it, returning (I think) whatever self.thing is, which should be an instance of the arg.
        # This may make no sense but it's predicted that self.w1 and self.w2 should be instances, and the same one, of the arg.
        # that's wrong [thing's formula instantiates once too much, Instance(thing) once too little since I meant, I guess, I(*thing)]
        # , but it's not what I seem to be seeing, which is w1.width below running on either a non-instance
        # or something with a non-instance inside it. The non-instance is Translate, w1 should be a Boxed, so maybe that's consistent
        # if there's an error in Boxed. So I'm adding sanity checks to zome of: Boxed, Overlay, InstanceMacro, Translate. ###DOIT
##    print "w1 before ExprsMeta = %r" % (w1,) ###
    w2 = Instance(thing)
    # kluge since we don't have Row yet:
    _value = Overlay( w1, Translate(w2, V_expr(w1.width + 4 * PIXELS, 0,0)))
    pass
示例#5
0
class TopCenter(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = (thing.bleft - thing.bright) / 2.0
    dy = -thing.btop
    delegate = Translate(thing, V_expr(dx, dy, 0))
示例#6
0
class BottomLeft(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = +thing.bleft
    dy = +thing.bbottom
    delegate = Translate(thing, V_expr(dx, dy, 0))
示例#7
0
class CenterLeft(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = +thing.bleft
    dy = (thing.bbottom - thing.btop) / 2.0
    delegate = Translate(thing, V_expr(dx, dy, 0))
示例#8
0
class TopLeft(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = +thing.bleft
    dy = -thing.btop
    delegate = Translate(thing, V_expr(dx, dy, 0))
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
示例#10
0
class Right(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = -thing.bright
    delegate = Translate(thing, V_expr(dx, 0, 0))
示例#11
0
class Bottom(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dy = +thing.bbottom
    delegate = Translate(thing, V_expr(0, dy, 0))
示例#12
0
class Top(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dy = -thing.btop
    delegate = Translate(thing, V_expr(0, dy, 0))
示例#13
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
示例#14
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
示例#15
0
class Vertex(
        ModelObject
):  # renamed Node -> Vertex, to avoid confusion (tho it added some too, since localvars not all changed,
    # and since the world ought to contain model objs anyway, in general, of which Vertex is only one type, and current implem
    # also has its own graphics code)...
    # see below about better ways to rename it...
    """It has a position, initializable from arg1 but also settable as state under name pos, and an arb appearance.
    Position is relative to whatever coords it's drawn in.
    When you drag it, it chooses depth just nearer than hitpoint -- which means if you wiggle it over itself,
    it gets nearer and nearer (design flaw). [see comment for possible fix]
    """
    # 070223 possible fix to seeing depth of self: during a drag, tell glpane not to draw dragobj into depth or during glselect
    # mode... so it finds some other selobj besides dragobj. means it should draw dragobj last i guess... maybe transparent
    # so you can see selobj behind it, or diff color when there is a selobj...

    ###e about what to rename it... Hmm, is it a general "Draggable"? .lookslike arg2 -> .islike or .thing arg1?

    # BTW, the highlightability is not yet specified here ###nim; it relates to the fact that we can bind commands to it
    # (as opposed to things it contains or is contained in, tho that should be permitted at the same time,
    #  tho implem requires nested glnames to sometimes ignore inner ones, when those are inactive);
    # but we might add it in a wrapper which makes it into a view of it that lets commands be bound to it,
    # except that World.draw assumes we draw the actual model objs, not wraps of them - also an issue if env says they
    # look different -- so maybe World needs to wrap all it draws with glue to add looks and behavior to it, in fact.
    # [update much later 070201: or maybe ModelObject knows about this and asks env whether to override default drawing code.]

    # but for now, can we do this here?

    pos0 = Arg(Position)
    pos = State(
        Position, pos0
    )  ###BUG -- does this work -- is pos0 set in time for this? not sure it's working... 061205 1009p
    #e we probably want to combine pos0/pos into one StateArg so it's obvious how they relate,
    # and only one gets saved in file, and only one self.attr name is used up and accessible

    # the rest of this class is for drawing it and interacting with it.
    # Can we move that code into e.g. VertexDrawable or VertexView
    # and have Vertex itself just delegate (for sake of draw, lbox, etc) to some rule in the env for getting a Drawable for it,
    # probably looking it up in a dynamic memoizing mapping in the env? ####e [070105]
    # I think YES.
    # - a main difference between a model & view object -- a view obj knows how to draw itself, a model obj asks the env.
    #   (and the answer is quite different in different envs, e.g. 3d area vs MT. but what if we mix those?)
    # related notes:
    # - it might want a different delegate for drawing purposes (draw, lbox) and sim purposes (or others).
    # - does it also have an attr corresponding to its index/address/id in the model world?
    # - and maybe some for relations to other model objs, eg MT-parent, tags, name, etc?
    # - and maybe some graphics prefs like color or whatever, even if it's up to the drawing rule whether/how to use these?
    # - and for that matter some arbitrary other data (named attrs), as we'll let any model object have?
    # simplest thing that could work --
    # - make some sort of MemoDict for model-view and put it into the env, even if we kluge how to set it up for now.
    #   how does demo_MT do it? With a hardcoded helper function using a MemoDict in a simple way -- no involvement of env.
    #   So see above for copied code from that... ###e

    #e so now what we want is for this (in super modelobject) to delegate to a computed viewer from the helper func above

    #e but also to have more args that can be used to set the color [do this only in Vertex_new, below]
    ## color = Option(Color, color)

    ##    pass

    ## class VertexView(xx): -- SOMETHING LIKE THIS IS THE INTENT ####

    #e and then we want this new class to have the hardcoded appearance & behavior which the code below now passes in lookslike arg

    lookslike = ArgOrOption(Anything)  # OrOption is so it's customizable
    ###BAD for lookslike to be an attr of the Vertex, at least if this should be a good example of editing a sketch. [070105]
    # (a fancy sketch might have custom point types, but they'd have tags or typenames, with rules to control what they look like)

    cmenu_maker = State(
        Anything, None
    )  # meant to be set from outside; let's hope None is a legal value [070223 HACK]
    ## delegate = _self.lookslike #k
    delegate = Highlightable(
        Translate(lookslike, pos),
        ## eval_Expr( call_Expr(lookslike.copy,)( color = yellow) ),  #####?? weird exc don't know why - reload?
        ## AssertionError: _this failed to find referent for '_this_Vertex'
        on_drag=_self.on_drag,  # 070103 kluge experiment, works (eg in _19d)
        cmenu_maker=
        cmenu_maker  #070223 HACK [#e rename cmenu_maker to cmenu_obj as I guessed it was named??]
    )

    #e actions? or do this in a per-tool wrapper which knows the actions?
    # or, do this here and make the actions delegate to the current tool for the current parent? guess: the latter.

    ##e digr: will we want to rename delegate so it's only for appearance? *is it*? does it sim like this too?
    # Guess: it's for everything -- looks, sim qualities, etc -- except what we override or grab from special members.
    # [if so, no need to rename, except to clarify, leaving it general.]
    #e might need something for how to save it in a file, Undo policy, etc

    def on_drag(
        self
    ):  # 070103 kluge experiment, copied/modified from on_drag_bg in bigger class below

        # Note: this bug reported in BUGS breaks dragging of these nodes; worked around by increasing DZFUZZ:
        # 070115 "highlightable-finder can be fooled due to check_target_depth_fudge_factor of 0.0001"

        # where i am 070103 447p (one of two places with that comment)
        # - sort of sometimes works, but posns are sometimes same as bg, not sure why that DZ would be needed,
        # oh i guess the mousepos comes from the gray bg rect not the self unless we drag very slow...

        point = self.current_event_mousepoint(
        )  ### MIGHT BE WRONG COORDS? guess: no
        #k guess: will have snap-to-fixed-point bug for generic drag code
        newpos = point + DZ * DZFUZZ  # used for different things, depending #### DZ needed but might cause trouble too
        self.pos = newpos
        ## print "in-node action set %r.pos = %r" % (self, newpos) # sometimes works
        self.KLUGE_gl_update()  #k needed?
        return

    pass  # end of class Vertex
示例#16
0
class BottomCenter(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = (thing.bleft - thing.bright) / 2.0
    dy = +thing.bbottom
    delegate = Translate(thing, V_expr(dx, dy, 0))
示例#17
0
class Left(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = +thing.bleft
    delegate = Translate(thing, V_expr(dx, 0, 0))
示例#18
0
class CenterX(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dx = (thing.bleft - thing.bright) / 2.0
    delegate = Translate(thing, V_expr(dx, 0, 0))
示例#19
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
示例#20
0
class CenterY(DelegatingInstanceOrExpr):
    thing = Arg(Widget2D)
    dy = (thing.bbottom - thing.btop) / 2.0
    delegate = Translate(thing, V_expr(0, dy, 0))
示例#21
0
class _cmd_MakeRect_BG(Highlightable):
    """Background event bindings for dragging out new Rects.
    (Not involved with selecting/moving/editing/resizing rects after they're made,
     even if that happens immediately to a rect this code makes from a single drag.)
    """
    # args [needed for sharing state with something]
    world = Option(World)
    #e something to share state with a control panel in the PM - unless we just use prefs for that

    # The drag event handlers modify the following state and/or derived objects (some documented with their defs):
    # self.rubber_rect = None or a newly made Rect we're dragging out right now
    #  (implemented as a rubberband-object drawable -- NOT a model object -- since it has formulae to our state, not its own state)
    #
    # nim: self.newnode = None or a Model Object version of the Rect we're dragging out now, or last dragged out...
    #  in general this may be redundant with "the selection", if dragging out a rect selects it, or shift-dragging it adds it to sel...
    # note, which of these are change-tracked? the ones used in drawing. that means all of them i guess.

    startpoint = State(Point,
                       None,
                       doc="mousedown position; one corner of the rect"
                       )  #e (or its center, for variants of this cmd)
    curpoint = State(
        Point,
        None,
        doc="last mouse position used for the other corner of the rect")
    making_a_rect_now = State(
        bool,
        False,
        doc="whether we're making a rect right now, using the current drag")

    # formulae
    whj = curpoint - startpoint  # contains dims of current rect; only valid while we're making one, or after it's done before next press
    w = whj[
        0]  ###k what if negative?? evidently we make a neg-width Rect and nothing complains and it draws properly... ###REVIEW
    h = whj[1]  # ditto
    color = purple  # for now -- will be a pref or PM control for the color to use for new rects
    rubber_rect = Instance(
        If(making_a_rect_now, Translate(Rect(w, h, color), startpoint)))
    # this Instance is needed, at least by Highlightable
    # appearance -- note, for superclass Highlightable, this is plain, not delegate, and must be an Instance.
    # This means it's not good to subclass Highlightable rather than delegating to it. (Especially in example code!) ###FIX
    ## delegate = _self.rubber_rect
    plain = _self.rubber_rect

    # code for event handlers during the drag.
    def on_press(self):
        self.startpoint = self.current_event_mousepoint()
        self.making_a_rect_now = False  #k probably not needed
        # don't make until we drag!
        self.curpoint = None  #k probably not needed, but might help to catch bugs where whj is used when it shouldn't be
        #e change cursor, someday; sooner, change state to name the desired cursor, and display that cursorname in the PM
        return

    def on_drag(self):
        self.curpoint = self.current_event_mousepoint(plane=self.startpoint)
        self.making_a_rect_now = True
        return

    def on_release(self):
        ##e decide whether to really make one... here, assume we do, as long as we started one:
        if self.making_a_rect_now:
            node_expr = DraggableObject(
                StatefulRect(self.rubber_rect)
            )  #e StatefulMovableRect? StatefulSnapshot(self.rubber_rect)??
            ###k can we just pass the rubber rect and assume StatefulRect can grab its state from it by taking a snapshot??
            ###WRONG for DraggableObject to be here, I think -- it's how we display it -- not sure, at least movability might be here...
            ### the posn is in the rubber_rect since it has Translate... this seems potentially bad/klugy tho...
            # older cmts, related: ... also its state needs to include abs posn...
            # maybe this means, split DraggableObject into event binding part (for this UI) and Movable part (for abs posn state). #k
            self.newnode = self.world.make_and_add(node_expr, type="Rect")
            ###BUG (understood): type = "Rect" is not affecting sbar_text in DraggableObject. Need to add it in StatefulRect itself.
            self.newnode.motion = self.startpoint  ###KLUGE
            self.making_a_rect_now = False  # hide the rubber rect now that the real one is there
        else:
            print "fyi: click with no drag did nothing"  ##e remove after debug
        return

    pass  # end of class _cmd_MakeRect_BG
示例#22
0
class AlignmentExpr(DelegatingInstanceOrExpr):  # doesn't work yet, see below
    thing = Arg(Widget2D)
    dx = 0  # override in some subclasses
    dy = 0
    delegate = Translate(thing, V_expr(dx, dy, 0))
    pass