class _height_dragger(DelegatingInstanceOrExpr): # args #e coordsystem? for now let x/y be the way it spreads, z be the height height_ref = Arg(StateRef, doc="stateref to a height variable") # appearance/behavior #e should draw some "walls" too, and maybe limit the height # note: the following sets up a cyclic inter-Instance ref ( drag_handler -> delegate -> drag_handler); # it works since the actual refs are symbolic (getattr_Expr(_self, 'attr'), not evalled except when used). drag_handler = Instance( xxx_drag_behavior(_self._delegate, height_ref, Ray(ORIGIN, DX))) ### DX for initial test, then DZ # note: passing _self._delegate (not _self.delegate) fixed my "undiagnosed bug". delegate = DraggableObject( Image( "blueflake.png" ), ###e needs an option to be visible from both sides (default True, probably) ## constrain_delta = _self.constrain_delta, ###IMPLEM constrain_delta in DraggableObject ## delta_stateref = height_ref ###IMPLEM delta_stateref [done] (and rename it); and change this to make height_ref a number not vector; ##e and maybe include the constraint in that transform, since it seems implicit in it anyway. ####HOW in semantics? # ... = PropertyRef(DZ * height_ref.value, Set( height_ref.value, project_onto_unit_vector( _something, DZ )) # ... = TransformStateRef( height_ref, ... ) # funcs? or formula in terms of 1 or 2 vars? with a chance at solving it?? ##e _kluge_drag_handler=drag_handler) ## def constrain_delta(self, delta): ## not yet - called ## return project_onto_unit_vector( delta, DZ) pass
def current_event_mouseray(self): p0 = self.highlightable.current_event_mousepoint( depth=0.0) # nearest depth ###k p1 = self.highlightable.current_event_mousepoint( depth=1.0) # farthest depth ###k return Ray( p0, p1 - p0 ) #e passing just p1 should be ok too, but both forms can't work unless p0,p1 are typed objects...
class xxx_drag_behavior( DragBehavior ): # revised 070316; on 070318 removed comments that were copied into version _3 """a drag behavior which moves the original hitpoint along a line, storing only its 1d-position-offset along the line's direction [noting that the hitpoint is not necessarily equal to the moved object's origin] [#doc better] """ # args highlightable = Arg( DraggableObject ) # kluge; revised 070316, delegate -> highlightable [works no worse than before [same bug as before]] # [but it's misnamed -- it has to be a DraggableObject since we modify its .motion] ###e rename, but what is it for? posn_parameter_ref = Arg(StateRef, doc="where the variable height is stored") ###e rename constrain_to_line = Arg( Ray, Ray(ORIGIN, DY), doc="the line/ray on which the height is interpreted as a position") ###e rename: constraint_line? line_to_constrain_to? constrain_to_this_line? # dflt_expr is just for testing #e remove it def current_event_mouseray(self): p0 = self.highlightable.current_event_mousepoint( depth=0.0) # nearest depth ###k p1 = self.highlightable.current_event_mousepoint( depth=1.0) # farthest depth ###k return Ray( p0, p1 - p0 ) #e passing just p1 should be ok too, but both forms can't work unless p0,p1 are typed objects... def on_press(self): self.startpoint = self.highlightable.current_event_mousepoint( ) # the touched point on the visible object (hitpoint) self.offset = self.startpoint - ( ORIGIN + self.highlightable.motion ) #k maybe ok for now, but check whether sensible in long run self.line = self.constrain_to_line + self.offset # the line the hitpoint is on (assuming self.motion already obeyed the constraint) def on_drag(self): # Note: we can assume this is a "real drag" (not one which is too short to count), due to how we are called. mouseray = self.current_event_mouseray() ## self._cmd_drag_from_to( oldpoint, point) # use Draggable interface cmd on self # ie self.delta_stateref.value = self.delta_stateref.value + (p2 - p1) ## def drag_mouseray_from_to(self, oldray, newray): # sort of like _cmd_from_to (sp?) in other eg code ## "[part of an interface XXX related to drag behaviors]" k = self.line.closest_pt_params_to_ray(mouseray) if k is not None: # store k self.posn_parameter_ref.value = k ####e by analogy with DraggableObject, should we perhaps save this side effect until the end? # compute new posn from k self.highlightable.motion = self.constrain_to_line.posn_from_params( k) #e review renaming, since we are asking it for a 3-tuple ####### LOGIC BUG: what causes self.motion to initially come from this formula, not from our own state? # maybe don't use DraggableObject at all? [or as initial kluge, just let initial motion and initial height both be 0] return def on_release(self): pass pass # end of class xxx_drag_behavior
def current_event_mouseray(self): p0 = self.current_event_mousepoint(depth = 0.0) # nearest depth ###k p1 = self.current_event_mousepoint(depth = 1.0) # farthest depth ###k return Ray(p0, p1 - p0)