KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > gui > graph > control > SelectTool


1 /***
2  * FractalGUI: a graphical tool to edit Fractal component configurations.
3  * Copyright (C) 2003 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: fractal@objectweb.org
20  *
21  * Authors: Eric Bruneton, Patrice Fauvel
22  */

23
24 package org.objectweb.fractal.gui.graph.control;
25
26 import org.objectweb.fractal.api.control.BindingController;
27
28 import org.objectweb.fractal.gui.graph.model.GraphModel;
29 import org.objectweb.fractal.gui.graph.model.Rect;
30 import org.objectweb.fractal.gui.graph.model.Tools;
31 import org.objectweb.fractal.gui.graph.view.ComponentPart;
32 import org.objectweb.fractal.gui.model.ClientInterface;
33 import org.objectweb.fractal.gui.model.Component;
34 import org.objectweb.fractal.gui.model.Configuration;
35 import org.objectweb.fractal.gui.selection.model.Selection;
36
37 import java.awt.Cursor JavaDoc;
38 import java.awt.Rectangle JavaDoc;
39 import java.awt.event.MouseEvent JavaDoc;
40
41 import javax.swing.JComponent JavaDoc;
42
43 /**
44  * A controller component to select, move and resize components. This controller
45  * component modifies a graph model, in reaction to events emited by a graph
46  * view.
47  */

48
49 public class SelectTool extends EmptyGraphViewListener
50   implements BindingController
51 {
52
53   /**
54    * A mandatory client interface bound to a {@link Tools tools} model. This
55    * model is used to know if this tool is the currently selected tool or not.
56    */

57
58   public final static String JavaDoc TOOLS_BINDING = "tools";
59
60   /**
61    * A mandatory client interface bound to a {@link Configuration configuration}
62    * model. When the user double clicks on a componnt, this tools changes the
63    * root component of this configuration to the previous component.
64    */

65
66   public final static String JavaDoc CONFIGURATION_BINDING = "configuration";
67
68   /**
69    * A mandatory client interface bound to a {@link GraphModel graph} model.
70    * This is the graph model that is used to move and resize the components.
71    */

72
73   public final static String JavaDoc GRAPH_BINDING = "graph";
74
75   /**
76    * A mandatory client interface bound to a {@link Selection selection} model.
77    * This model is used to select components or interfaces, or to know the
78    * component that must be moved or resized.
79    */

80
81   public final static String JavaDoc SELECTION_BINDING = "selection";
82
83   /**
84    * The tools client interface.
85    */

86
87   private Tools tools;
88
89   /**
90    * The configuratioon client interface.
91    */

92
93   private Configuration configuration;
94
95   /**
96    * The graph model client interface.
97    */

98
99   private GraphModel graph;
100
101   /**
102    * The selection client interface.
103    */

104
105   private Selection selection;
106
107   /**
108    * x coordinate of the point from which the mouse is being dragged.
109    */

110
111   private int startX;
112
113   /**
114    * y coordinate of the point from which the mouse is being dragged.
115    */

116
117   private int startY;
118
119   /**
120    * {@link Rect#x0} coordinate of the moved or resized component, just before
121    * the mouse was dragged.
122    */

123
124   private double startX0;
125
126   /**
127    * {@link Rect#y0} coordinate of the moved or resized component, just before
128    * the mouse was dragged.
129    */

130
131   private double startY0;
132
133   /**
134    * {@link Rect#x1} coordinate of the moved or resized component, just before
135    * the mouse was dragged.
136    */

137
138   private double startX1;
139
140   /**
141    * {@link Rect#y1} coordinate of the moved or resized component, just before
142    * the mouse was dragged.
143    */

144
145   private double startY1;
146
147   /**
148    * The component part that is moved (a corner, a border, of all the
149    * component).
150    */

151
152   private ComponentPart draggedPart;
153
154   /**
155    * Constructs a new {@link SelectTool} component.
156    */

157
158   public SelectTool () {
159   }
160
161   // -------------------------------------------------------------------------
162
// Implementation of the BindingController interface
163
// -------------------------------------------------------------------------
164

165   public String JavaDoc[] listFc () {
166     return new String JavaDoc[] {
167       TOOLS_BINDING,
168       CONFIGURATION_BINDING,
169       GRAPH_BINDING,
170       SELECTION_BINDING
171     };
172   }
173
174   public Object JavaDoc lookupFc (final String JavaDoc clientItfName) {
175     if (TOOLS_BINDING.equals(clientItfName)) {
176       return tools;
177     } else if (CONFIGURATION_BINDING.equals(clientItfName)) {
178       return configuration;
179     } else if (GRAPH_BINDING.equals(clientItfName)) {
180       return graph;
181     } else if (SELECTION_BINDING.equals(clientItfName)) {
182       return selection;
183     }
184     return null;
185   }
186
187   public void bindFc (
188     final String JavaDoc clientItfName,
189     final Object JavaDoc serverItf)
190   {
191     if (TOOLS_BINDING.equals(clientItfName)) {
192       tools = (Tools)serverItf;
193     } else if (CONFIGURATION_BINDING.equals(clientItfName)) {
194       configuration = (Configuration)serverItf;
195     } else if (GRAPH_BINDING.equals(clientItfName)) {
196       graph = (GraphModel)serverItf;
197     } else if (SELECTION_BINDING.equals(clientItfName)) {
198       selection = (Selection)serverItf;
199     }
200   }
201
202   public void unbindFc (final String JavaDoc clientItfName) {
203     if (TOOLS_BINDING.equals(clientItfName)) {
204       tools = null;
205     } else if (CONFIGURATION_BINDING.equals(clientItfName)) {
206       configuration = null;
207     } else if (GRAPH_BINDING.equals(clientItfName)) {
208       graph = null;
209     } else if (SELECTION_BINDING.equals(clientItfName)) {
210       selection = null;
211     }
212   }
213
214   // -------------------------------------------------------------------------
215
// Overriden EmptyGraphViewListener methods
216
// -------------------------------------------------------------------------
217

218   public void viewChanged () {
219     draggedPart = null;
220   }
221
222   public void mousePressed (final MouseEvent JavaDoc e, final ComponentPart p) {
223     if (tools.getTool() != Tools.SELECT) {
224       return;
225     }
226     draggedPart = null;
227     if (p.getComponent() != null) {
228       if (p.getInterface() != null) {
229         selection.selectInterface(p.getInterface());
230         if (p.getInterface() instanceof ClientInterface) {
231           tools.setBindInterface(p.getInterface());
232           tools.setTool(Tools.BIND);
233           e.consume();
234         }
235       } else {
236         Component c = p.getComponent();
237         if (e.getClickCount() == 2) {
238           if (c.getMasterComponent() != null) {
239             c = c.getMasterComponent();
240           }
241           selection.selectComponent(c);
242           configuration.setRootComponent(c);
243         } else {
244           selection.selectComponent(c);
245         }
246         if (c != configuration.getRootComponent()) {
247           Rect position = graph.getComponentPosition(c);
248           startX = e.getX();
249           startY = e.getY();
250           startX0 = position.x0;
251           startY0 = position.y0;
252           startX1 = position.x1;
253           startY1 = position.y1;
254           draggedPart = p;
255         }
256       }
257     }
258   }
259
260   public void mouseReleased (final MouseEvent JavaDoc e, final ComponentPart p) {
261     draggedPart = null;
262   }
263
264   public void mouseClicked (final MouseEvent JavaDoc e, final ComponentPart p) {
265     draggedPart = null;
266   }
267
268   public void mouseDragged (final MouseEvent JavaDoc e) {
269     if (draggedPart != null) {
270       Rectangle JavaDoc r = draggedPart.getPosition();
271       int x0 = r.x;
272       int y0 = r.y;
273       int x1 = x0 + r.width;
274       int y1 = y0 + r.height;
275       int x = e.getX();
276       int y = e.getY();
277       switch (draggedPart.getPart()) {
278         case ComponentPart.HEADER:
279         case ComponentPart.CONTENT:
280           x0 += x - startX;
281           y0 += y - startY;
282           x1 += x - startX;
283           y1 += y - startY;
284           break;
285         case ComponentPart.TOP_LEFT_CORNER:
286           x0 = x;
287           y0 = y;
288           break;
289         case ComponentPart.TOP_RIGHT_CORNER:
290           x1 = x;
291           y0 = y;
292           break;
293         case ComponentPart.BOTTOM_LEFT_CORNER:
294           x0 = x;
295           y1 = y;
296           break;
297         case ComponentPart.BOTTOM_RIGHT_CORNER:
298           x1 = x;
299           y1 = y;
300           break;
301         case ComponentPart.LEFT_BORDER:
302           x0 = x;
303           break;
304         case ComponentPart.TOP_BORDER:
305           y0 = y;
306           break;
307         case ComponentPart.RIGHT_BORDER:
308           x1 = x;
309           break;
310         case ComponentPart.BOTTOM_BORDER:
311           y1 = y;
312           break;
313         default:
314           break;
315       }
316       double X0 = ((x0 - r.x)*(startX1 - startX0))/r.width + startX0;
317       double Y0 = ((y0 - r.y)*(startY1 - startY0))/r.height + startY0;
318       double X1 = ((x1 - r.x)*(startX1 - startX0))/r.width + startX0;
319       double Y1 = ((y1 - r.y)*(startY1 - startY0))/r.height + startY0;
320       switch (draggedPart.getPart()) {
321         case ComponentPart.HEADER:
322         case ComponentPart.CONTENT:
323           if (X0 < 0) {
324             X1 = X1 - X0;
325             X0 = 0;
326           } else if (X1 > 1) {
327             X0 = X0 - X1 + 1;
328             X1 = 1;
329           }
330           if (Y0 < 0) {
331             Y1 = Y1 - Y0;
332             Y0 = 0;
333           } else if (Y1 > 1) {
334             Y0 = Y0 - Y1 + 1;
335             Y1 = 1;
336           }
337           break;
338         case ComponentPart.TOP_LEFT_CORNER:
339           X0 = Math.max(0, Math.min(X0, X1));
340           Y0 = Math.max(0, Math.min(Y0, Y1));
341           break;
342         case ComponentPart.TOP_RIGHT_CORNER:
343           X1 = Math.max(X0, Math.min(X1, 1));
344           Y0 = Math.max(0, Math.min(Y0, Y1));
345           break;
346         case ComponentPart.BOTTOM_LEFT_CORNER:
347           X0 = Math.max(0, Math.min(X0, X1));
348           Y1 = Math.max(Y0, Math.min(Y1, 1));
349           break;
350         case ComponentPart.BOTTOM_RIGHT_CORNER:
351           X1 = Math.max(X0, Math.min(X1, 1));
352           Y1 = Math.max(Y0, Math.min(Y1, 1));
353           break;
354         case ComponentPart.LEFT_BORDER:
355           X0 = Math.max(0, Math.min(X0, X1));
356           break;
357         case ComponentPart.TOP_BORDER:
358           Y0 = Math.max(0, Math.min(Y0, Y1));
359           break;
360         case ComponentPart.RIGHT_BORDER:
361           X1 = Math.max(X0, Math.min(X1, 1));
362           break;
363         case ComponentPart.BOTTOM_BORDER:
364           Y1 = Math.max(Y0, Math.min(Y1, 1));
365           break;
366         default:
367           break;
368       }
369       graph.setComponentPosition(
370         draggedPart.getComponent(),
371         new Rect(X0, Y0, X1, Y1));
372     }
373   }
374
375   public void mouseMoved (final MouseEvent JavaDoc e, final ComponentPart p) {
376     // draggedPart = null; // TODO bug JDK1.4? Windows?
377
if (tools.getTool() == Tools.SELECT) {
378       updateCursor((JComponent JavaDoc)e.getSource(), p);
379     }
380   }
381
382   // -------------------------------------------------------------------------
383
// Other methods
384
// -------------------------------------------------------------------------
385

386   /**
387    * Updates the cursor of the given Swing component, depending above which
388    * component part it is.
389    *
390    * @param component the Swing component whose cursor must be updated.
391    * @param p the component part above which the cursor is.
392    */

393
394   private void updateCursor (
395     final JComponent JavaDoc component,
396     final ComponentPart p)
397   {
398     int type = Cursor.DEFAULT_CURSOR;
399     if (p.getComponent() != null &&
400         p.getComponent() != configuration.getRootComponent())
401     {
402       switch (p.getPart()) {
403         case ComponentPart.HEADER:
404           type = Cursor.MOVE_CURSOR;
405           break;
406         case ComponentPart.TOP_LEFT_CORNER:
407           type = Cursor.NW_RESIZE_CURSOR;
408           break;
409         case ComponentPart.TOP_RIGHT_CORNER:
410           type = Cursor.NE_RESIZE_CURSOR;
411           break;
412         case ComponentPart.BOTTOM_LEFT_CORNER:
413           type = Cursor.SW_RESIZE_CURSOR;
414           break;
415         case ComponentPart.BOTTOM_RIGHT_CORNER:
416           type = Cursor.SE_RESIZE_CURSOR;
417           break;
418         case ComponentPart.LEFT_BORDER:
419           type = Cursor.W_RESIZE_CURSOR;
420           break;
421         case ComponentPart.TOP_BORDER:
422           type = Cursor.N_RESIZE_CURSOR;
423           break;
424         case ComponentPart.RIGHT_BORDER:
425           type = Cursor.E_RESIZE_CURSOR;
426           break;
427         case ComponentPart.BOTTOM_BORDER:
428           type = Cursor.S_RESIZE_CURSOR;
429           break;
430         default:
431           break;
432       }
433     }
434     component.setCursor(Cursor.getPredefinedCursor(type));
435   }
436 }
437
Popular Tags