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

  1. package sub_arctic.lib;
  2.  
  3. import sub_arctic.input.*;
  4. import sub_arctic.output.*;
  5. import sub_arctic.lib.sub_arctic_error;
  6. import sub_arctic.constraints.std_function;
  7. import sub_arctic.constraints.constraint;
  8.  
  9. /**
  10.  *
  11.  * @author Ian Smith
  12.  */
  13. public class hierarchy_parent 
  14. extends base_parent_interactor implements clickable {
  15.  
  16.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  17.  
  18.   /**
  19.    * Keep track if we are open. 
  20.    */
  21.   protected boolean _is_open;
  22.   public boolean is_open() { return _is_open;};
  23.   public void set_is_open(boolean i) {
  24.     loaded_image img;
  25.     icon the_icon;
  26.  
  27.     _is_open=i;
  28.     /* If we have a special child, set his icon partner to be right */
  29.     if (special_child()!=null) {
  30.       /* which icon to use? */
  31.       if (is_open()) {
  32.     img=std.hm_down_arrow();
  33.       } else {
  34.     img=std.hm_right_arrow();
  35.       }
  36.       /* get the icon from the right spot */
  37.       the_icon=(icon)child(0).child(0);
  38.       /* reset the image */
  39.       the_icon.set_image(img);
  40.     }
  41.     set_child_constraints();
  42.   }
  43.  
  44.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  45.  
  46.   /**
  47.    * We need to know if we are handling the first child management.
  48.    */
  49.   protected interactor _special_child;
  50.  
  51.   /**
  52.    * This returns null if we aren't handling anything special for them. 
  53.    */
  54.   public interactor special_child() { return _special_child;};
  55.  
  56.   /**
  57.    * If you call this method the interactor you pass becomes the 
  58.    * first child. Note that you'll need to compensate for the
  59.    * width of the triangle if you care about all objects being 
  60.    * equal width. 
  61.    */
  62.   public void set_special_child(interactor b) { 
  63.     base_parent_interactor base;
  64.     icon i;
  65.  
  66.     _special_child=b;
  67.     /* are they setting it to null ?*/
  68.     if (b==null) return;
  69.       
  70.       /* build a subtree that includes the icon and their interactor */
  71.     base=new shrink_wrap_container(0,0,0,false);
  72.  
  73.     /* are we open or closed ?*/
  74.     if (is_open()) {
  75.       i=new icon(0,0,std.hm_down_arrow());
  76.     } else {
  77.       /*closed */
  78.       i=new icon(0,0,std.hm_right_arrow());
  79.     }
  80.     /* stick in icon */
  81.     base.add_child(i);
  82.     /* put in their interactor */
  83.     base.add_child(b);
  84.     /* add these two to our interactor */
  85.     if (num_children()==0) {
  86.       add_child(base);
  87.     }
  88.     else {
  89.       set_child(0,base);
  90.     }
  91.     /* setup the child constraints */
  92.     set_child_constraints();
  93.   }
  94.  
  95.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  96.  
  97.   /** Border around our edges.  */
  98.   int _border;
  99.  
  100.   /** 
  101.    * Border around our edges.  
  102.    * @return int the border size.
  103.    */
  104.   int border() { return _border;};
  105.  
  106.   /** 
  107.    * Set the border around our edges. 
  108.    * @param int b the new border size.
  109.    */
  110.   void set_border(int b) {
  111.     _border=b;
  112.     set_child_constraints();
  113.   }
  114.  
  115.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  116.  
  117.   /** Space between children.  */
  118.   int _interchild_space;
  119.  
  120.   /** 
  121.    * Space between our children 
  122.    *
  123.    * @return int the amount of vertical spacing maintained between our children.
  124.    */
  125.   int interchild_space() { return _interchild_space;};
  126.  
  127.   /**
  128.    * Set the amount of space maintained between children 
  129.    */
  130.   void set_interchild_space(int b) 
  131.     {
  132.       _interchild_space=b;
  133.       set_child_constraints();
  134.     };
  135.  
  136.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  137.  
  138.   /**
  139.    * This builds the constraints for the children.   This is at init time 
  140.    * and again if any of the spacing parameters changes.
  141.    */
  142.   protected void set_child_constraints() {
  143.     int i, max = num_children();
  144.     interactor current_child,icon, tmp;
  145.     constraint strut_between_children, xposition = null;
  146.     
  147.     /* loop over all children */ 
  148.     for (i=0; i<max; ++i) {
  149.  
  150.       /* set the current child */
  151.       current_child = child(i);
  152.  
  153.       /* drop the current constraints, if any */
  154.       current_child.set_x_constraint(NO_CONSTRAINT);
  155.       current_child.set_y_constraint(NO_CONSTRAINT);
  156.  
  157.       /* is it the first child? */
  158.       if (i != 0) {
  159.     /* this is the strut which keeps the y position of a child 
  160.      * below the previous child and possibly shifts it over */
  161.     strut_between_children = std_function.offset(PREV_SIBLING.Y2(), 
  162.                           interchild_space());
  163.     current_child.set_y_constraint(strut_between_children);
  164.  
  165.     /* if its not the first child , space it over */
  166.     current_child.set_x_constraint(std_function.offset(PARENT.X(), 
  167.                             border()+ indent_spacing()));
  168.       } else {
  169.     /* note that the constraints are different if we are open 
  170.      * or closed. This lets us enforce the border only when
  171.      * we are open. 
  172.      */
  173.     if (is_open()) {
  174.       /* i is zero, setup the top constraint */
  175.       strut_between_children = std_function.offset(PARENT.Y(), border());
  176.       current_child.set_y_constraint(strut_between_children);
  177.  
  178.       /* first child is not indented */
  179.       current_child.set_x_constraint(std_function.offset(PARENT.X(),
  180.                               border()));
  181.     } else { /* this is the closed case */
  182.       /* just put it at 0,0 so we don't do anything to it */
  183.       current_child.set_x(0);
  184.       current_child.set_y(0);
  185.     }
  186.       }
  187.     }
  188.  
  189.     /* do we have a special child #0? */
  190.     if (special_child()!=null) {
  191.       /* extract children */
  192.       icon=child(0).child(0);
  193.       tmp=child(0).child(1);
  194.  
  195.       /* set up the constraints for layout in x*/
  196.       icon.set_x_constraint(std_function.offset(PARENT.X(),0));
  197.       tmp.set_x_constraint(std_function.offset(PREV_SIBLING.X2(), 0));
  198.  
  199.       /* center them next to each other in y*/
  200.       if (icon.h()>tmp.h()) {
  201.     icon.set_y(0);
  202.     tmp.set_y((icon.h()-tmp.h())/2);
  203.       } else {
  204.     icon.set_y((tmp.h()-icon.h())/2);
  205.     tmp.set_y(0);
  206.       }
  207.     }
  208.  
  209.     /* do our constraints and size computation */
  210.     set_local_constraints();
  211.     damage_self();
  212.  
  213.   }
  214.  
  215.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  216.  
  217.   /**
  218.    * Set up our own constraints.  This is done at init time and again if
  219.    * we every redo the child constraints.
  220.    */
  221.   void set_local_constraints() {
  222.     /* are there children? */
  223.     if (num_children()==0) {
  224.       /* drop constraints */
  225.       set_h_constraint(NO_CONSTRAINT);
  226.       set_w_constraint(NO_CONSTRAINT);
  227.  
  228.       /* set w/h manually to be twice the border */
  229.       set_h(2*border());
  230.       set_w(2*border());
  231.       return;
  232.     }
  233.  
  234.     /* we have children... are we open */
  235.     if (is_open()) {
  236.       /* just do the max of our children */
  237.       set_h_constraint(std_function.offset(MAX_CHILD.Y2(), border()));
  238.  
  239.       /* just do the max of our children */
  240.       set_w_constraint(std_function.offset(MAX_CHILD.X2(), border()));
  241.  
  242.     } else {
  243.       /* set the no constraint */
  244.       set_w_constraint(NO_CONSTRAINT);
  245.       set_h_constraint(NO_CONSTRAINT);
  246.       /* note: we don't want the border if we are closed because
  247.        * we want to show no difference from child(0).
  248.      */
  249.       set_h(child(0).h());
  250.       set_w(child(0).w());
  251.     }
  252.   }
  253.  
  254.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  255.  
  256.   /**
  257.    * Override the way child drawing is done.
  258.    * @param drawable d the drawing surface we produce our result on.
  259.    */
  260.   protected void draw_children(drawable d) 
  261. {
  262.     /* if we are in the normal state, just draw them */
  263.     if (is_open()) {
  264.       super.draw_children(d);
  265.     } else {
  266.       /* we are closed, just draw first child */
  267.       child(0).draw_self(d);
  268.     }
  269.   }
  270.  
  271.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  272.  
  273.   /** This holds the amount that children in the hierarchy are indented.  */
  274.   protected int _indent_spacing;
  275.  
  276.   /**
  277.    * The amount that children in the hierarchy are indented.
  278.    * @return int indentation amount.
  279.    */
  280.   public int indent_spacing() { return _indent_spacing;};
  281.  
  282.   /**
  283.    * Set the amount that children in the hierarchy are indented.
  284.    * @param int s new indentation amount.
  285.    */
  286.   public void set_indent_spacing(int s) { 
  287.     _indent_spacing=s;
  288.     set_child_constraints();
  289.     damage_self();
  290.   }
  291.  
  292.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  293.  
  294.   /**
  295.    * Build a hierarchy object, which is a special type of parent.
  296.    * The first object is always displayed, children 1 through n-1 are displayed
  297.    * only if the manager is open. It defaults to being closed.
  298.    * This object steals the press event from its first child.
  299.    * 
  300.    * @param int xv                     the x position of the interactor.
  301.    * @param int yv                     the y position of the interactor.
  302.    * @param int the_border             the size of the border around our 
  303.    *                                   children.
  304.    * @param int the_interchild_spacing vertical space between children.
  305.    * @param int the_indent_spacing     amount to indent children.
  306.    */
  307.   public hierarchy_parent(int xv, int yv, int the_border, 
  308.                int the_interchild_spacing,
  309.                int the_indent_spacing) 
  310. {
  311.  
  312.     /* constraints take care of w,h */
  313.     super(xv,yv);
  314.  
  315.     _indent_spacing=the_indent_spacing;
  316.     _interchild_space=the_interchild_spacing;
  317.     _border=the_border;
  318.     _special_child=null;
  319.     set_is_open(false);
  320.   }
  321.  
  322.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  323.  
  324.   /**
  325.    * This builds a default hierarchy manager with no border, interchild
  326.    * spacing of 2, and indent spacing of 15. It also defaults to being
  327.    * closed.
  328.    * 
  329.    * @param int xv the x position of the interactor.
  330.    * @param int yv the y position of the interactor.
  331.    */
  332.   public hierarchy_parent(int xv, int yv) 
  333. {
  334.     super(xv,yv);
  335.     _indent_spacing=15;
  336.     _interchild_space=2;
  337.     _special_child=null;
  338.     _border=0;
  339.     set_is_open(false);
  340.   }
  341.  
  342.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  343.  
  344.   /**
  345.    * This builds a default hierarchy manager with default position of 0,0,
  346.    * no border, interchild spacing of 2, and indent spacing of 15. It also 
  347.    * defaults to being closed.
  348.    */
  349.   public hierarchy_parent() 
  350. {
  351.     super(0,0);
  352.     _indent_spacing=15;
  353.     _interchild_space=2;
  354.     _special_child=null;
  355.     _border=0;
  356.     set_is_open(false);
  357.   }
  358.  
  359.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  360.  
  361.   /**
  362.    * This causes the hierarchy to "open up".
  363.    */
  364.   public void open() 
  365. {
  366.     interactor chld;
  367.     
  368.     /* don't bother if open */
  369.     if (is_open()) return;
  370.     set_is_open(true);
  371.   }
  372.  
  373.    //had:
  374.    //* @exception general
  375.  
  376.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  377.  
  378.   /**
  379.    * This causes the hierarchy to "close up".
  380.    */
  381.   public void close() 
  382. {
  383.     interactor chld;
  384.  
  385.     /* don't bother if already closed */
  386.     if (!is_open()) return;
  387.     set_is_open(false);
  388.   }
  389.  
  390.    //had:
  391.    //* @exception general
  392.  
  393.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  394.  
  395.   /**
  396.    * This is the input stealer for the first object.  We use clicks over the
  397.    * first child to trigger opening and closing, so we test here whether the 
  398.    * first child was picked, and if so we claim to be picked also.  
  399.    * 
  400.    * @param int pt_x the x coordinate of the query point.
  401.    * @param int pt_y the y coordinate of the query point.
  402.    */
  403.   public void pick(int pt_x, int pt_y, pick_collector pick_list) 
  404. {
  405.     int i;
  406.     user_info_holder h;
  407.  
  408.     pick_within_children(pt_x,pt_y,pick_list);
  409.  
  410.     /* loop over everyone picked */
  411.     for (i=0; i<pick_list.num_picks(); ++i) {
  412.       h=pick_list.pick(i);
  413.  
  414.       /* if child #0 is in the list, we are picked also */
  415.       if (find_child(h.obj)==0) {
  416.     pick_list.report_pick(this);
  417.       }
  418.     }
  419.   }
  420.  
  421.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  422.  
  423.   /**
  424.    * Handle click input.  We get this when a click occurs over our first child
  425.    * (and the child does not itself consume the click).
  426.    *
  427.    * @param event  evt the release event.
  428.    * @param Object ui  user_info passed to the pick (ignored).
  429.    */
  430.   public boolean click(event evt, Object ui) {
  431.     /* reverse the state */
  432.     if (is_open()) {
  433.       close();
  434.     }
  435.     else {
  436.       open();
  437.     }
  438.     return true;
  439.   }
  440.  
  441.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  442.  
  443.   /* these are copied right out the column code */
  444.   /* note: it appears to me that the column (and the hierarchy
  445.      manager) should not be converted to incremental addition
  446.      of constraints as this makes them MUCH harder to subclass */
  447.  
  448.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  449.  
  450.   /** 
  451.    * Override to also add constraints.
  452.    * @param interactor chld the child object being added.
  453.    */
  454.   public void add_child(interactor chld) 
  455. {
  456.       super.add_child(chld);
  457.       set_child_constraints();
  458.     }
  459.  
  460.    //had:
  461.    //* @exception op_not_supported if this object does not support children  or
  462.    //*                             has fixed children (shouldn't happen).
  463.    //* @exception general
  464.  
  465.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  466.  
  467.   /** 
  468.    * Override to also add constraints.
  469.    * @param int        at_indx index where the child goes.
  470.    * @param interactor chld    the child object to insert at that index
  471.    */
  472.   public void insert_child(int at_indx, interactor chld) 
  473. {
  474.       super.insert_child(at_indx,chld);
  475.       set_child_constraints();
  476.     }
  477.  
  478.    //had:
  479.    //* @exception op_not_supported if this object does not support children  or
  480.    //*                             has fixed children (shouldn't happen).
  481.    //* @exception general
  482.  
  483.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  484.  
  485.   /** 
  486.    * Override to also add constraints 
  487.    * @param int at_indx index of child to be removed.
  488.    */
  489.   public interactor remove_child(int at_indx) 
  490. {
  491.       interactor i;
  492.  
  493.       i=super.remove_child(at_indx);
  494.       set_child_constraints();
  495.       return i;
  496.     }
  497.  
  498.    //had:
  499.    //* @exception op_not_supported if this object does not support children
  500.    //*                             (shouldn't happen).
  501.    //* @exception general
  502.  
  503.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  504.  
  505.   /** 
  506.    * Override to also add constraints.
  507.    * @param interactor the_child the child to remove.
  508.    */
  509.   public void remove_child(interactor the_child) 
  510. {
  511.       super.remove_child(the_child);
  512.       set_child_constraints();
  513.     }
  514.  
  515.    //had:
  516.    //* @exception op_not_supported if this object does not support children
  517.    //*                             (shouldn't happen).
  518.    //* @exception general
  519.  
  520.   /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
  521. }
  522. /*=========================== COPYRIGHT NOTICE ===========================
  523.  
  524. This file is part of the subArctic user interface toolkit.
  525.  
  526. Copyright (c) 1996 Scott Hudson and Ian Smith
  527. All rights reserved.
  528.  
  529. The subArctic system is freely available for most uses under the terms
  530. and conditions described in 
  531.   http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html 
  532. and appearing in full in the lib/interactor.java source file.
  533.  
  534. The current release and additional information about this software can be 
  535. found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
  536.  
  537. ========================================================================*/
  538.