1   package fi.jyu.mit.graphics;
2   import java.awt.event.MouseAdapter;
3   import java.awt.event.MouseEvent;
4   
5   
6   /**
7    * Luokka jolla voidaan siirtää kuvia hiiren klikkauksen kohdalle.
8    * TODO: ei (ehkä) toimi jos paneelia on skaalattu.  Tarvitsee toteuttaa
9    * ensin käänteiskuvaus.  Samoin ei toimi jos peruspolkua on muutettu. 
10   * @author Vesa Lappalainen
11   * @version 20.8.2008
12   * @version 8.3.2012
13   */
14  public class MouseFollower extends MouseAdapter {
15      public interface MouseMoveFollower {
16          public void mouseMoved(RPoint rp);
17      }
18      
19      private Transformable object;
20      private MouseMoveFollower follower = null;
21      private SpacePanel panel;
22      private boolean currentDrag = false;
23      private boolean currentMove = false;
24      private boolean currentPressed = true;
25      
26      /**
27       * Alustetaan hiiren seuraaja.
28       * @param panel    paneli jossa tapahtumia muutoksia seurataan
29       * @param object   olio jota siirretään hiiren mukaan.
30       * @param x olion koordinaatti johon keskitetään 
31       * @param y olion koordinaatti johon keskitetään
32       * @param z olion koordinaatti johon keskitetään
33       * @param drag liikutetaan
34       */
35      @SuppressWarnings("unused")
36      public MouseFollower(SpacePanel panel, Transformable object, double x,double y, double z,boolean drag) { // NOPMD
37          this.object = object;
38          this.panel = panel;
39          panel.addMouseListener(this);
40          startFollow(drag); 
41      }
42      
43      /**
44       * Alustetaan hiiren seuraaja.
45       * @param panel    paneli jossa tapahtumia muutoksia seurataan
46       * @param follower käsittelijä jota kutsutaan kun hiiri liikahtaa
47       * @param drag jos true, kutsutaan hiiri pohjassa liikuttelusta, muuten vain klikkauksesta
48       */
49      public MouseFollower(SpacePanel panel, MouseMoveFollower follower,boolean drag) {
50          this.follower = follower;
51          this.panel = panel;
52          startFollow(drag); 
53      }
54      
55      /**
56       * Alustetaan hiiren seuraaja siten, että z-koordinaatin arvo on nolla ja liikutetaan on tosi
57       * @param panel paneeli jossa tapahtumia muutoksia seurataan
58       * @param object olio jota siirretään hiiren mukaan.
59       * @param x olion koordinaatti johon keskitetään 
60       * @param y olion koordinaatti johon keskitetään
61       */
62      public MouseFollower(SpacePanel panel, Transformable object, double x,double y) {
63          this(panel,object,x,y,0,true);
64      }
65      
66      
67      /**
68       * Alustetaan hiiren seuraaja siten, että z-koordinaatin arvo on nolla ja liikutetaan on tosi
69       * @param panel paneeli jossa tapahtumia muutoksia seurataan
70       * @param object olio jota siirretään hiiren mukaan.
71       * @param drag jos true, kutsutaan hiiri pohjassa liikuttelusta, muuten vain klikkauksesta
72       */
73      public MouseFollower(SpacePanel panel, Transformable object, boolean drag) {
74          this(panel,object,0,0,0,drag);
75      }
76      
77      
78      /**
79       * Alustetaan hiiren seuraaja siten, että z-koordinaatin arvo on nolla ja liikutetaan on tosi
80       * @param panel paneeli jossa tapahtumia muutoksia seurataan
81       * @param object olio jota siirretään hiiren mukaan.
82       */
83      public MouseFollower(SpacePanel panel, Transformable object) {
84          this(panel,object,0,0,0,false);
85      }
86      
87      
88      /**
89       * Lopetetaan hiiren seuraaminen
90       */
91      public void stopFollow() {
92          panel.removeMouseListener(this);
93          panel.removeMouseMotionListener(this);
94      }
95      
96      
97      /**
98       * Aloitetaan hiiren seuraaminen
99       * @param drag jos true, kutsutaan hiiri pohjassa liikuttelusta, muuten vain klikkauksesta
100      */
101     public void startFollow(boolean drag) {
102         stopFollow();
103         panel.addMouseListener(this);
104         panel.addMouseMotionListener(this);
105         currentDrag = drag;
106     }
107     
108     
109     /**
110      * Aloitetaan hiiren seuraaminen
111      */
112     public void startFollow() {
113         startFollow(currentDrag);
114     }
115     
116     
117     /**
118      * Palautetaan panelin ruutpistettä vastaava reaalimaailman piste tasosta z=0
119      * @param panel mhinkä paneelin piste
120      * @param x panelin ruutupisteen x-koordinaatti
121      * @param y panelin ruutupisteen x-koordinaatti
122      * @param sp piste johon palautetaan klikatuin pisteen laitekoordinaatit
123      * @return reaalimaailman piste 
124      */
125     public static RPoint getRPoint(SpacePanel panel, double x, double y, RPoint sp) {
126         RPoint rp = new RPoint(); 
127         panel.getFullTransform().getInversion().transform(x,y,0,sp,rp); 
128         return rp;
129     }
130 
131     
132     /**
133      * Palautetaan panelin ruutpistettä vastaava reaalimaailman piste tasosta z=0
134      * @param panel mhinkä paneelin piste
135      * @param x panelin ruutupisteen x-koordinaatti
136      * @param y panelin ruutupisteen x-koordinaatti
137      * @return reaalimaailman piste 
138      */
139     public static RPoint getRPoint(SpacePanel panel, double x, double y) {
140         return getRPoint(panel, x, y, new RPoint());
141     }
142 
143     
144     /**
145      * Palautetaan mouse eventtiä vastaava reaalimaailman piste tasosta z=0
146      * @param panel mhinkä paneelin piste
147      * @param e hiiren tapahtuman tiedot
148      * @param sp piste johon palautetaan klikatuin pisteen laitekoordinaatit
149      * @return reaalimaailman piste 
150      */
151     public static RPoint getRPoint(SpacePanel panel, MouseEvent e, RPoint sp) {
152         return getRPoint(panel,e.getX(),e.getY(),sp);
153     }
154     
155     /**
156      * Palautetaan mouse eventtiä vastaava reaalimaailman piste tasosta z=0
157      * @param panel mhinkä paneelin piste
158      * @param e hiiren tapahtuman tiedot
159      * @return reaalimaailman piste 
160      */
161     public static RPoint getRPoint(SpacePanel panel, MouseEvent e) {
162         return getRPoint(panel, e,new RPoint());
163     }
164 
165     
166     /**
167      * This is only for inner purposes
168      * @param e MouseEvent
169      */
170     private void doMove(MouseEvent e) {
171         // if ( ! (e.getComponent() instanceof  SpacePanel) ) return;
172         SpacePanel panel = (SpacePanel)e.getComponent();
173         RPoint sp = new RPoint(); 
174         if ( object != null ) {
175             BasicShape comp = (BasicShape)object; 
176             SPoint op = comp.getPoint(panel.getFullTransform(), 0, 0, 0);
177             RPoint rp = getRPoint(panel,e.getX()-op.getX(),e.getY()-op.getY(),sp); 
178             RPoint rp0 = getRPoint(panel,0,0,sp); 
179             //comp.setTransform(new TranslateMatrix(sp.getX()-op.getX(),sp.getY()-op.getY(),0).multiply(comp.getTransform(null)));
180             comp.setTransform(new TranslateMatrix(rp.getX()-rp0.getX(),rp.getY()-rp0.getY(),0).multiply(comp.getTransform(null)));
181         }
182         if ( follower != null ) {
183            RPoint rp = getRPoint(panel,e,sp); 
184            follower.mouseMoved(rp);  
185         }
186     }
187     
188     
189     /**
190      * Hiiren painalluksen tapahtumankäsittelijä
191      * @param e käsiteltävä hiiritapahtuma
192      */
193     @Override
194     public void mousePressed(MouseEvent e) {
195         if ( currentPressed )
196            doMove(e);
197     }
198     
199     
200     /**
201      * Hiiren raahauksen tapahtumankäsittelijä
202      * @param e käsiteltävä hiiritapahtuma
203      */
204     @Override
205     public void mouseDragged(MouseEvent e) {
206         if ( currentDrag )
207            doMove(e);
208     }
209 
210     
211     /**
212      * Tyhjä toteutus metodille. MouseAdapter Java 6:ssa sisältää tyhjät
213      * toteutukset MouseMotionListener-rajapinnan metodeille. Javan versiot
214      * 1.5:stä aiempiin eivät näitä sisällä.
215      * 
216      * @param e ei käytetä.
217      * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
218      */
219     @Override
220     public void mouseMoved(MouseEvent e) {
221         if ( currentMove )
222             doMove(e);
223     }
224 
225     
226     /**
227      * @return seurataanko liikuttelua
228      */
229     public boolean isMove() {
230         return currentMove;
231     }
232 
233 
234     /**
235      * Asetetaan seuraamaan liikuttelua
236      * @param move päälle vaiko pois
237      */
238     public void setMove(boolean move) {
239         this.currentMove = move;
240     }
241 
242     
243     /**
244      * @return Seurataanko clikkausta
245      */
246     public boolean isPressed() {
247         return currentPressed;
248     }
249 
250     
251     /**
252      * Asetetaan seuraamaan klikkausta
253      * @param pressed päälle vaiko pois
254      */
255     public void setPressed(boolean pressed) {
256         this.currentPressed = pressed;
257     }
258 
259     
260     /**
261      * @return seurataanko raahaamista
262      */
263     public boolean isDrag() {
264         return currentDrag;
265     }
266 
267     
268     /**
269      * Asetetaan seuraamaan raahaamista 
270      * @param drag
271      */
272     public void setDrag(boolean drag) {
273         this.currentDrag = drag;
274     }
275 }
276