sub_arctic.input
Class snap_drag_agent

java.lang.Object
  |
  +--sub_arctic.input.dispatch_agent
        |
        +--sub_arctic.input.focus_dispatch_agent
              |
              +--sub_arctic.input.single_focus_agent
                    |
                    +--sub_arctic.input.snap_drag_agent

public class snap_drag_agent
extends single_focus_agent

Focus agent that implements snap-dragging. Snap dragging is an interaction technique where objects being dragged snap to interesting points within objects they are dragged over. These interesting points typically represent semantically interesting places to "let go of" the dragged object such as positions where they will legally "connect to" other object. The determination of what represents an interesting point is done by means of predicates on the objects snapped from (the ones being dragged) and snapped to (the ones "under" them). In snap dragging, dragged objects implement the snap_draggable protocol, while objects which they are dragged over, and can be snapped to, implement the snap_targetable protocol (and generally are called snap targets).

Each dragged object advertises a set of feature points. By default base_interactor provides 5: the 4 corners plus the center of the object. Other object types may provide additional or complete different points that suit their semantics. Each active feature point is eligible to snap to a snap target object. Snap target objects are not limited to being points and may implement areas, lines, points, and other geometric forms. With each target comes a geometric test to determine if a point is considered close enough to the target to snap to it (and provide a distance to it). Snapping occurs by considering active feature point within snapping distance of a target. For each geometrically possible snap, semantic tests are performed to determine if the snap is semantically acceptable (i.e., it constitutes an "interesting" snap). The closest candidate snap that passes semantic tests is performed. Both dragged and target objects are informed of the snap (an any subsequent unsnap) and given the opportunity to provide feedback. If snaps are geometrically possible, but none pass the semantic tests, then starting with the closest each is given the opportunity to make a special "anti-snap". This is done to provide negative feedback (I kind of error message) which indicates why a geometrically legal snap has been ruled out semantically.

Once a snap has been performed, users can reject the snap by moving the dragged object out of range of the snap. In addition, the snap can be rejected and disabled (for the duration of the drag operation) by pressing a designated keyboard key (by default space -- this can be changed with the set_snap_break_key() method) while the snap is in force.

Note: in order for snap disabling to occur, this agent needs to be (and by default is) installed before the text focus agent within the agent list of the focus policy.

See Also:
snap_draggable, snap_targetable

Field Summary
protected static int _bound_traversal
          Traversal identifier for the snap bound test traversal
protected static int _snap_break_key
          The keyboard event code used to signal that the currently active snap should be be broken and disabled.
protected  sub_arctic.input.snap_record active_anti_snap
          Snap record containing information about the currently active anti-snap (or null if there is none).
protected  java.lang.Object active_anti_snap_info
          Application specific information about the currently active anti-snap
protected  sub_arctic.input.snap_record active_snap
          Snap record containing information about the currently active snap (or null if there is none).
protected  java.lang.reflect.Method anti_snap_feedback
          Keep a reference to the method anti_snap_feedback in our protocol.
protected  java.lang.reflect.Method anti_snap_to
          Keep a reference to the method anti_snap_to in our protocol.
protected  java.lang.reflect.Method drag_end
          Keep a reference to the method drag_end in the normal move protocol.
protected  java.lang.reflect.Method drag_feedback
          Keep a reference to the method drag_feedback in the normal move protocol.
protected  java.lang.reflect.Method drag_start
          Keep a reference to the method drag_start in the normal move protocol.
protected  java.util.Vector feature_points
          Set of active feature points of the object being dragged (stored as a Vector of Point objects).
protected  int feature_rect_h
          Height of feature point bounding rectangle
protected  int feature_rect_w
          Width of feature point bounding rectangle
protected  int grab_x
          Grab x position (start position in local coordinates).
protected  int grab_y
          Grab y position (start position in local coordinates).
protected static interactor_pred is_snap_obj
          Interactor predicate object to test if an object is a snap_targetable.
protected  int min_feature_x
          Min x of feature points
protected  int min_feature_y
          Min y of feature points
protected  int num_feature_points
          Number of active feature points for the object currently being dragged.
protected static interactor_pred overlaps
          Interactor predicate object to test if an expanded snap region overlaps the bounds of an object.
protected static traversal_xform rect_to_child
          Traversal transformation object to transform a Rectangle from parent to child coordinates.
protected  java.util.Hashtable rejected_snaps
          Table of snaps that the user has rejected and disabled for this drag.
protected static interactor_pred snap_and_overlap
          Interactor predicate object to test if an object is both a snap_targetable object and passes the overlap test.
protected  java.lang.reflect.Method snap_feedback
          Keep a reference to the method snap_feedback in our protocol.
protected  java.lang.reflect.Method snap_to
          Keep a reference to the method snap_to in our protocol.
protected  int start_x
          Start x position of the current drag (in global coordinates)
protected  int start_y
          Start y position of the current drag (in global coordinates)
protected  java.lang.reflect.Method unanti_snap_to
          Keep a reference to the method unanti_snap_to in our protocol.
protected  java.lang.reflect.Method unsnap_to
          Keep a reference to the method unsnap_to in our protocol.
 
Fields inherited from class sub_arctic.input.focus_dispatch_agent
_focus_set, _user_info_set
 
Constructor Summary
snap_drag_agent()
          Default constructor
 
Method Summary
 boolean allowable_focus(focusable candidate_obj)
          Method to limit the objects allowable as members of the focus set.
static int bound_traversal()
          Traversal identifier for the snap bound test traversal
protected  void break_active_anti_snap(event evt, java.lang.Object user_info)
          Break the currently active anti_snap
protected  void break_active_snap(event evt, java.lang.Object user_info)
          Break the currently active snap.
protected  void collect_feature_info(interactor obj)
          Collect feature point information from a new focus object.
 boolean dispatch_event(event evt, java.lang.Object user_info, interactor to_obj, int seq_num)
          Dispatch an event under this protocol.
 boolean event_is_useful(event evt)
          Method to determine if this agent needs to see a given event.
protected  pick_collector find_overlapped_targets(int new_x, int new_y, snap_draggable drag_obj)
          Collect the set of snap target objects whose bounds are within snapping distance of the bounding box of the feature points of the object being dragged.
 boolean have_active_anti_snap()
          Indicate whether we have an active anti-snap
 boolean have_active_snap()
          Indicate whether we have an active snap
 boolean have_active()
          Indicate whether we have either an active snap or anti_snap
protected  void inform_focus_enter(focusable obj, event evt, java.lang.Object user_info)
          Override the normal inform_focus_enter to deliver the drag_start().
protected  void inform_focus_exit(focusable obj, event evt, java.lang.Object user_info)
          Override the normal inform_focus_exit to deliver the drag_end().
protected  boolean make_anti_snap_active(sub_arctic.input.snap_record snap_rec, event evt, java.lang.Object anti_snap_info, java.lang.Object user_info)
          Activate a new anti-snap.
protected  boolean make_snap_active(sub_arctic.input.snap_record snap_rec, event evt, java.lang.Object user_info)
          Activate a new snap.
protected  boolean process_snap(int new_x, int new_y, snap_draggable drag_obj, event evt, java.lang.Object user_info)
          Attempt to find a snap point between some active feature point of the currently dragged object and some snap_targetable object.
static void set_snap_break_key(int char_val)
          Set the keyboard event code used to signal that the currently active snap should be be broken and disabled.
static int snap_break_key()
          The keyboard event code used to signal that the currently active snap should be be broken and disabled.
static int snap_dist()
          Distance at which snap points should become active
static int snap_dist2()
          Square of distance at which snap points should become active
 
Methods inherited from class sub_arctic.input.single_focus_agent
add_to_focus, clear_focus, remove_from_focus, set_focus_to
 
Methods inherited from class sub_arctic.input.focus_dispatch_agent
focus_item, focus_set_size, is_in_focus, user_info_item
 
Methods inherited from class sub_arctic.input.dispatch_agent
after_dispatch_notify, dispatch_unused_event
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

snap_to

protected java.lang.reflect.Method snap_to
Keep a reference to the method snap_to in our protocol.

snap_feedback

protected java.lang.reflect.Method snap_feedback
Keep a reference to the method snap_feedback in our protocol.

unsnap_to

protected java.lang.reflect.Method unsnap_to
Keep a reference to the method unsnap_to in our protocol.

anti_snap_to

protected java.lang.reflect.Method anti_snap_to
Keep a reference to the method anti_snap_to in our protocol.

anti_snap_feedback

protected java.lang.reflect.Method anti_snap_feedback
Keep a reference to the method anti_snap_feedback in our protocol.

unanti_snap_to

protected java.lang.reflect.Method unanti_snap_to
Keep a reference to the method unanti_snap_to in our protocol.

drag_start

protected java.lang.reflect.Method drag_start
Keep a reference to the method drag_start in the normal move protocol.

drag_feedback

protected java.lang.reflect.Method drag_feedback
Keep a reference to the method drag_feedback in the normal move protocol.

drag_end

protected java.lang.reflect.Method drag_end
Keep a reference to the method drag_end in the normal move protocol.

_snap_break_key

protected static int _snap_break_key
The keyboard event code used to signal that the currently active snap should be be broken and disabled. The snap stays disabled until the next snap drag sequence. Currently this key is .

start_x

protected int start_x
Start x position of the current drag (in global coordinates)

start_y

protected int start_y
Start y position of the current drag (in global coordinates)

grab_x

protected int grab_x
Grab x position (start position in local coordinates). This is where the cursor was positioned relative to the object when the mouse button went down to initiate the drag.

grab_y

protected int grab_y
Grab y position (start position in local coordinates). This is where the cursor was positioned relative to the object when the mouse button went down to initiate the drag.

feature_points

protected java.util.Vector feature_points
Set of active feature points of the object being dragged (stored as a Vector of Point objects).

num_feature_points

protected int num_feature_points
Number of active feature points for the object currently being dragged.

min_feature_x

protected int min_feature_x
Min x of feature points

min_feature_y

protected int min_feature_y
Min y of feature points

feature_rect_w

protected int feature_rect_w
Width of feature point bounding rectangle

feature_rect_h

protected int feature_rect_h
Height of feature point bounding rectangle

_bound_traversal

protected static final int _bound_traversal
Traversal identifier for the snap bound test traversal

overlaps

protected static final interactor_pred overlaps
Interactor predicate object to test if an expanded snap region overlaps the bounds of an object. The parameter to this predicate is a Rectangle object which represents the bound of the feature points of the drag object, expanded by the maximum snap_distance.

is_snap_obj

protected static final interactor_pred is_snap_obj
Interactor predicate object to test if an object is a snap_targetable.

snap_and_overlap

protected static final interactor_pred snap_and_overlap
Interactor predicate object to test if an object is both a snap_targetable object and passes the overlap test.

rect_to_child

protected static final traversal_xform rect_to_child
Traversal transformation object to transform a Rectangle from parent to child coordinates.

active_snap

protected sub_arctic.input.snap_record active_snap
Snap record containing information about the currently active snap (or null if there is none).

active_anti_snap

protected sub_arctic.input.snap_record active_anti_snap
Snap record containing information about the currently active anti-snap (or null if there is none).

active_anti_snap_info

protected java.lang.Object active_anti_snap_info
Application specific information about the currently active anti-snap

rejected_snaps

protected java.util.Hashtable rejected_snaps
Table of snaps that the user has rejected and disabled for this drag. This table contains snap_rec objects.
Constructor Detail

snap_drag_agent

public snap_drag_agent()
Default constructor
Method Detail

allowable_focus

public boolean allowable_focus(focusable candidate_obj)
Method to limit the objects allowable as members of the focus set. In this case we only allow things which implement snap_draggable.
Parameters:
candidate_obj - the object we are deciding upon
Returns:
a boolean indicating if the object is acceptable
Overrides:
allowable_focus in class focus_dispatch_agent

snap_break_key

public static int snap_break_key()
The keyboard event code used to signal that the currently active snap should be be broken and disabled. The snap stays disabled until the next snap drag sequence. Currently this key is .

set_snap_break_key

public static void set_snap_break_key(int char_val)
Set the keyboard event code used to signal that the currently active snap should be be broken and disabled. The snap stays disabled until the next snap drag sequence.

event_is_useful

public boolean event_is_useful(event evt)
Method to determine if this agent needs to see a given event. In this case we are interested in MOUSE_DRAGGED, MOUSE_MOVED and MOUSE_RELEASED all the time and the keyboard events associated for breaking a snap only when we have an active snap or anti_snap.
Parameters:
evt - the event in question
Overrides:
event_is_useful in class dispatch_agent

collect_feature_info

protected void collect_feature_info(interactor obj)
Collect feature point information from a new focus object. Information is stored in various instance variables for use during the drag.
Parameters:
interactor - obj the object we are collecting feature points from.

inform_focus_enter

protected void inform_focus_enter(focusable obj,
                                  event evt,
                                  java.lang.Object user_info)
Override the normal inform_focus_enter to deliver the drag_start().
Parameters:
obj - the object we are dragging
evt - the event that "caused" the start of drag (typically a mouse button down event)
user_info - an uninterpreted object to be passed to the object
Overrides:
inform_focus_enter in class focus_dispatch_agent

inform_focus_exit

protected void inform_focus_exit(focusable obj,
                                 event evt,
                                 java.lang.Object user_info)
Override the normal inform_focus_exit to deliver the drag_end().
Parameters:
obj - the object we are dragging
evt - the event that "caused" the end of drag (typically a mouse button up event)
user_info - an uninterpreted object to be passed to the object
Overrides:
inform_focus_exit in class focus_dispatch_agent

snap_dist

public static int snap_dist()
Distance at which snap points should become active

snap_dist2

public static int snap_dist2()
Square of distance at which snap points should become active

bound_traversal

public static int bound_traversal()
Traversal identifier for the snap bound test traversal

have_active_snap

public boolean have_active_snap()
Indicate whether we have an active snap

have_active_anti_snap

public boolean have_active_anti_snap()
Indicate whether we have an active anti-snap

have_active

public boolean have_active()
Indicate whether we have either an active snap or anti_snap

break_active_snap

protected void break_active_snap(event evt,
                                 java.lang.Object user_info)
Break the currently active snap.
Parameters:
event - evt the event "causing" the break.
Object - user_info the user info value passed to the object.

break_active_anti_snap

protected void break_active_anti_snap(event evt,
                                      java.lang.Object user_info)
Break the currently active anti_snap
Parameters:
event - evt the event "causing" the break.
Object - user_info the user info value passed to the object.

make_snap_active

protected boolean make_snap_active(sub_arctic.input.snap_record snap_rec,
                                   event evt,
                                   java.lang.Object user_info)
Activate a new snap.
Parameters:
snap_record - snap_rec record describing the snap we are activating.
event - evt event that "caused" the snap.
Object - user_info the user info passed to the objects.
Returns:
boolean indicating if either the drag object or the target object accepted the snap.

make_anti_snap_active

protected boolean make_anti_snap_active(sub_arctic.input.snap_record snap_rec,
                                        event evt,
                                        java.lang.Object anti_snap_info,
                                        java.lang.Object user_info)
Activate a new anti-snap.
Parameters:
snap_record - snap_rec record describing the anti-snap we are activating.
event - evt event that "caused" the anti-snap.
Object - user_info the user info passed to the objects.
Returns:
boolean indicating if either the drag object or the target object accepted the anti-snap.

find_overlapped_targets

protected pick_collector find_overlapped_targets(int new_x,
                                                 int new_y,
                                                 snap_draggable drag_obj)
Collect the set of snap target objects whose bounds are within snapping distance of the bounding box of the feature points of the object being dragged. The set of objects is returned as a pick_collector object loaded with the possible targets.
Parameters:
int - new_x new left edge of the dragged object
int - new_y new top edge of the dragged object
snap_draggable - drag_obj the dragged object
Returns:
pick_collector containing the set of candidate target objects.

process_snap

protected boolean process_snap(int new_x,
                               int new_y,
                               snap_draggable drag_obj,
                               event evt,
                               java.lang.Object user_info)
Attempt to find a snap point between some active feature point of the currently dragged object and some snap_targetable object. If a snap is found, appropriate calls in the snap_draggable and snap_targetable protocols are made and true is returned. (Protocol calls including unsnap_to() and unsnap_from(), or unanti_snap_to() and unanti_snap_from() for any active snaps or anti-snaps that no longer hold, as well as snap_to() and snap_from(), or anti_snap_to() and anti_snap_from() for new snaps or anti-snaps that become active). If no suitable snap is found, false is returned.
Parameters:
int - new_x new x position of the dragged object.
int - new_y new y position of the dragged object.
snap_draggable - drag_obj the dragged object.
event - evt, the event "causing" the drag.
Object - user_info the user info to be passed.
Returns:
boolean indicating whether a snap has been found.

dispatch_event

public boolean dispatch_event(event evt,
                              java.lang.Object user_info,
                              interactor to_obj,
                              int seq_num)
Dispatch an event under this protocol. This does full snap processing including possible rejection and disabling of active snap points.
Parameters:
evt - the event being dispatched (already approved by event_is_useful())
user_info - an uninterpreted info object to be passed to the dragged object
to_obj - for focus agents this is always null
seq_num - for focus agents this is ignored
Returns:
value indicating if the event was consumed
Overrides:
dispatch_event in class focus_dispatch_agent
See Also:
process_snap(int, int, sub_arctic.input.snap_draggable, sub_arctic.input.event, java.lang.Object)