1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.6. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2008 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.viewmode;
15  
16  import demo.view.DemoBase;
17  import y.view.AbstractMouseInputEditor;
18  import y.view.Drawable;
19  import y.view.EditMode;
20  import y.view.Graph2DView;
21  import y.view.HitInfo;
22  import y.view.Mouse2DEvent;
23  import y.view.MouseInputEditor;
24  import y.view.MouseInputEditorProvider;
25  
26  import javax.swing.Timer;
27  import java.awt.Color;
28  import java.awt.Graphics2D;
29  import java.awt.Rectangle;
30  import java.awt.Shape;
31  import java.awt.event.ActionEvent;
32  import java.awt.event.ActionListener;
33  import java.awt.geom.AffineTransform;
34  import java.awt.geom.GeneralPath;
35  import java.awt.geom.Point2D;
36  
37  /**
38   * This class demonstrates how to add a custom drawable to the view that interacts
39   * with {@link y.view.EditMode}'s {@link y.view.MouseInputMode}.
40   */
41  public class MouseInputDemo extends DemoBase {
42  
43    public MouseInputDemo() {
44      {
45        AffineTransform transform = AffineTransform.getTranslateInstance( 45, 45 );
46        transform.translate( 0, -40 );
47        new ArrowButton( view,
48                         ArrowButton.ARROW.createTransformedShape( transform ),
49                         new ScrollActionListener( 0, -10 ) );
50      }
51      {
52        AffineTransform transform = AffineTransform.getTranslateInstance( 45, 45 );
53        transform.rotate( Math.toRadians( -90 ) );
54        transform.translate( 0, -40 );
55        new ArrowButton( view,
56                         ArrowButton.ARROW.createTransformedShape( transform ),
57                         new ScrollActionListener( -10, 0 ) );
58      }
59      {
60        AffineTransform transform = AffineTransform.getTranslateInstance( 45, 45 );
61        transform.rotate( Math.toRadians( -180 ) );
62        transform.translate( 0, -40 );
63        new ArrowButton( view,
64                         ArrowButton.ARROW.createTransformedShape( transform ),
65                         new ScrollActionListener( 0, 10 ) );
66      }
67      {
68        AffineTransform transform = AffineTransform.getTranslateInstance( 45, 45 );
69        transform.rotate( Math.toRadians( 90 ) );
70        transform.translate( 0, -40 );
71        new ArrowButton( view,
72                         ArrowButton.ARROW.createTransformedShape( transform ),
73                         new ScrollActionListener( 10, 0 ) );
74      }
75  
76      loadGraph( "resource/5.gml" );
77    }
78  
79    protected void registerViewModes() {
80      EditMode editMode = new EditMode();
81      editMode.getMouseInputMode().setDrawableSearchingEnabled( true );
82      editMode.allowMouseInput( true );
83      view.addViewMode( editMode );
84    }
85  
86    static final class ArrowButton implements Drawable, MouseInputEditorProvider {
87      private final Graph2DView view;
88      private final Shape arrow;
89      private final ActionListener action;
90      private boolean highlight;
91  
92      public static final GeneralPath ARROW;
93  
94      static {
95        GeneralPath path;
96        path = new GeneralPath( GeneralPath.WIND_EVEN_ODD, 8 );
97        path.moveTo( 0, 0 );
98        path.lineTo( 15, 15 );
99        path.lineTo( 5, 15 );
100       path.lineTo( 5, 25 );
101       path.lineTo( -5, 25 );
102       path.lineTo( -5, 15 );
103       path.lineTo( -15, 15 );
104       path.closePath();
105       ARROW = path;
106     }
107 
108 
109     public ArrowButton( Graph2DView view, Shape arrow, ActionListener action ) {
110       this.view = view;
111       this.arrow = arrow;
112       this.action = action;
113       view.addDrawable( this );
114     }
115 
116     public void paint( Graphics2D g ) {
117       double x = view.toWorldCoordX( 0 );
118       double y = view.toWorldCoordY( 0 );
119       g = ( Graphics2D ) g.create();
120       g.translate( x, y );
121       double z2 = 1 / view.getZoom();
122       g.scale( z2, z2 );
123       g.setColor( new Color( 0, 0, 0, 64 ) );
124       g.translate( 4, 4 );
125       g.fill( arrow );
126       g.translate( -4, -4 );
127       g.setColor( highlight ? Color.yellow : Color.red );
128       g.fill( arrow );
129       g.setColor( Color.black );
130       g.draw( arrow );
131       g.dispose();
132     }
133 
134     public Rectangle getBounds() {
135       Rectangle bounds = arrow.getBounds();
136       double x = view.toWorldCoordX( ( int ) bounds.getCenterX() );
137       double y = view.toWorldCoordY( ( int ) bounds.getCenterY() );
138       double w2 = ( int ) ( 0.5d * bounds.getWidth() / view.getZoom() );
139       double h2 = ( int ) ( 0.5d * bounds.getHeight() / view.getZoom() );
140       return new Rectangle( ( int ) ( x - w2 ), ( int ) ( y - h2 ), ( int ) ( 2 * w2 ), ( int ) ( 2 * h2 ) );
141     }
142 
143     public MouseInputEditor findMouseInputEditor( double x, double y ) {
144       int vx = view.toViewCoordX( x );
145       int vy = view.toViewCoordY( y );
146       if ( arrow.contains( vx, vy ) ) {
147         return new AbstractMouseInputEditor() {
148           Timer timer;
149 
150           {
151             timer = new Timer( 30, action );
152             timer.setRepeats( true );
153             timer.setInitialDelay( 200 );
154           }
155 
156           public boolean startsEditing( Mouse2DEvent event ) {
157             int vx = view.toViewCoordX( event.getX() );
158             int vy = view.toViewCoordY( event.getY() );
159             return arrow.contains( vx, vy );
160           }
161 
162           public void mouse2DEventHappened( Mouse2DEvent event ) {
163             int vx = view.toViewCoordX( event.getX() );
164             int vy = view.toViewCoordY( event.getY() );
165             boolean contains = arrow.contains( vx, vy );
166             switch ( event.getId() ) {
167               case Mouse2DEvent.MOUSE_DRAGGED:
168                 break;
169               case Mouse2DEvent.MOUSE_PRESSED:
170                 timer.start();
171                 break;
172               case Mouse2DEvent.MOUSE_CLICKED:
173                 action.actionPerformed( new ActionEvent( ArrowButton.this, ActionEvent.ACTION_PERFORMED, null ) );
174                 view.updateView();
175                 // fall through
176               case Mouse2DEvent.MOUSE_RELEASED:
177                 timer.stop();
178                 // fall through
179               case Mouse2DEvent.MOUSE_MOVED:
180                 if ( highlight != contains ) {
181                   highlight = contains;
182                   view.updateView();
183                 }
184                 if ( !contains ) {
185                   stopEditing();
186                 }
187             }
188           }
189         };
190       } else {
191         return null;
192       }
193     }
194 
195     public MouseInputEditor findMouseInputEditor( Graph2DView view, double x, double y, HitInfo hitInfo ) {
196       return findMouseInputEditor( x, y );
197     }
198   }
199 
200   private class ScrollActionListener implements ActionListener {
201     private final double dx;
202     private final double dy;
203 
204     public ScrollActionListener( double dx, double dy ) {
205       this.dx = dx;
206       this.dy = dy;
207     }
208 
209     public void actionPerformed( ActionEvent e ) {
210       Point2D viewPoint2D = view.getViewPoint2D();
211       view.setViewPoint2D( viewPoint2D.getX() + dx, viewPoint2D.getY() + dy );
212       view.updateView();
213     }
214   }
215 
216   public static void main( String[] args ) {
217     initLnF();
218     new MouseInputDemo().start( "MouseInputDemo" );
219   }
220 }
221