Exemple #1
0
class whatever(DelegatingInstanceOrExpr):  ###e rename
    # simulates the env that demo_ui will provide (stub version, evolving to be more like it)
    ui_and_world = Instance(World())  #####
    ###e following needs to permit cmd_DrawOnSurface to vary
    # (at least let it also be cmd_MakeRect; use a menu of options? or use one ActionButton per command, since more like a toolbar?)
    # -- but with Instance inside the variation, I think --
    # ie it should be a map from the desired cmd expr to the cmd instance -- or, make a new one each time, so it's a cmdrun...
    # maybe see how demo_ui/toolbar was planning to do it... ###e
    toolbar = SimpleColumn(
        ActionButton(
            _self.do_cmd_DrawOnSurface, "button: cmd_DrawOnSurface"
        ),  #e make the text from the command #e the running one should look pressed
        ActionButton(_self.do_cmd_MakeRect, "button: cmd_MakeRect"),
    )  ###e show it where? above PM for now?
    current_cmdrun = State(
        Anything, None
    )  # what is actually in here? an Instance of a "command run",   [btw is None needed??]

    # or of a command obj that handles multiple runs (ie a command_runner?)... up to it to not get messed up if that happens
    # (and for now, unfortunately, not remaking it is probably a significant speed optim)
    # (so should we let an outer command handler have the PM and get reused, but an inner CommandRun get remade? why bother?)
    def do_cmd_DrawOnSurface(
        self
    ):  #e which name is better: do_cmd or set_cmd? depends on type of command!
        self._do_cmd(cmd_DrawOnSurface)

    def do_cmd_MakeRect(self):
        self._do_cmd(cmd_MakeRect)

    def _do_cmd(self, cmd):
        "set self.current_cmdrun, etc..."
        # do we make a new one if button pressed when one already running?? yes for now.
        self.current_cmdrun = self.Instance(
            cmd(world=self.ui_and_world),
            id(cmd))  #e cache that expr? index ok? why cache instance?
        #old cmt: #e args? world? new object? does its super handle some? Command vs CommandRun?

    pm = current_cmdrun.property_manager
    corner_stuff = SimpleColumn(toolbar, pm)
    delegate = Overlay(
        current_cmdrun,
        DrawInCorner(corner_stuff, corner=PM_CORNER),
    )

    def _init_instance(self):
        super(whatever, self)._init_instance()
        self.do_cmd_MakeRect(
        )  # or at least set some command, preferably a "null" or "default" one
        # note that this resets the current tool state on reload -- not really desirable;
        # how was demo_ui planning to handle that? ###k

    pass
Exemple #2
0
def demo_drag_toolcorner_expr_maker(world):  #070106 improving the above
    # given an instance of World, return an expr for the "toolcorner" for use along with GraphDrawDemo_FixedToolOnArg1 (on the same World)
    expr = SimpleColumn(
        checkbox_pref(kluge_dragtool_state_prefs_key,
                      "drag new nodes?",
                      dflt=kluge_dragtool_state_prefs_default),
        checkbox_pref(kluge_dragtool_state_prefs_key + "bla",
                      "make polyline?",
                      dflt=False),
        checkbox_pref(kluge_dragtool_state_prefs_key + "bla2",
                      "(make it closed?)",
                      dflt=False),
        ## ActionButton( world._cmd_Clear, "button: clear") # works
        # 070108: try this variant which uses _cmd_Clear_nontrivial: will the If work as an Expr?? If_kluge should tell us #####k
        ####k also will the type tests inside ActionButton work with an If? Probably not -- that's a ###BUG but I'll put it off.
        ## 1. make this work later: ActionButton( world._cmd_Clear, If_kluge( world._cmd_Clear_nontrivial, "button: clear", "button (disabled): clear"))
        ##          2. this too: If_kluge( world._cmd_Clear_nontrivial,
        ##                  ActionButton( world._cmd_Clear, "button: clear"),
        ##                  ActionButton( world._cmd_Clear, "button (disabled): clear")
        ##         )
        If_kluge(
            getattr_Expr(world, '_cmd_Clear_nontrivial'),
            ActionButton(world._cmd_Clear, "button: clear"),
            ActionButton(world._cmd_Clear,
                         "button (disabled): clear",
                         enabled=False)
        )  # works, though text change is so slow I suspect there's actually a highlighting or update bug making it appear even slower...
        # update 070109: the bug seems to be that as long as the mouse stays on the button, it remains highlighted with the old highlight form.
    )
    return expr
Exemple #3
0
class TestIterator_wrong_to_compare(InstanceMacro):
    """
    variant of that which shows one Instance twice
    """
    thing = Arg(Widget) # the only difference
    w1 = Instance(thing) # these Instances will be idempotent
    w2 = Instance(thing)
    _value = SimpleColumn( w1, w2) # show one instance twice
    pass
Exemple #4
0
class TestIterator(InstanceMacro):
    """
    simple iterator which makes two distinct instances of the same arg
    """
    #e for debug, we should make args to pass to this which show their ipaths as text!
    thing = ArgExpr(Widget)
    w1 = Instance(thing)
    w2 = Instance(thing) # two distinct instances
    _value = SimpleColumn( w1, w2)
    pass
Exemple #5
0
class make_Rect_PG(PropertyGroup):
    "property group contents for making a Rect"
    # note: classname includes make_Rect rather than MakeRect,
    # since it might not be the *only* PG for cmd_MakeRect, and it might be shared by other commands' PMs.
    # (not sure this is sensible)
    title = "Rect properties"
    delegate = SimpleColumn(
        ColorEdit(color_ref,
                  label),  ##e [could put color name into prefs, for now...]
        #e dimensions? (numeric textfields) co-update with its draggability? yes...
        #e someday: units, gridding, ref plane, ...
    )
    pass
Exemple #6
0
def ChoiceColumn( nchoices, dflt = 0, **kws): ##e should be an InstanceMacro, not a def! doesn't work to be customized this way.
    "#doc"
    #e nim: Column -- esp on list like this -- Column( map(...)) -- so use SimpleColumn
    return Apply(
        lambda stateref_expr, nchoices = nchoices, dflt = dflt, kws = kws:
            SimpleRow( # stateref_expr will be a Symbol when this lambda is run, to produce an expr, once only
                SimpleColumn( * map( ChoiceButton(choiceref = stateref_expr, **kws), range(nchoices) ) ), # choose
                TextRect( format_Expr( "choice is %%r (default %s)" % dflt, stateref_expr.value ), 1, 30) # show choice
            ),
        LocalVariable_StateRef(int, dflt)
            # LocalState, combining this and the Apply?
                # or, just a stateref to some fixed state somewhere... whose instance has .value I can get or set? use that for now.
                ##k is there any way to use the new-061203 State macro for this?
    )
Exemple #7
0
class make_polyline3d_PG(
        PropertyGroup
):  ###e call me ###e revise -- not clear it should refer to a pref
    #e rename? this name means "PG for the command make_<class>"
    ###e who supplies this? the command? i guess so. is it a local class inside it? or at least the value of an attr inside it?
    "contents of property manager group for a polyline3d which is being made"
    ###e needs some args that let it find that polyline3d or the making-command!
    ##    arg = Arg()
    #e someday be able to automake this from higher-level contents... but returning a widget is always going to be a possibility
    # (see also comments in PM_from_groups about this)
    title = "Polyline Properties"  ###e USE ME in PM_from_groups
    delegate = SimpleColumn(
        checkbox_pref(kluge_dragtool_state_prefs_key + "bla2",
                      "closed loop?",
                      dflt=False),  # only gets closed when done -- ok??
    )
    pass
Exemple #8
0
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
Exemple #9
0
class PM_from_groups(
        DelegatingInstanceOrExpr
):  ###e refile into demo_ui or so, and call it on [make_polyline3d_PG(somearg)]
    "Make a Property Manager UI from a list of groupbox content widgets (eg columns of field editors) and other info."
    # args
    groups = Arg(list_Expr)
    #e in future these groups need to come with more attrs, like group titles
    # (WAIT, they already do have a title attr which we don't use here!),
    # whether they're closable and if so whether initially closed...
    # and they might include their own Boxed already...
    # the type decl might say we want a list of PropertyGroupBoxes,
    # with autoconversion of ParameterGroups to those...
    message = Option(
        str, "(PM message goes here)"
    )  # this has to be already split into lines, for now; all indentation is stripped

    # formulae
    def _C_use_message(self):
        lines = self.message.split('\n')
        lines = [line.strip() for line in lines]
        lines = filter(None, lines)
        return '\n'.join(lines)

    use_message = _self.use_message
    # appearance
    message_box = Boxed(TextRect(use_message), gap=0, bordercolor=yellow)
    group_box_column = MapListToExpr(
        KLUGE_for_passing_expr_classes_as_functions_to_ArgExpr(
            Boxed),  ###e change to a GroupBox, with a title from the group...
        groups,
        KLUGE_for_passing_expr_classes_as_functions_to_ArgExpr(SimpleColumn))
    delegate = SimpleColumn(
        Left(message_box),
        Left(group_box_column),
    )
    pass
Exemple #10
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
Exemple #11
0
class ToggleShow(InstanceMacro):
    # args
    thing = Arg(Widget2D)
    label = Arg(Widget2D, TextRect("label")) #e or coerce text into a 1-line TextRect -- how do we declare that intent??

    if 0: # first make it work with a self-made stateref only, imitating Highlightable, using transient state
        stateref = Arg(StateRef, Automatic) ###k assumes the dflt can be a way to make one, not a literal one

        ## Q: how does each stateref we have, e.g. the one here meant for 'open', relate to StatePlace args
        # we might make or get from a superclass? (like the ones now in Highlightable.py but to be moved to a super of it)
        # if caller passes one, no need for our own, but to make our own, we'd make it in a StatePlace of our own, I think. ##e 061117

    if 0 and 'maybe':
        ##e might need to also say it's supposed to be boolean
        # note, on 070115 I revised StateRef (still a stub) but might have broken it due to the arg being passed here (not tested)
        stateref = Arg(StateRef(bool), Automatic)

        ##e and also spell out the default location -- assume ipath itself can be coerced into the full stateref

        stateref = Arg(StateRef(bool), _self.ipath)

        ####k is ipath local to something like _self, or only rel to the entire model?? his matters if we name the statepath here!

        stateref = Arg(StateRef(bool), _my_node.open) ###k assumes _my_node.open can be an lval even after _my_node is bound! ####k


        ##e or we could spell out the default stateref as _self.ipath, assuming that can be coerced into one --
        # of course it can't, we also need to say it's boolean (openQ: open is true, closed is false) and with what encoding.
        # but come to think of it, that is not part of the arg, right? the arg is "some boolean state"... hmm, i guess it is.
        # but the arg can also be "where to store the state, of whatever kind you want". And we say the type and encoding
        # if the arg doesn't -- as if the caller can supply partial info in the arg, and we supply defaults rather than
        # making them get made up by the bare argtype -- which could work by just using a fancified argtype created here.
        # which the Arg macro could make for us somehow... but that can all wait for later. For now,
        # we can detect the boolean type by how we try to use the arg, i guess... not sure, maybe just say it right here.
        # and the default encoding for bools (known to the bool type, not custom to us) is fine.

    if 1: # works fine, but as of 061126 late, comment out the remaining stmt, since done in InstanceOrExpr superclass rather than here
        pass ## transient_state = StatePlace('transient') #e move into super along with the ones in Highlightable of which this is a copy
        #e rename stateref to be specific for open, maybe open_stateref, in that if 0 code above
        # devel scratch: transient_state is an attr_accessor, which lets you do getattr and setattr.
        # but what we want it to do for us is tell us an lval for the attr 'open'
        # so we can retain that, attached to self.open somehow -- as its actual lval, maybe? not sure.
        # but much like that, since get or set self.open should work that way.
        # so a stateref (instance of StateRef) is basically an instance which acts as an lval... and can be attached to an attr.
        # But ExprsMeta right now insists on making its own lval, being passed a formula. Should we kluge-adapt to that or change it?
        # Guess: better & maybe easier to change it. So we have a new kind of object, not a formula (or a special kind of one),
        # to use as an rhs and process by ExprsMeta. It's not an lval, that's per-Instance. Is it a formula for making an lval?###
        # But it might be semantically different, since we don't store the lval as the value for self.open,
        # but as the value for its lval. hmm.... can we tell ExprsMeta to do this by an assignment to open
        # of a wrapped formula? it means, get the lval not by making one whose vals come from this formula
        # but make a property whose lvals come from this formula (which should be per-instance but time-constant, maybe,
        # tho if not time constant, it might be ok -- not sure ##e).

        ## open = State('transient','open')
            ### hmm... maybe 'open' needn't be passed if it gets it like Arg or Option does... maybe the kind is also default something?
            # so: open = State()? bt say the type and dfault val -- like I did in this:
            # staterefs.py: 181:     LocalState( lambda x = State(int, 1): body(x.value, x.value = 1) ) #

        # see if this gets the expected asfail: it does! [061121 late]
        ## set_default_attrs( transient_state, open = True)

    if 0: # this will be real code someday when no longer nim, but use an easier way first.
        open = State(bool, True) # default 'kind' of state depends on which layer this object is in, or something else about its class
            # but for now make it always transient_state
            # this is a macro like Option
            # it takes exprs for type & initial val
            #  but those are only evalled in _init_instance or so -- not yet well defined what happens if they time-vary
            # and note, that form doesn't yet let you point the state into a storage place other than _self.ipath... should it??
            # but the importance is, now in python you use self.open for get and set, just as you'd expect for an instance var.

    else:
        def get_open(self): #k
            return self.transient_state.open
        def set_open(self, val): #k
            self.transient_state.open = val
            return
        open = property(get_open, set_open)
        pass

    def _init_instance(self):
        super(ToggleShow, self)._init_instance()
        set_default_attrs( self.transient_state, open = True)

    # constants
    # 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))

    if 0:
        open_icon   = TextRect('-',1,1) #stub
        closed_icon = TextRect('+',1,1) #stub
    else:
        ####@@@@ I vaguely recall that Highlightable didn't work on text!
        # and indeed, highlighting doesn't seem to be working on those.
        # if so, the above'll need revision until that's fixed.
        # BUT, with these grays anyway, clicks on the text are working. But it might be because the grays are behind them. ###k
        if 0 and 'varying rect sizes':
            # how it was during debugging
            open_icon   = Overlay(Rect(0.5,1), TextRect('-',1,1)) # added 0.5 061120 1018p temp debug kluge
            closed_icon = Overlay(Rect(1,0.5), TextRect('+',1,1)) #061120 changed impicit 1 -> 0.5
        else:
            # easier on the mouse-hand and eye
            open_icon   = Overlay(Rect(0.4), TextRect('-',1,1)) # added 0.5 061120 1018p temp debug kluge
            closed_icon = Overlay(Rect(0.4), TextRect('+',1,1)) #061120 changed impicit 1 -> 0.5

    # _value, and helper formulae

    ## open = stateref.value # can we make it work to say Set(open, newval) after this?? ####k
        # the hard part would be: eval arg1, but not quite all the way. we'd need a special eval mode for lvals.
        # it'd be related to the one for simplify, but different, since for (most) subexprs it'd go all the way.
    ## openclose = If( open, open_icon, closed_icon )

    # Status as of 061121 421p: both if 0 and if 1 cases seem to work fine, provided you restart when changing between them.
    # (Testing was not extensive, so it might turn out that avoiding other reloads is also needed.)
    # The known bugfixes that led to this:
    # - selobj = None in some places (not sure which are needed).
    # - no usage/change tracking by stateplaces that get set during draw (or that contain glname -- don't know if that matters).
    # - no usage/change tracking by set_default_attrs.
    # And other changes that might be helping:
    # - don't recycle glnames.
    # - some others I forget, which are marked by 061120 (or maybe 061121)
    #   in comments or stringlits (in this or other files).
    #  - don't track_use on exception in Lval get_value (BUT, i suspect it's actually wrong not to; see cmt there 061121)
    #  - more conservative selobj_still_ok
    #  - mode.update_selobj(event) in leftClick and ReleasedOn
    #  - self.inval(mode) #k needed? (done in two places per method, guess is neither is needed)
    #
    # Soon, the needed or not of the above workarounds should be sorted out,
    # and most of the following debugging-log commentary should be removed. #e

    if 1:
        openclose = Highlightable( If_kluge( open, open_icon, closed_icon ),
                                   on_press = _self.toggle_open,
                                   sbar_text = _this(Highlightable).ipath # this line just for debugging
                                   )
            ##e we should optim Highlightable's gl_update eagerness
            # for when some of its states look the same as others!
            # (no gl_update needed then, at least not just for that change --
            #  note, this is a special case of the inval optim for when something was changed to an equal value)
            #e someday be able to say:
            # on_press = Set( open, not_Expr(open) )
            ## silly: on_press = lambda open = open: open = not open # no, open = not open can't work
            # in fact, you can't use "lambda open = open", since open has to be replaced by ExprsMeta

            ##k can on_press be an expr to eval, instead of a (constant expr for a) func to call?? ####k
            ## on_press = call_Expr( lambda xxx: self.open = not self.open, xxx) # no, no assignment in lambda
        pass
    else:
        # so try this form 155p - bug of not working is gone, but now, it always draws the + form! Is it drawing the old one
        # due to same glname? no (I guess), they should have different names!
        # is it drawing old one due to not realizing that one is obs? ######where i am
        # is it failing to invalidate the drawing effect of this instance? (after all, who is it that sees the usage of open?
        # it must be glpane as if we were using a prefs variable here! is that sufficient?? does it work ok re selobj system???###)
        # IS THE CHOICE OF DELEGATE being invalled? I think so, since I see the alignment calcs get updated,
        # or is that just the live gltranslate inside the draw method?
        # HEY, when I covered up the glpane with this app, then uncovered it, suddenly I see the new selobj,
        # then the conjunction of both! how can that be? thes are similar to whgat I sawe earlier. conclusion: weird update bugs
        # in selobj/highlight system, i guess. (maybe it does the main draw and highlight draw on different objects?
        # try altering color, or using 4 images not 2. ###)
        # now it sems that mouse around on the closed that looks like open is what makes it look like clsed, or like both.
        # yes, repeatable, for either change of state. Ok, try that in 'if 1' case of this. ### siilar but not identical
        # and that time is again does get stuck into the closed state, with the grayrect no longer optiming redraws re stencil buffer.
        # .. reviewing code in Highlightable, I see some things to try -- see its 061120 comments.
        # ... I did all that, and the 'gray becomes inactive bug' in 'if 1 openclose case' is still there. howbout the if 0 case?
        # [later: i think that still had some bad bugs too, not much changed.]
        # for more, see string lits containing 061120, and for a log see big cmt just below here.
        openclose = If_kluge( open,
##                              Highlightable(open_icon,   on_press = _self.toggle_open, sbar_text = _self.ipath),
##                              Highlightable(closed_icon, on_press = _self.toggle_open, sbar_text = _self.ipath),
                              ###BUG - same ipaths? NO, I USED _self BUT MEANT _this(Highlightable)!!! AAArgh! ##k works now?? yes
          Highlightable(open_icon,   on_press = _self.toggle_open, sbar_text = _this(Highlightable).ipath),
          Highlightable(closed_icon, on_press = _self.toggle_open, sbar_text = _this(Highlightable).ipath),
                    )
        pass

    def toggle_open(self):
        if 'yet another shot in the dark 061120 1001p':
            self.env.glpane.selobj = None ##### THIS SEEMS TO FIX THE BUG, at least together with other potshots and if 0 openclose.
            # theory: old selobjs are being drawn highlighted even when not drawn normally. they mask the real stuff.
            # but with if 1 openclose it doesn't fix the different bug (gets wedged into closed state). why not???
            # this is with no recycling of names, and also selobj=None in recycler.
            # guess: in if 1, the same glname is used... but it's same literal selobj too, right? and remaking is turned off.
            # I don't have a theory for 'if 1' bug cause, or for why it only affects the inner thing, not outer one.
            # Does it only affect that after it's once been hidden? ### if so, is it "you were selobj and then not drawn" that makes it
            # happen? that might fit the data but I don't see how that could work.
            # So I added a 2nd 0.5 so neither gray rect form covers the other. but first inner close hits the bug of making it
            # inactive and act non-highlighted. so i wondered if the glname really only covers the openclose? code says so.
            # I added a try/except to be sure the PopName occurs; not triggered during this if 1 bug.
            #
            # Stopping for night 061120 1027p, summary: I understand some bug causes but not all; wish I could see inside the glselect
            # reasoning, so plan to add debug prints to glpane. Need to think thru its assumptions re chaotic glname/selobj/size/
            # whether-drawn situation, see which are wrong, which might cause the bug. Also - can event processing occur during
            # paintGL? I hope not, but verify. Also maybe GLPane needs to track frame numbers for selobjs being drawn,
            # stencil bits being made, vs selobj state mods as tracked by inval....
            #
            # update 061121 953a, where I am: after basic fixes elsewhere [some stateplaces not tracked, some usage tracking disallowed],
            # and still using all kluge/workarounds from 061120, bug seems totally fixed for if 0 case, all or most for if 1 ##k.
            # IIRC it was slightly remaining before some usage tracking disallowed, but that is not complaining, which is suspicious.
            # Anyway, if if 1 works too, plan is to gradually remove the kluges and clean up and keep it working.
            # BUT it looks like if 1 (using reloaded code) has a bug of some disallowed usage... details to follow.
            # BUT after restart I don't see it. BTW I recently reenabled reloading -- could that have fixed some bugs (how???),
            # or could it be that they now occur after reloading but not before it?? indeed, this is after changing if 1->0 and reload,
            # and looks like it might relate to old state being there, and
            ###### WHAT IF RELOADED CODE USES THE SAME STATE DIFFERENTLY AND HAS A BUG? #####
            # [but, that bug aside, there is still a real problem with whatever usage tracking this
            #  set_default_attrs is doing. [fixed now]]


        if 0: #061121 822p i've been using if 1 forever, let's see if if 0 works here: it does! either is ok, given the open property.
            old = self.transient_state.open
            self.transient_state.open = new = not old
            ## print "toggle_open changed self.transient_state.open from %r to %r" % (old, new,)
        else:
            old = self.open
            self.open = new = not old
            ## print "toggle_open changed self.open from %r to %r" % (old, new,)
            # [obs cmt re open property, but was it talking about that or a partly working State decl? as of 061121 I can't remember:]
                # should work but doesn't, see bug in notesfile, it delegates self.open eval to _value: 061118 late
                # (or is it just because the val was not initialized? GUESS, YES ###k)
                ## self.open = not self.open ### can this work??? it will call set of self.open -- what does the descriptor do for that?
                # (asfail, or not have __set__ at all?? FIND OUT. the notesfile says the same thing but for a different Q, what was it?)
                ## WE SHOULD MAKE THIS WORK even if we also make on_press = Set( open, not_Expr(open) ) work, since it's so natural.
        ### BTW what is it that will notice the inval, and the usage of this when we drew, and know that gl_update is needed?
        # the same thing that would know a display list content was invalid -- but where is it in our current code (if anywhere)?
        # I vaguely recall a discussion of that issue, in the displist chunk code or notesfile, weeks ago.
        # some way to have lvals representing displist contents or frame buffer contents, whose inval means an update is needed.
        printnim("toggle_open might do a setattr which is not legal yet, and (once that's fixed) might not properly gl_update yet")
        return

    _value = SimpleRow(
        openclose,
        SimpleColumn(
            label,
            If_kluge( open,
                      thing,
                      TextRect("<closed>") #####BUG: I wanted None here, but it exposes a logic bug,
                          # not trivial to fix, discuss in If or Column [see also a discussion in demo_MT.py, 070302];
                          ##e Spacer(0) can also be tried here [##e should what to show here be an arg??]
                      )
        )
    )

##    if 0: # if 0 for now, since this happens, as semiexpected:
##        ## AssertionError: compute method asked for on non-Instance <SimpleRow#3566(a) at 0xe708cb0>
##
##        ##e do we want to make the height always act as if it's open? I think not... but having a public open_height attr
##        # (and another one for closed_height) might be useful for some callers (e.g. to draw a fixed-sized box that can hold either state).
##        # Would the following defns work:?
##
##        # (They might not work if SimpleRow(...).attr fails to create a getattr_Expr! I suspect it doesn't. ####k )
##
##        # [WARNING: too inefficient even if they work, due to extra instance of thing -- see comment for a fix]
##        open_height = SimpleRow(
##            open_icon,
##            SimpleColumn(
##                label,
##                thing
##            )).height   ##k if this works, it must mean the SimpleRow gets instantiated, or (unlikely)
##                        # can report its height even without that. As of 061116 I think it *will* get instantiated from this defn,
##                        # but I was recently doubting whether it *should* (see recent discussions of TestIterator etc).
##                        # If it won't, I think wrapping it with Instance() should solve the problem (assuming height is deterministic).
##                        # If height is not deterministic, the soln is to make open_instance and closed_instance (sharing instances
##                        # of label), then display one of them, report height of both. (More efficient, too -- only one instance of thing.)
##                        # (Will the shared instance of label have an ipath taken from one of its uses, or something else?
##                        #  Guess: from the code that creates it separately.)
##
##        closed_height = SimpleRow(
##            closed_icon,
##            SimpleColumn( # this entire subexpr is probably equivalent to label, but using this form makes it more clearly correct
##                label,
##                None
##            )).height

    pass # end of class ToggleShow
class main_ui_layout(DelegatingInstanceOrExpr):
    #e rename? is it not only the ui, but the entire app? (selection, files, etc)
    #e merge in the App obj from test.py, and the _recent_tests system in some form?

    # args (none yet)

    # internal state - permanent
    ###e note: when we reload and remake this instance, we'd prefer it if the world state stayed unchanged (as i presume it does)
    # but if the default_tool instance and toolstack state got remade. The lack of the latter has been confusing me
    # since changes to ui code aren't working. I think this is a difference between a ui and operations layer (should change)
    # vs model data layer (should not change even tho the op methods on it can change). So when I can put these things into layers
    # (not only State, but even Instance or attrs within them) and make those sensitive to reload, that will help.
    # In the meantime -- if I could kluge Instance and State to take an option to control this
    # (like index = exprs_globals.reload_counter)
    # it might help.... #####TRYIT SOMETIME, and BE CAREFUL UNTIL I DO.
    world = Instance(World())
    default_tool = Instance(DefaultToolRun())

    # internal state - varying
    toolstack = State(list_Expr, [
        default_tool
    ])  # always has at least one tool on it; a stack of Instances not exprs
    # maybe the better term for this is something like command & subcommand
    current_tool = toolstack[
        -1]  # last tool on the stack is current; exiting it will pop the stack (Instance not expr)
    ##e (add a type-assertion (as opposed to type-coercion) primitive, so I can say "this is an Instance" in the code?)
    # NOTE: this is not strictly speaking a tool, but ONE RUN of a tool. That might be important enough to rename it for,
    # to ToolRun or maybe ActiveTool or RunningTool or ToolInUse or ToolBeingUsed...
    # [but note, obj might remain around on history or in Undo stack, even when no longer being used],
    # since we also have to deal with Tools in the sense of Tool Run Producers, eg toolbuttons. ###e

    # parts of the appearance
    registry = find_or_make_global_command_registry(
    )  ## None ###STUB, will fail --
    ## AttributeError: 'NoneType' object has no attribute 'command_for_toolname'
    toolstack_ref = None  ###STUB
    toolbar = Instance(
        MainToolbar(registry, ["Features", "Build", "Sketch"],
                    toolstack_ref))  #e arg order?
    ###e args/opts for what tools to show -- maybe their cmdnames & it loads them from elsewhere
    #e add row of tool buttons, and flyout toolbar; use ChoiceRow?? the things should probably look pressed...
    # they might need cmenus (find out what the deal is with the cmenus i see in the ui mockup - related to flyouts?
    #    yes, it's like this: main tools have cmenus with subtools, and if you pick one, main tool and its subtool both look pressed
    # I'll need new specialized controls.py classes for these; new super Control for all kinds of controls?? (not sure why...)
    propmgr = SimpleColumn(
        TextRect(
            "(property manager)"),  #e possibly to become a tab control tab
        DebugPrintAttrs(
            current_tool.property_manager
        )  # must be None if we don't want one visible; otherwise an Instance
        ###BUG: DebugPrintAttrs shows that it's a spacer -- I guess IorE turns None into one when it instantiates? Make it a false one??
    )
    mt = SimpleColumn(
        TextRect(
            "(model tree)"
        ),  #e possibly to become a tab control tab, but only when we're in the left channel
        MT_try2(world)  #e rename to  "Feature Manager" ??
        ##e soon, MT should be not on whole world but on model or cur. part, a specific obj in the world
    )
    graphics_area = _self.world
    ##e ditto for what we show here, except it might not be the exact same object, and it will really be shown in a way
    # that depends on both the current display style and the current tool (command & subcommand)
    graphics_area_topright_buttons = current_tool.graphics_area_topright_buttons
    # overall appearance
    delegate = Overlay(
        # stuff in the corners -- note, these don't use the corner constants for standalone tests like PM_CORNER
        DrawInCorner(corner=UPPER_LEFT)(
            SimpleColumn(
                toolbar,
                #e add tab control
                SimpleRow(
                    If(
                        current_tool.property_manager, Top(propmgr), None
                    ),  #k None?? prob ok now, see demo_MT comment 070302 ###k
                    Top(mt)
                ),  #e actually we'd then put a splitter & glpane-like-thing...
                #e anything just below the propmgr?
            )),
        DrawInCorner(corner=UPPER_RIGHT)
        (  ##e of graphics area, not entire screen...
            graphics_area_topright_buttons  ### WRONG, these should go under the main toolbar area on the right
            # (but we don't yet have any 2dwidgets which expand to fill the available space, except DrawInCorner of entire screen)
            # (this won't matter once the toolbar is done entirely in Qt, so we don't need to correct it for now)
        ),
        #e other corners? "... an area (view) on the right side
        # of the main window for accessing the part library, on-line documentation, etc"
        # the main graphics area
        #e [this too ought to go under the toolbar and to the right of the propmgr, but that can wait until they're fully in Qt]
        graphics_area)
    pass
Exemple #13
0
    import foundation.env as env
    polyline = env.prefs.get(kluge_dragtool_state_prefs_key + "bla",
                             False)  #070223 new hack
    if polyline:
        return "polyline"
    # for this kluge, let the stored value be False or True for whether it's drag
    drag = env.prefs.get(kluge_dragtool_state_prefs_key,
                         kluge_dragtool_state_prefs_default)
    return drag and 'drag' or 'draw'


kluge_dragtool_state()  # set the default val

kluge_dragtool_state_checkbox_expr = SimpleColumn(  # note, on 061215 late, checkbox_pref was replaced with a better version, same name
    checkbox_pref(kluge_dragtool_state_prefs_key,
                  "drag new nodes?",
                  dflt=kluge_dragtool_state_prefs_default),
    checkbox_pref(kluge_dragtool_state_prefs_key + "bla", "some other pref"),
)


def demo_drag_toolcorner_expr_maker(world):  #070106 improving the above
    # given an instance of World, return an expr for the "toolcorner" for use along with GraphDrawDemo_FixedToolOnArg1 (on the same World)
    expr = SimpleColumn(
        checkbox_pref(kluge_dragtool_state_prefs_key,
                      "drag new nodes?",
                      dflt=kluge_dragtool_state_prefs_default),
        checkbox_pref(kluge_dragtool_state_prefs_key + "bla",
                      "make polyline?",
                      dflt=False),
        checkbox_pref(kluge_dragtool_state_prefs_key + "bla2",
                      "(make it closed?)",