Esempio n. 1
0
def _ArgOption_helper(attr_expr,
                      argpos_expr,
                      type_expr,
                      dflt_expr,
                      _lvalue_flag=False,
                      _arglist=False,
                      **moreopts):
    """
    [private helper for Arg, Option, and maybe ArgOrOption]

    attr_expr should be None, or some sort of expr (in practice always _E_ATTR so far)
      that will get replaced by a constant_Expr for the current attr (in ExprsMeta's FormulaScanner),
      according to whether the current attr should be part of the index and a public option-name for supplying the arg
      (we make sure those conditions are the same). [#e Note that if someday we wanted to include f(attr) in the index,
      but still use attr alone as an option name, we'd have to modify this to permit both f(attr) (or f) and attr to be passed.]

    argpos_expr should similarly be None, or some sort of expr (in practice a private subclass of internal_Expr)
      that will get replaced by a constant_Expr for the argument position (an int) that should be allocated to the current attr's arg
      (determined in ExprsMeta's FormulaScanner by allocating posns 0,1,2,etc to newly seen arg-attrs, whether or not the attr itself
      is public for that arg).

    type_expr ###doc, passed herein to canon_type

    dflt_expr ###doc, can also be _E_DFLT_FROM_TYPE_ or [handled in caller i think, but survives here unmatteringly] _E_REQUIRED_ARG_;
        will be passed through canon_expr

    _lvalue_flag is a private option used by LvalueArg.

    _arglist is a private option used by ArgList.
    """
    if _lvalue_flag:
        printnim("_lvalue_flag's proper interaction with dflt_expr is nim"
                 )  # in all cases below
        ### guess: we want it to be an expr for a default stateref
    global _self  # fyi
    type_expr = canon_type(type_expr)
    printnim(
        "can type_expr legally be self-dependent and/or time-dependent? ###k I guess that's nim in current code!"
    )  #070115 comment
    if _arglist:
        # new feature 070321. The type is applied to each element, but the default value is for the entire list --
        # OTOH, when would it ever be used, since even if no args are supplied, the list can be formed??
        # Probably it would only be used when the list was 0 length, and could meaningfully be [], (), or another list-like thing...
        # this is all a guess and I probably won't even review this code for this issue now, unless it fails when tried. ####k
        type_expr = tuple_Expr(
            type_expr
        )  # type-coerce the value to a list of the given type [070321 guess] ###e or list_Expr???
    if dflt_expr is _E_DFLT_FROM_TYPE_:
        dflt_expr = default_expr_from_type_expr(type_expr)
        ## note [070115], this would be impossible for time-dependent types! and for self-dep ones, possible but harder than current code.
        assert is_pure_expr(dflt_expr)  #k guess 061105
    else:
        dflt_expr = canon_expr(
            dflt_expr
        )  # hopefully this finally will fix dflt 10 bug, 061105 guesshope ###k [works for None, 061114]
        assert is_pure_expr(
            dflt_expr
        )  # not sure this is redundant, since not sure if canon_expr checks for Instance ###k
        printnim("not sure if canon_expr checks for Instance")
    # Note on why we use explicit call_Expr & getattr_Expr below,
    # rather than () and . notation like you can use in user-level formulae (which python turns into __call__ and getattr),
    # to construct Exprs like _self._i_grabarg( attr_expr, ...):
    # it's only to work around safety features which normally detect that kind of Expr-formation (getattr on _i_* or _e_*,
    # or getattr then call) as a likely error. These safety features are very important, catching errors that would often lead
    # to hard-to-diagnose bugs (when our code has an Expr but thinks it has an Instance), so it's worth the trouble.
    held_dflt_expr = hold_Expr(dflt_expr)
    # Note, this gets evalled back into dflt_expr (treated as inert, may or may not be an expr depending on what it is right here)
    # by the time _i_grabarg sees it (the eval is done when the call_Expr evals its args before doing the call).
    # So if we wanted _i_grabarg to want None rather than _E_REQUIRED_ARG_ as a special case, we could change to that (there & here).
    grabopts = {}
    if _arglist:
        grabopts.update(dict(_arglist=constant_Expr(_arglist)))
    grabarg_expr = call_Expr(getattr_Expr(_self, '_i_grabarg'), attr_expr,
                             argpos_expr, held_dflt_expr, **grabopts)
    # comments 070115:
    # - This will eval to an expr which depends on self but not on time. We could optim by wrapping it
    # (or declaring it final) in a way which effectively replaced it with its value-expr when first used.
    # (But it's not obvious where to store the result of that, since the exprs being returned now are assigned to classes
    #  and will never be specific to single selfs. Do we need an expr to use here, which can cache its own info in self??
    #  Note: AFAIK, self will be the same as what _self gets replaced with when this is used. (We ought to assert that.) ###e)
    # - Further, grabarg_expr is probably supposed to be wrapped *directly* by eval_Expr, not with type_expr inside. I think I'll
    # make that change right now and test it with EVAL_REFORM still False, since I think it's always been required, as said
    # in other comments here. DOING THIS NOW.
    if attr_expr is not None and argpos_expr is not None:
        # for ArgOrOption, use a tuple of a string and int (attr and argpos) as the index
        index_expr = tuple_Expr(attr_expr, argpos_expr)
    elif attr_expr is None and argpos_expr is None:
        assert 0, "attr_expr is None and argpos_expr is None ..."
    elif attr_expr is not None:
        # for Option, use a plain attr string as the index
        index_expr = attr_expr
    else:
        assert argpos_expr is not None
        # for Arg, use a plain int as the index
        # (note: ExprsMeta replaces argpos_expr with that int wrapped in constant_Expr, but later eval pulls out the raw int)
        index_expr = argpos_expr


# see if this is fixed now, not that it means much since we were using a stub... but who knows, maybe the stub was buggy
# and we compensated for that and this could if so cause a bug:
##    printnim("I suspect type_expr (stub now) is included wrongly re eval_Expr in _ArgOption_helper, in hindsight 061117")
##        ### I suspect the above, because grabarg expr needs to be evalled to get the expr whose type coercion we want to instantiate
    res = Instance(_type_coercion_expr(type_expr, eval_Expr(grabarg_expr)),
                   _index_expr=index_expr,
                   _lvalue_flag=_lvalue_flag,
                   **moreopts)
    # note: moreopts might contain _noinstance = True, and if so, Instance normally returns its first arg unchanged
    # (depending on other options).
    # 070115 replaced eval_Expr( type_expr( grabarg_expr)) with _type_coercion_expr( type_expr, eval_Expr(grabarg_expr) )
    return res  # from _ArgOption_helper
Esempio n. 2
0
 def _i_grabarg_0(self, attr, argpos, dflt_expr, _arglist=False):
     """
     [private helper for _i_grabarg]
     return the pair (external-flag, expr to use for this arg)
     """
     # i think dflt_expr can be _E_REQUIRED_ARG_, or any (other) expr
     if dflt_expr is _E_REQUIRED_ARG_:
         required = True
     else:
         required = False
         if isinstance(dflt_expr, _E_REQUIRED_ARG_.__class__
                       ) and dflt_expr._e_name.startswith("_E_"):
             print "possible bug: dflt_expr for arg %r in %r is a Symbol %r named _E_* (suspicious internal symbol??)" % \
                   ( (attr, argpos), self, dflt_expr )
             # kluge sanity check for _E_ATTR or other internal symbols [revised 070131]
     if attr is not None and argpos is not None:
         printnim(
             "should assert that no expr gets same arg twice (positionally and as named option)"
         )  ###e
     if attr is not None:
         # try to find it in _e_kws; I suppose the cond is an optim or for clarity, since None won't be a key of _e_kws
         try:
             return True, self._e_kws[attr]
         except KeyError:
             pass
     if argpos is not None:
         try:
             res = self._e_args[argpos]
         except IndexError:  # "tuple index out of range"
             pass
         else:
             # res was the arg provided at argpos
             if _arglist:
                 res = tuple_Expr(*self._e_args[argpos:])
             return True, res
     # no arg was provided at argpos
     if _arglist:
         # [_arglist supports ArgList, a new feature 070321]
         # no args were provided for an ArgList -- use dflt_expr, or tuple_Expr().
         # (Note: we don't use list_Expr. See comments near def of ArgList.)
         if required:
             return False, tuple_Expr()  #k probably equiv to canon_expr(())
             ##k optim-related Q: what should external_flag be in this case? [070321 Q]
         else:
             return False, dflt_expr  # note: nothing fundamental requires that dflt_expr evals/instantiates to a list or tuple,
             # though it would usually be an error if it doesn't (depending on how the class body formulae were written).
             # It's not an error per se, just likely to be one given how ArgList is conventionally used.
     else:
         # ordinary arg was not provided -- error or use dflt_expr
         if required:
             print "error: required arg %r or %r not provided to %r. [#e Instance-maker should have complained!] Using None." % \
                   (attr, argpos, self)
             # Note: older code returned literally None, not an expr, which caused a bug in caller which tried to _e_eval the result.
             # Once we've printed the above, we might as well be easier to debug and not cause that bug right now,
             # so we'll return a legal expr -- in some few cases this will not cause an error, making this effectively a warning,
             # "missing args are interpreted as None". Review this later. [061118]
             printnim(
                 "a better error retval might be a visible error indicator, if the type happens to be a widget"
             )  ###e
             #e I think we don't know the type here -- but we can return a general error-meaning-thing (incl error msg text)
             # and let the type-coercers do with it what they will. Or we could return something equivalent to an exception
             # (in our interpreted language) and revise our eval semantics to handle that kind of thing. [061118]
             return False, canon_expr(None)
             ##k optim-related Q: what should external_flag be in this case? [070321 Q]
         else:
             return False, dflt_expr
     pass  # above should not _e_eval or canon_expr without review -- should return an arg or dflt expr, not its value
Esempio n. 3
0
def _ArgOption_helper( attr_expr, argpos_expr, type_expr, dflt_expr, _lvalue_flag = False, _arglist = False, **moreopts ):
    """
    [private helper for Arg, Option, and maybe ArgOrOption]

    attr_expr should be None, or some sort of expr (in practice always _E_ATTR so far)
      that will get replaced by a constant_Expr for the current attr (in ExprsMeta's FormulaScanner),
      according to whether the current attr should be part of the index and a public option-name for supplying the arg
      (we make sure those conditions are the same). [#e Note that if someday we wanted to include f(attr) in the index,
      but still use attr alone as an option name, we'd have to modify this to permit both f(attr) (or f) and attr to be passed.]

    argpos_expr should similarly be None, or some sort of expr (in practice a private subclass of internal_Expr)
      that will get replaced by a constant_Expr for the argument position (an int) that should be allocated to the current attr's arg
      (determined in ExprsMeta's FormulaScanner by allocating posns 0,1,2,etc to newly seen arg-attrs, whether or not the attr itself
      is public for that arg).

    type_expr ###doc, passed herein to canon_type

    dflt_expr ###doc, can also be _E_DFLT_FROM_TYPE_ or [handled in caller i think, but survives here unmatteringly] _E_REQUIRED_ARG_;
        will be passed through canon_expr

    _lvalue_flag is a private option used by LvalueArg.

    _arglist is a private option used by ArgList.
    """
    if _lvalue_flag:
        printnim("_lvalue_flag's proper interaction with dflt_expr is nim") # in all cases below
            ### guess: we want it to be an expr for a default stateref
    global _self # fyi
    type_expr = canon_type( type_expr)
    printnim("can type_expr legally be self-dependent and/or time-dependent? ###k I guess that's nim in current code!")#070115 comment
    if _arglist:
        # new feature 070321. The type is applied to each element, but the default value is for the entire list --
        # OTOH, when would it ever be used, since even if no args are supplied, the list can be formed??
        # Probably it would only be used when the list was 0 length, and could meaningfully be [], (), or another list-like thing...
        # this is all a guess and I probably won't even review this code for this issue now, unless it fails when tried. ####k
        type_expr = tuple_Expr(type_expr) # type-coerce the value to a list of the given type [070321 guess] ###e or list_Expr???
    if dflt_expr is _E_DFLT_FROM_TYPE_:
        dflt_expr = default_expr_from_type_expr( type_expr)
            ## note [070115], this would be impossible for time-dependent types! and for self-dep ones, possible but harder than current code.
        assert is_pure_expr(dflt_expr) #k guess 061105
    else:
        dflt_expr = canon_expr(dflt_expr) # hopefully this finally will fix dflt 10 bug, 061105 guesshope ###k [works for None, 061114]
        assert is_pure_expr(dflt_expr) # not sure this is redundant, since not sure if canon_expr checks for Instance ###k
        printnim("not sure if canon_expr checks for Instance")
    # Note on why we use explicit call_Expr & getattr_Expr below,
    # rather than () and . notation like you can use in user-level formulae (which python turns into __call__ and getattr),
    # to construct Exprs like _self._i_grabarg( attr_expr, ...):
    # it's only to work around safety features which normally detect that kind of Expr-formation (getattr on _i_* or _e_*,
    # or getattr then call) as a likely error. These safety features are very important, catching errors that would often lead
    # to hard-to-diagnose bugs (when our code has an Expr but thinks it has an Instance), so it's worth the trouble.
    held_dflt_expr = hold_Expr(dflt_expr) 
        # Note, this gets evalled back into dflt_expr (treated as inert, may or may not be an expr depending on what it is right here)
        # by the time _i_grabarg sees it (the eval is done when the call_Expr evals its args before doing the call).
        # So if we wanted _i_grabarg to want None rather than _E_REQUIRED_ARG_ as a special case, we could change to that (there & here).
    grabopts = {}
    if _arglist:
        grabopts.update(dict(_arglist = constant_Expr(_arglist)))
    grabarg_expr = call_Expr( getattr_Expr(_self, '_i_grabarg'), attr_expr, argpos_expr, held_dflt_expr, **grabopts )
        # comments 070115:
        # - This will eval to an expr which depends on self but not on time. We could optim by wrapping it
        # (or declaring it final) in a way which effectively replaced it with its value-expr when first used.
        # (But it's not obvious where to store the result of that, since the exprs being returned now are assigned to classes
        #  and will never be specific to single selfs. Do we need an expr to use here, which can cache its own info in self??
        #  Note: AFAIK, self will be the same as what _self gets replaced with when this is used. (We ought to assert that.) ###e)
        # - Further, grabarg_expr is probably supposed to be wrapped *directly* by eval_Expr, not with type_expr inside. I think I'll
        # make that change right now and test it with EVAL_REFORM still False, since I think it's always been required, as said
        # in other comments here. DOING THIS NOW.
    if attr_expr is not None and argpos_expr is not None:
        # for ArgOrOption, use a tuple of a string and int (attr and argpos) as the index
        index_expr = tuple_Expr( attr_expr, argpos_expr )
    elif attr_expr is None and argpos_expr is None:
        assert 0, "attr_expr is None and argpos_expr is None ..."
    elif attr_expr is not None:
        # for Option, use a plain attr string as the index
        index_expr = attr_expr
    else:
        assert argpos_expr is not None
        # for Arg, use a plain int as the index
        # (note: ExprsMeta replaces argpos_expr with that int wrapped in constant_Expr, but later eval pulls out the raw int)
        index_expr = argpos_expr
# see if this is fixed now, not that it means much since we were using a stub... but who knows, maybe the stub was buggy
# and we compensated for that and this could if so cause a bug:
##    printnim("I suspect type_expr (stub now) is included wrongly re eval_Expr in _ArgOption_helper, in hindsight 061117")
##        ### I suspect the above, because grabarg expr needs to be evalled to get the expr whose type coercion we want to instantiate
    res = Instance( _type_coercion_expr( type_expr, eval_Expr(grabarg_expr) ),
                     _index_expr = index_expr, _lvalue_flag = _lvalue_flag, **moreopts )
        # note: moreopts might contain _noinstance = True, and if so, Instance normally returns its first arg unchanged
        # (depending on other options).
        # 070115 replaced eval_Expr( type_expr( grabarg_expr)) with _type_coercion_expr( type_expr, eval_Expr(grabarg_expr) )
    return res # from _ArgOption_helper
Esempio n. 4
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
Esempio n. 5
0
 def _i_grabarg_0( self, attr, argpos, dflt_expr, _arglist = False):
     """
     [private helper for _i_grabarg]
     return the pair (external-flag, expr to use for this arg)
     """
     # i think dflt_expr can be _E_REQUIRED_ARG_, or any (other) expr
     if dflt_expr is _E_REQUIRED_ARG_:
         required = True
     else:
         required = False
         if isinstance(dflt_expr, _E_REQUIRED_ARG_.__class__) and dflt_expr._e_name.startswith("_E_"):
             print "possible bug: dflt_expr for arg %r in %r is a Symbol %r named _E_* (suspicious internal symbol??)" % \
                   ( (attr, argpos), self, dflt_expr )
             # kluge sanity check for _E_ATTR or other internal symbols [revised 070131]
     if attr is not None and argpos is not None:
         printnim("should assert that no expr gets same arg twice (positionally and as named option)")###e
     if attr is not None:
         # try to find it in _e_kws; I suppose the cond is an optim or for clarity, since None won't be a key of _e_kws
         try:
             return True, self._e_kws[attr]
         except KeyError:
             pass
     if argpos is not None:
         try:
             res = self._e_args[argpos]
         except IndexError: # "tuple index out of range"
             pass
         else:
             # res was the arg provided at argpos
             if _arglist:
                 res = tuple_Expr(* self._e_args[argpos:])
             return True, res                
     # no arg was provided at argpos
     if _arglist:
         # [_arglist supports ArgList, a new feature 070321]
         # no args were provided for an ArgList -- use dflt_expr, or tuple_Expr().
         # (Note: we don't use list_Expr. See comments near def of ArgList.)
         if required:
             return False, tuple_Expr() #k probably equiv to canon_expr(())
                  ##k optim-related Q: what should external_flag be in this case? [070321 Q]
         else:
             return False, dflt_expr # note: nothing fundamental requires that dflt_expr evals/instantiates to a list or tuple,
                 # though it would usually be an error if it doesn't (depending on how the class body formulae were written).
                 # It's not an error per se, just likely to be one given how ArgList is conventionally used.
     else:
         # ordinary arg was not provided -- error or use dflt_expr
         if required:
             print "error: required arg %r or %r not provided to %r. [#e Instance-maker should have complained!] Using None." % \
                   (attr, argpos, self)
             # Note: older code returned literally None, not an expr, which caused a bug in caller which tried to _e_eval the result.
             # Once we've printed the above, we might as well be easier to debug and not cause that bug right now,
             # so we'll return a legal expr -- in some few cases this will not cause an error, making this effectively a warning,
             # "missing args are interpreted as None". Review this later. [061118]
             printnim("a better error retval might be a visible error indicator, if the type happens to be a widget")###e
                 #e I think we don't know the type here -- but we can return a general error-meaning-thing (incl error msg text)
                 # and let the type-coercers do with it what they will. Or we could return something equivalent to an exception
                 # (in our interpreted language) and revise our eval semantics to handle that kind of thing. [061118]
             return False, canon_expr(None)
                 ##k optim-related Q: what should external_flag be in this case? [070321 Q]
         else:
             return False, dflt_expr
     pass # above should not _e_eval or canon_expr without review -- should return an arg or dflt expr, not its value
Esempio n. 6
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