home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / IDE / SUBARTIC / SUB_ARCT / INPUT / POINT_AG.JAV < prev    next >
Encoding:
Text File  |  1996-10-04  |  13.2 KB  |  444 lines

  1. package sub_arctic.input;
  2. import sub_arctic.lib.interactor;
  3. import sub_arctic.lib.manager;
  4. import sub_arctic.anim.timer;
  5. import sub_arctic.anim.timer_transition;
  6. import sub_arctic.anim.transition;
  7.  
  8. /**
  9.  * This is the agent that handles the pointable interface as well
  10.  * as the display_help interface. It is an agent under the positional policy,
  11.  * but must dispatch events in some cases in which there might be
  12.  * no objects picked by the event. We use the dispatch_unused_event()
  13.  * method on dispatch_agent to get that to work. Further, we use
  14.  * the manager's "after_dispatch" list to get notified when other
  15.  * agents dispatch events.
  16.  * 
  17.  * @author Ian Smith
  18.  */
  19. public class point_agent_class extends dispatch_agent implements timer {
  20.  
  21.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  22.  
  23.   /**
  24.    * This is the transition that is currently pending to let us
  25.    * know when the stable time has elapsed. It is null when
  26.    * no transitions are pending.
  27.    */
  28.   protected transition trans = null;
  29.  
  30.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  31.  
  32.   /**
  33.    * This variable becomes true if we have a help message displayed
  34.    * right now.
  35.    */
  36.   protected boolean help_displayed = false;
  37.  
  38.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  39.  
  40.   /**
  41.    * This holds the number of milliseconds the user must
  42.    * be quiescent with the mouse to get a display help box. It defaults
  43.    * to 1/2 second (500 millis).
  44.    */
  45.   protected long _stable_time = 500;
  46.  
  47.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  48.  
  49.   /**
  50.    * Query the amount of time that the mouse must be stable
  51.    * to get a display help box.
  52.    * @return long the amount of stable time required to get a help display 
  53.    *              (in milliseconds)
  54.    */
  55.   public long stable_time() { return _stable_time;}
  56.  
  57.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  58.  
  59.   /**
  60.    * Set the length of time the user must be stable before a display help
  61.    * display is generated. 
  62.    * @param long stable the length of time in milliseconds
  63.    */
  64.   public void set_stable_time(long stable) { _stable_time=stable;}
  65.  
  66.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  67.  
  68.   /**
  69.    * This variable tells us if we are yet on the managers 
  70.    * list of interested agents for the "after_dispatch" notification.
  71.    */
  72.   protected boolean in_list=false;
  73.  
  74.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  75.  
  76.   /**
  77.    * Highest event ID seen
  78.    */
  79.   protected int highest_event;
  80.  
  81.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  82.  
  83.   /**
  84.    * This is where we keep the object we are currently pointing
  85.    * at (or null to signify the that we aren't pointing at anything).
  86.    */
  87.   protected pointable _point_focus = null;
  88.  
  89.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  90.  
  91.   /**
  92.    * Return the current point focus.
  93.    * @return interactor the interactor we are currently pointing at (well, 
  94.    *                    pointing at <I>and</I> which implements the pointable 
  95.    *                    interface).
  96.    */
  97.   public pointable point_focus() { return _point_focus;}
  98.  
  99.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  100.  
  101.   /**
  102.    * Set the point focus. Pass null to indicate that there is no
  103.    * object currently in the focus.
  104.    * 
  105.    * @param pointable i the new point focus
  106.    * @param event evt the event that caused this change in focus
  107.    */
  108.   public void set_point_focus(pointable i, event evt){
  109.     display_help help;
  110.     event        evt_copy;
  111.  
  112.     /* if we are not on the list in manager, we may need to be ... 
  113.      * also note that we CAN NOT do this in the constructor of this 
  114.      * class because this object is statically initialized in 
  115.      * the manager's initialization,
  116.      * thus we would be making calls on the manager before it has
  117.      * completed its own initialization ... also, this allows people
  118.      * who aren't using this agent to not have any event dispatch
  119.      * overhead */
  120.  
  121.     /* be aware that this code is NOT run if the point_focus is
  122.      * not going to change (same object is pointed at)... 
  123.      * that will result in a call to mouse_event_same_object()*/
  124.     if (i!=null) {
  125.       /* are we in the list? */
  126.       if ( !in_list) {
  127.     in_list=true;
  128.     manager.add_to_after_dispatch_list(this);
  129.       }
  130.     } else {
  131.       /* check for the other case, as well... are we not in list? */
  132.       if (in_list) {
  133.     in_list=false;
  134.     manager.remove_from_after_dispatch_list(this);
  135.       }
  136.  
  137.       /* do we have any transitions pending?*/
  138.       if (trans!=null) {
  139.     manager.animation.remove_transition(trans);
  140.     trans=null;
  141.       }
  142.     }
  143.  
  144.     /* some new focus ... was there a help message up?*/
  145.     if (help_displayed) {
  146.       help=(display_help)_point_focus;
  147.       evt_copy = new event(evt);
  148.       if (help instanceof interactor)
  149.         evt_copy.global_to_local((interactor)help);
  150.       else
  151.     evt_copy.reset_to_global();
  152.       help.help_close(evt_copy);
  153.       help_displayed=false;
  154.     }
  155.  
  156.     /* change the focus */
  157.     _point_focus=i;
  158.   }
  159.  
  160.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  161.  
  162.   /**
  163.    * Construct a point_agent. User's should not have to do this,
  164.    * it should be done by toolkit initialization.
  165.    */
  166.   public point_agent_class() {
  167.   }
  168.  
  169.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  170.  
  171.   /**
  172.    * We are only interested for normal dispatching purposes in
  173.    * move events. We get a hold of the other types of mouse events
  174.    * via the manager's "after_dispatch" list and that is how we
  175.    * handle generating a mouse_exit() call.
  176.    * 
  177.    * @param event evt the event to check to see if we care about it
  178.    * @return boolean return true if its an event we care about
  179.    */
  180.   public boolean event_is_useful(event evt) {
  181.     return (evt.id()==event.MOUSE_MOVE);
  182.   }
  183.  
  184.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  185.  
  186.   /**
  187.    * We override dispatch_unused_event so we can tell the object
  188.    * that the mouse left the area even if the mouse is now not
  189.    * over any of our sub_arctic interactors.
  190.    * @param event evt the event to dispatch
  191.    * @return boolean return true if we dispatched the event
  192.    */
  193.   public boolean dispatch_unused_event(event evt) {
  194.     event evt_copy;
  195.  
  196.     /* make copy of event */
  197.     evt_copy = new event(evt);
  198.  
  199.     /* if we don't have a focus, no work to do */
  200.     if (point_focus()==null) return false;
  201.  
  202.     /* put event in coordinates of object we are dispatching to */
  203.     if (point_focus() instanceof interactor)
  204.       evt_copy.global_to_local((interactor)point_focus());
  205.     else
  206.       evt_copy.reset_to_global();
  207.  
  208.     /* send the message */
  209.     point_focus().mouse_exit(evt_copy);
  210.  
  211.     /* no focus now */
  212.     set_point_focus(null,evt);
  213.  
  214.     /* we handled the event */
  215.     return true;
  216.   }
  217.  
  218.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  219.  
  220.   /**
  221.    * This is the method that does most of the work for dispatching
  222.    * these events.  It determines if the object in question is
  223.    * pointable and if it is sends it the right messages on in and out.
  224.    *
  225.    * @param event evt the event to dispatch
  226.    * @param Object user_info policy defined user information
  227.    * @param interactor to_obj the object to (possibly)send the event to
  228.    * @param int seq_num the sequence number of this event
  229.    */
  230.   public boolean dispatch_event(
  231.     event      evt, 
  232.     Object     user_info,
  233.     interactor to_obj, 
  234.     int        seq_num) {
  235.  
  236.     pointable p,pf=point_focus();
  237.     event evt_copy = new event(evt);
  238.  
  239.     /* first determine if we care about this object */
  240.     if (to_obj instanceof pointable){
  241.  
  242.       /* make sure we record that we saw this */
  243.       if (seq_num>highest_event) {
  244.     highest_event=seq_num;
  245.       }
  246.  
  247.       /* its ours, is it the one we are already over? */
  248.       p=(pointable)to_obj;
  249.  
  250.       /* is there already a point focus? */
  251.       if (pf!=null) {
  252.  
  253.     /* is it already this object? */
  254.     if (pf==p) {
  255.  
  256.       /* deal with this event */
  257.       mouse_event_same_object(evt);
  258.  
  259.       /* we are done */
  260.       return false;
  261.  
  262.     } else {
  263.  
  264.       /* need to tell them we are not on them anymore */
  265.       if (pf instanceof interactor)
  266.         evt_copy.global_to_local((interactor)pf);
  267.       else
  268.         evt_copy.reset_to_global();
  269.       pf.mouse_exit(evt_copy);
  270.     }
  271.       }
  272.  
  273.       /* reset the focus */
  274.       set_point_focus(p,evt);
  275.  
  276.       /* reschedule the transition for later */
  277.       reschedule_transition();
  278.  
  279.       /* send the enter message */
  280.       if (p instanceof interactor)
  281.         evt_copy.global_to_local((interactor)p);
  282.       else
  283.         evt_copy.reset_to_global();
  284.       p.mouse_enter(evt_copy,user_info);
  285.  
  286.       /* we handled it, so return true */
  287.       return true;
  288.     }
  289.  
  290.     /* if its not pointable we don't care*/
  291.     return false;
  292.   }
  293.  
  294.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  295.  
  296.   /**
  297.    * This method is called by the manager after an event is
  298.    * dispatched. This agent uses this to become informed of
  299.    * events which were handled by other agents so it can 
  300.    * tell clients of its interface that the mouse may have
  301.    * left their area.
  302.  
  303.    * @param event evt the event which was dispatched (or not)
  304.    * @param boolean dispatched true if the event was handled by some agent
  305.    *
  306.    */
  307.   public void after_dispatch_notify(event evt, boolean dispatched) {
  308.     event evt_copy;
  309.  
  310.     /* there are several reasons we might not care about this
  311.      * event: 1) we don't have a point _focus 2) its not an event
  312.      * type we care about 3) its a sequence number we have
  313.      * seen before (thus we've already dealt with it)
  314.      */
  315.     if ((point_focus()==null) ||
  316.     (is_mouse_event(evt)==false) ||
  317.     (highest_event==manager.event_seq_num())) {
  318.       /* we don't care  */
  319.       return;
  320.     }
  321.  
  322.     /* make a copy of the event */
  323.     evt_copy = new event(evt);
  324.  
  325.     /* so this is the interesting case... some event got processed 
  326.      * and we have a point focus ... we need to tell them we
  327.      * are done
  328.      */
  329.     if (point_focus() instanceof interactor)
  330.       evt_copy.global_to_local((interactor)point_focus());
  331.     else
  332.       evt_copy.reset_to_global();
  333.     point_focus().mouse_exit(evt_copy);
  334.  
  335.     /* reset */
  336.     set_point_focus(null,evt);
  337.   }
  338.  
  339.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  340.  
  341.   /**
  342.    * This is a convenience method for checking if an event is
  343.    * any of the mouse events.
  344.    * @param event e the event to be tested
  345.    * @return boolean true if the event is a mouse event
  346.    */
  347.   protected boolean is_mouse_event(event e) {
  348.     return ((e.id()==event.MOUSE_MOVE) ||
  349.         (e.id()==event.MOUSE_UP) ||
  350.         (e.id()==event.MOUSE_DOWN) ||
  351.         (e.id()==event.MOUSE_ENTER) ||
  352.         (e.id()==event.MOUSE_EXIT));
  353.   }
  354.  
  355.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  356.  
  357.   /**
  358.    * This is called to tell us that the timer we previous scheduled
  359.    * has expired.
  360.    * @param event e the event that caused this timer to expire
  361.    *                (currently ignored)
  362.    */
  363.   public void time_expired(event evt /* ignored */) {
  364.     display_help help; /* cause I need somebody...not just anybody */
  365.  
  366.     /* is there a focus now?*/
  367.     if ((point_focus()!=null)  && (point_focus() instanceof display_help)){
  368.  
  369.       /* send the starting message */
  370.       help=(display_help)point_focus();
  371.       help.help_open();
  372.       help_displayed=true;
  373.  
  374.     }
  375.   }
  376.  
  377.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  378.  
  379.   /**
  380.    * This is called to get a new scheduled transition. The user has
  381.    * moved or clicked, so we need to wait a few more seconds.
  382.    */
  383.   protected void reschedule_transition() {
  384.     /* is there one */
  385.     if (trans!=null) {
  386.       manager.animation.remove_transition(trans);
  387.     }
  388.  
  389.     /* make a new transition and schedule it */
  390.     trans=new timer_transition(this,stable_time());
  391.     manager.animation.schedule_transition(trans);
  392.   }
  393.  
  394.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  395.  
  396.   /**
  397.    * This gets called when we get a mouse event, but it is over the
  398.    * same object we were over before.
  399.    * @param event evt the that caused this processing
  400.    */
  401.   public void mouse_event_same_object(event evt) {
  402.     display_help help;
  403.     event        evt_copy;
  404.  
  405.     /* reset the transition */
  406.     reschedule_transition();
  407.  
  408.     /* if there is a help message displayed, put it down */
  409.     if (help_displayed) {
  410.  
  411.       help=(display_help)point_focus();
  412.       evt_copy = new event(evt);
  413.       if (help instanceof interactor)
  414.         evt_copy.global_to_local((interactor)help);
  415.       else
  416.         evt_copy.reset_to_global();
  417.       help.help_close(evt_copy);
  418.       help_displayed=false;
  419.  
  420.     }
  421.   }
  422.  
  423.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  424.  
  425. }
  426.  
  427.  
  428. /*=========================== COPYRIGHT NOTICE ===========================
  429.  
  430. This file is part of the subArctic user interface toolkit.
  431.  
  432. Copyright (c) 1996 Scott Hudson and Ian Smith
  433. All rights reserved.
  434.  
  435. The subArctic system is freely available for most uses under the terms
  436. and conditions described in 
  437.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  438. and appearing in full in the lib/interactor.java source file.
  439.  
  440. The current release and additional information about this software can be 
  441. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  442.  
  443. ========================================================================*/
  444.