home *** CD-ROM | disk | FTP | other *** search
- package sub_arctic.test;
-
- import sub_arctic.lib.*;
- import sub_arctic.input.*;
- import sub_arctic.anim.*;
- import sub_arctic.output.*;
-
- import java.awt.Point;
-
- /**
- * This is the class for building a "window shade" composition object. This
- * object composes two children, one that forms the background (inside the
- * window pane) and one that is on a movable shade that can be pulled up and
- * down by th user. This interaction can replace typical pop-up modal dialogs
- * with an interaction that is richer in metaphor and more familiar to most
- * users.
- *
- * @author Ian Smith
- */
- public class shade extends base_parent_interactor
- implements pressable, animatable {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * String length in pixels
- */
- protected final int string_length=30;
-
- /**
- * Size of the handle in pixels (both width and height)
- */
- protected final int handle_size=10;
-
- /**
- * pane borders in pixels (around the outside of the window)
- */
- protected final int pane_borders=3;
-
- /**
- * This is how long the animation takes, in millseconds
- */
- protected final long anim_length=1500;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is true if an animation is in progress
- */
- protected boolean anim_in_progress=false;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This holds how far "down" the shade is as a percentage. At
- * 100 percent down (1.0), it doesn't cover all the area, there is some
- * area left for the string and chain to hang into.
- */
- protected double _percent_down=0.9;
-
- /**
- * Access to how far "down" the shade is as a percentage. At
- * 100 percent down (1.0), it doesn't cover all the area, there is some
- * area left for the string and chain to hang into.
- */
- public double percent_down() {return _percent_down;}
-
- /**
- * Set how far "down" the shade is as a percentage. At
- * 100 percent down (1.0), it doesn't cover all the area, there is some
- * area left for the string and chain to hang into.
- */
- public void set_percent_down(double v)
- {
- if (_percent_down != v)
- {
- _percent_down = v;
- damage_self();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Simple constructor assuming that position and size will be set with
- * constraints */
- public shade() {
- super(0,0,100,100);
- setup_for_fixed_children(2);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Draw the child and the window dressing
- */
- public void draw_self_local(drawable d) {
- color_scheme cs=style_manager.default_color_scheme();
- int center_x, center_y; // what the user perceives as the center
- int shade_boundary,bottom_boundary;
-
- /* traverse into first child and draw */
- if (child(0) != null) child(0).draw_self(d);
-
- /* now clear the bottom area */
- d.setColor(cs.base());
- d.fillRect(0,h()-(string_length + handle_size), w(),
- string_length + handle_size);
-
- /* draw the panes */
- center_x=w()/2;
- center_y=(h()- (string_length + handle_size)) /2;
-
- /* figure out where shade ends in y */
- shade_boundary=(int)((percent_down() *
- ((double)(h()-(string_length + handle_size)))));
-
- /* draw the string and handle */
- d.setColor(cs.foreground());
- d.drawLine(w()/2,shade_boundary,w()/2,shade_boundary+string_length);
- d.drawArc((w()/2)-(handle_size/2),shade_boundary+string_length,
- handle_size, handle_size, 0, 360);
-
- /* now draw the shade part */
- d.setColor(cs.base());
- d.fillRect(0,0,w(),shade_boundary);
-
- /* now do second child, on the top */
- if (child(1) != null) child(1).draw_self(d);
-
- /* finally do border over the top */
- d.setColor(cs.foreground());
- bottom_boundary=(h()-(string_length+handle_size))-pane_borders;
- d.fillRect(0,0,w(),pane_borders); /* top */
- d.fillRect(0,0,pane_borders,bottom_boundary); /* left */
- d.fillRect(w()-pane_borders,0,pane_borders,bottom_boundary); /* right */
- d.fillRect(0,bottom_boundary,w(),pane_borders); /* bottom */
-
- d.fillRect(0,shade_boundary-(pane_borders-1),w(),pane_borders-1);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Whenever we get a call to configure, be sure to enforce
- * the shade on the second child.
- */
- public void configure() {
- int space, shift;
-
- super.configure();
-
- /* figure out how much space we have */
- space=h()-(string_length+ handle_size);
-
- /* now what number of pixels of shift do we need */
- shift=(int) (((double)space)*percent_down());
-
- /* we want the bottom edge of child 1 to at the bottom of the shade */
- if (child(1) != null)
- {
- /* position the second child on the shade */
- child(1).set_y(shift - child(1).h());
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Handle the picking sequence. We need to determine where
- * the user's input is w.r.t. to us. We only make ourselves
- * the picked object when they click on the handle, but we
- * don't want children getting picked if they click on any
- * of the blank areas or the frame.
- */
- public void pick(int pt_x, int pt_y, pick_collector pick_list) {
- int shade_boundary;
- Point child_point;
-
- /* if they are close to the edges, they are on the frame and we'll
- just ignore those */
- if ((pt_x < pane_borders) || (pt_x > (w()-pane_borders)) ||
- (pt_y < pane_borders) || (pt_y > (h()-pane_borders))) {
- /* nobody can be picked, we just return */
- return;
- }
-
- /* figure out where shade ends in y */
- shade_boundary=(int)((percent_down() *
- ((double)(h()-(string_length + handle_size)))));
-
- /* enforce the picking of us if they are over the handle */
- if ((pt_x>=(w()/2)-(handle_size/2))&& (pt_x<=(w()/2)+(handle_size/2)) &&
- (pt_y>=(shade_boundary+string_length)) &&
- (pt_y<=(shade_boundary+string_length+handle_size))) {
- /* put us in the pick list and bail */
- pick_list.report_pick(this);
- return;
- }
-
- /* ok, now enforce the bottom region ... */
- if (pt_y>= (h()-(string_length+handle_size))) {
- return;
- }
-
- /* enforce the shade region */
- if (pt_y<=shade_boundary) {
- /* create a point in the childs coordinate system */
- child_point= child(1).into_local(new Point(pt_x,pt_y));
-
- /* now let him do the pick */
- child(1).pick(child_point.x, child_point.y, pick_list);
- } else {
- /* ok, they picked an ok area which is not covered by
- * the shade... do the pick within child 0 */
- /* create a point in the childs coordinate system */
- child_point= child(0).into_local(new Point(pt_x,pt_y));
-
- /* now let him do the pick */
- child(0).pick(child_point.x, child_point.y, pick_list);
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /* we don't need to do any processing here */
- public boolean release(event evt, Object user_info) {
- return false;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Handle a call on the pressable interface
- */
- public boolean press(event evt, Object user_info) {
- long now=time_interval.now();
- time_interval ti;
- transition trans;
- shade_trajectory traj;
-
- if (anim_in_progress) {
- return false;
- } else {
- anim_in_progress=true;
- }
-
- /* are at top ? */
- if (percent_down()<=0.1) {
- /* at the top */
- traj=new shade_trajectory(percent_down(),0.9);
- } else {
- /* not at top, go up */
- traj=new shade_trajectory(percent_down(), 0.03);
- }
-
- /* no animation going on now, lets do it */
- ti=new time_interval(now,now+anim_length);
-
- /* make the transition */
- trans=new transition(this,ti,traj);
-
- /* schedule it */
- manager.animation.schedule_transition(trans);
-
- return true;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * start the animation
- */
- public void start_transition(transition trans, trajectory traj,
- double start_t, Object start_obj, event e,
- Object user_info) {
- /* nothing to do here */
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * we just look at the end_obj (which is a Float) and
- * send that to the set_shade code
- */
- public void transition_step(transition trans, trajectory traj,
- double start_t, Object start_obj,
- double end_t, Object end_obj,
- event e, Object user_info) {
- Float f=(Float) end_obj;
- set_percent_down(f.doubleValue());
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Again, we just look at the end_obj (which is a Float) and
- * set the shade to be the right position
- */
- public void end_transition(transition trans, trajectory traj,
- double start_t, Object start_obj,
- double end_t, Object end_obj,
- event e, Object user_info) {
- Float f=(Float) end_obj;
- set_percent_down(f.doubleValue());
- anim_in_progress=false;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- }
-
- /*---------------------------------------------------------------------*/
-
-
- /**
- * This is a simple little trajectory to make the shade move
- */
- class shade_trajectory implements trajectory {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is the percentage of time spent going down
- * on raises of the blind.
- */
- protected static final double down_percent_of_time=0.2;
-
- /**
- * This is the extra distance down we travel before going up
- */
- protected static double down_shift=0.1;
-
- /**
- * Start and stop positions.
- */
- protected double start;
- protected double stop;
-
- /*
- * Pacing function
- */
- protected pacer pace;
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /*
- * Initialize with a start and a stop postion
- */
- public shade_trajectory(double start_pos, double stop_pos) {
- start=start_pos;
- stop=stop_pos;
- if (start>stop) {
- /* going up */
- pace=new slow_in_slow_out(down_percent_of_time,2*down_percent_of_time);
- } else {
- /* down */
- pace=new linear_pacer();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /* convert a time interval into a number from 0.0 to 1.0... so
- * just subtract from one
- */
- public Object object_for_parm(double t) {
- double delta,extra,real_start, scale;
-
- if (start>stop) {
- /* we are going up */
- if (t<down_percent_of_time) {
- /* extra down part */
- extra=start*down_shift;
- /* scale the extra part into that time% */
- extra*=(t/down_percent_of_time);
- return (new Float(start+extra));
- } else {
- /* lets compute the extra amount down we are */
- extra=start*down_shift;
- /* now we can get the real starting position */
- real_start=start+ extra;
- /* from this (large value) we can subtract the ending value */
- delta=real_start-stop;
- /* now delta has the distance to travel, scale to fit in teh
- * last bit of the interval */
- scale= (t-down_percent_of_time)/(1.0-down_percent_of_time);
- /* now figure out how far along we are */
- delta*=scale;
- /* ok, now compute the final value */
- return (new Float( (real_start-delta)));
- }
- } else {
- /* we are going down */
- delta=stop-start;
- return (new Float((delta*t)+start));
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * For now, just use a linear pacing
- */
- public pacer pacing_function() {
- return pace;
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- }
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-