Arbol de plugins y clases nuevas
[DND.git] / DNDCore / Workspace.java
blob582077acf1fc9d27e2d075f20f5155aba8380353
1 package DNDCore;
3 import java.util.logging.Level;
4 import java.util.logging.Logger;
5 import javax.swing.*;
6 import java.awt.*;
7 import java.awt.event.*;
8 import java.util.ArrayList;
10 public class Workspace extends JScrollPane implements MouseListener, MouseMotionListener, ActionListener, KeyListener {
12 private Workarea workarea;
13 private Diagram diagram;
14 private ArrayList<DiagramObject> selectedList;
15 private Tool currentTool;
16 private Rectangle visibleRectangle;
17 private CanvasRectangle selectRectangle;
18 private int startX, startY;
19 private JPopupMenu dObjectPopupmenu;
20 private JPopupMenu dPopupmenu;
21 private JMenuItem cutItem;
22 private JMenuItem copyItem;
23 private JMenuItem pasteItem;
24 private JMenuItem deleteItem;
25 private ArrayList<DiagramObject> clipboard;
26 private boolean clipboardCopy;
27 private Tool oldTool;
28 private DiagramFigure resizerObject;
29 private DiagramObject inserterObject;
30 private JMenuItem[] extendedMenu;
32 public Workspace(Diagram diagram)
34 super();
35 this.diagram = diagram;
36 diagram.setWorkspace(this);
37 setAutoscrolls(true);
38 workarea = new Workarea(this);
39 setViewportView(workarea);
41 workarea.addMouseListener(this);
42 workarea.addMouseMotionListener(this);
44 setTool(Tool.SELECT);
46 visibleRectangle = new Rectangle();
47 selectedList = new ArrayList<DiagramObject>();
48 // Menu para objeto seleccionado
49 dObjectPopupmenu = new JPopupMenu();
50 // Menu para diagrama
51 dPopupmenu = new JPopupMenu();
52 cutItem = new JMenuItem("Cortar");
53 cutItem.addActionListener(this);
54 dObjectPopupmenu.add(cutItem);
55 copyItem = new JMenuItem("Copiar");
56 copyItem.addActionListener(this);
57 dObjectPopupmenu.add(copyItem);
58 deleteItem = new JMenuItem("Eliminar");
59 deleteItem.addActionListener(this);
60 dObjectPopupmenu.add(deleteItem);
61 pasteItem = new JMenuItem("Pegar");
62 pasteItem.addActionListener(this);
63 dPopupmenu.add(pasteItem);
64 pasteItem.setEnabled(false);
65 dObjectPopupmenu.add(new JSeparator());
66 clipboard = new ArrayList<DiagramObject>();
68 getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_DOWN_MASK), "pressed");
69 getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, KeyEvent.CTRL_DOWN_MASK), "pressed");
70 getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_DOWN_MASK), "pressed");
71 getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_DOWN_MASK), "pressed");
72 addKeyListener(this);
74 extendedMenu = null;
77 public void setDNDiagram(Diagram diagram)
79 this.diagram = diagram;
82 public Diagram getDNDiagram()
84 return diagram;
87 public void addElement(DiagramObject element)
89 if(inserterObject != null) {
92 inserterObject.unselect();
95 inserterObject = element;
96 unselectAll();
98 diagram.addElement(element);
99 element.select();
101 setTool(Tool.INSERTER);
104 public void updateWorkspace()
108 // No queremos que se redimensione con el rectangulo de selección
109 if(selectRectangle == null) {
110 Canvas canvas = diagram.getCanvas();
112 int xMove = 0;
113 int yMove = 0;
114 ArrayList<DiagramObject> elements = diagram.getElements();
115 for(DiagramObject o : elements)
117 CanvasSmartObject cso = o.getDrawing();
118 Point p = cso.getPosition();
119 if(p.x < 0 && -p.x > xMove) {
120 xMove = -p.x;
123 if(p.y < 0 && -p.y > yMove) {
124 yMove = -p.y;
128 for(DiagramObject o : elements) {
129 Point p = o.getDrawing().getPosition();
130 p.x += xMove;
131 p.y += yMove;
134 Dimension pd = canvas.getSize();
135 int barWidth;
137 barWidth = Math.max(15, getVerticalScrollBar().getWidth());
138 pd.width = Math.max(pd.width, getSize().width - barWidth);
139 barWidth = Math.max(15, getHorizontalScrollBar().getWidth());
140 pd.height = Math.max(pd.height, getSize().height - barWidth);
142 workarea.setPreferredSize(pd);
143 workarea.setMinimumSize(pd);
145 /* Creen que es correcto setear View cada vez que un componente
146 * cambia una propiedad de interes ?
148 setViewportView(workarea);
151 workarea.repaint();
154 public void mouseClicked(MouseEvent e)
159 public void mouseEntered(MouseEvent e)
164 public void mouseExited(MouseEvent e)
169 private void deleteSelected() {
170 for (DiagramObject o : selectedList) {
171 if(o instanceof DiagramVertice)
172 ((DiagramVertice)o).disconnect();
174 diagram.removeElement(o);
178 private void unselectAll()
180 for(DiagramObject o : selectedList)
181 o.unselect();
183 selectedList.clear();
186 private void selectAll()
188 for(DiagramObject o : selectedList)
189 o.select();
192 private void moveSelectedList(int xDiff, int yDiff) {
193 for (DiagramObject o : selectedList) {
194 Point curPos = o.getDrawing().getPosition();
195 curPos.x += xDiff;
196 curPos.y += yDiff;
201 private void showMenu(JPopupMenu menu)
203 Point mousePosition = getViewport().getMousePosition();
204 menu.show(this, mousePosition.x, mousePosition.y);
208 public void mousePressed(MouseEvent e) {
209 DiagramObject diagramObject;
210 Canvas canvas = diagram.getCanvas();
212 requestFocus();
214 switch (currentTool) {
215 case SELECT:
216 Point evPoint = canvas.toCanvasCoordinate(e.getPoint());
217 startX = evPoint.x;
218 startY = evPoint.y;
219 if ((diagramObject = diagram.getElementIn(startX, startY)) != null) {
220 CanvasSmartObject drawing = diagramObject.getDrawing();
221 if (!selectedList.contains(diagramObject)) {
223 if (selectedList.size() > 0) {
224 unselectAll();
227 selectedList.add(diagramObject);
228 diagramObject.select();
229 // To top
230 diagram.removeElement(diagramObject);
231 diagram.addElement(diagramObject);
233 updateWorkspace();
234 } else if(diagramObject instanceof DiagramFigure && e.getButton() == MouseEvent.BUTTON1){
235 // Es un objeto seleccionado
236 // Reviso si el cursor esta en la esquina inferior derecha.
237 int cornerX = drawing.getPosition().x + drawing.getWidth();
238 int cornerY = drawing.getPosition().y + drawing.getHeight();
239 System.out.println(cornerX);
240 System.out.println(cornerY);
242 System.out.println(evPoint);
243 if(evPoint.x >= cornerX-6 && evPoint.x <= cornerX + 6 && evPoint.y >= cornerY - 6 && evPoint.y <= cornerY + 6) {
244 setTool(Tool.RESIZER);
245 resizerObject = (DiagramFigure) diagramObject;
246 resizerObject.unselect();
247 selectRectangle = new CanvasRectangle(new Point(drawing.getPosition().x, drawing.getPosition().y), drawing.getWidth(), drawing.getHeight());
248 selectRectangle.setBackground(new Color(0, 200, 0, 180));
249 canvas.addElement(selectRectangle);
250 updateWorkspace();
254 if (e.getButton() == MouseEvent.BUTTON3) {
256 if(extendedMenu != null)
257 for(JMenuItem mi : extendedMenu) {
258 dObjectPopupmenu.remove(mi);
261 extendedMenu = diagramObject.getExtendedMenu();
262 if(extendedMenu != null)
263 for(JMenuItem mi : extendedMenu) {
264 dObjectPopupmenu.add(mi);
267 showMenu(dObjectPopupmenu);
269 } else {
271 if(selectedList.size() > 0)
272 unselectAll();
274 if(selectRectangle != null)
275 canvas.removeElement(selectRectangle);
277 if(e.getButton() == MouseEvent.BUTTON1) {
278 selectRectangle = new CanvasRectangle(new Point(startX, startY), 0, 0);
279 selectRectangle.setBackground(new Color(0, 255, 0, 50));
280 canvas.addElement(selectRectangle);
281 } else if(e.getButton() == MouseEvent.BUTTON3)
282 showMenu(dPopupmenu);
285 break;
286 case HAND:
287 startX = e.getPoint().x;
288 startY = e.getPoint().y;
289 break;
290 case INSERTER:
291 inserterObject.unselect();
292 inserterObject = null;
293 setTool(oldTool);
294 break;
298 public void mouseReleased(MouseEvent e) {
299 Canvas canvas = diagram.getCanvas();
301 switch (currentTool) {
302 case SELECT:
303 if (selectRectangle != null) {
304 canvas.removeElement(selectRectangle);
305 if(Math.abs(selectRectangle.getWidth() + selectRectangle.getHeight()) > 0)
306 diagram.getElementsIn(selectedList, selectRectangle.getEffectivePosition().x, selectRectangle.getEffectivePosition().y, selectRectangle.getWidth(), selectRectangle.getHeight());
308 selectAll();
309 selectRectangle = null;
311 break;
312 case HAND:
313 break;
315 case RESIZER:
316 canvas.removeElement(selectRectangle);
318 int width = selectRectangle.getWidth();
319 int height = selectRectangle.getHeight();
321 Point p = resizerObject.getDrawing().getPosition();
323 if(width < 0) {
324 p.x += width;
325 width = -width;
328 if(height < 0) {
329 p.y += height;
330 height = -height;
333 resizerObject.resize(width, height);
335 selectRectangle = null;
336 resizerObject.select();
337 resizerObject = null;
338 currentTool = oldTool;
339 break;
341 setTool(currentTool);
342 updateWorkspace();
345 public void mouseDragged(MouseEvent e)
347 Canvas canvas = diagram.getCanvas();
348 Point evPoint = canvas.toCanvasCoordinate(e.getPoint());
350 switch(currentTool) {
352 case SELECT:
353 if(selectedList.size() > 0) {
354 moveSelectedList(evPoint.x - startX, evPoint.y - startY);
355 workarea.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
356 } else if(selectRectangle != null) {
357 selectRectangle.setWidth(selectRectangle.getWidth() + evPoint.x - startX);
358 selectRectangle.setHeight(selectRectangle.getHeight() + evPoint.y - startY);
360 startX = evPoint.x;
361 startY = evPoint.y;
362 break;
363 case HAND:
364 JViewport vp = getViewport();
365 Dimension visibleDimension = vp.getExtentSize();
366 Point mousePosition = vp.getMousePosition();
367 if(mousePosition != null) {
368 int xDistance = e.getPoint().x - startX;
369 int yDistance = e.getPoint().y - startY;
371 if(xDistance == 0) {
372 visibleRectangle.x = mousePosition.x;
373 visibleRectangle.width = 0;
374 } else
375 // Arrastre hacia la izquierda
376 if(xDistance < 0) {
377 visibleRectangle.x = visibleDimension.width;
378 visibleRectangle.width = -xDistance;
379 } else { // Arrastre hacia la derecha
380 visibleRectangle.x = -xDistance;
381 visibleRectangle.width = xDistance;
384 if(yDistance == 0) {
385 visibleRectangle.y = mousePosition.y;
386 visibleRectangle.height = 0;
387 } else
388 // Arrastre hacia arriba
389 if(yDistance < 0) {
390 visibleRectangle.y = visibleDimension.height;
391 visibleRectangle.height = -yDistance;
392 } else { // Arrastre hacia abajo
393 visibleRectangle.y = -yDistance;
394 visibleRectangle.height = yDistance;
396 vp.scrollRectToVisible(visibleRectangle);
399 break;
400 case RESIZER:
401 int width = evPoint.x - resizerObject.getX();
402 int height = evPoint.y - resizerObject.getY();
403 selectRectangle.setWidth(width);
404 selectRectangle.setHeight(height);
405 break;
408 updateWorkspace();
412 public void mouseMoved(MouseEvent e)
414 Canvas canvas = diagram.getCanvas();
415 Point evPoint = canvas.toCanvasCoordinate(e.getPoint());
417 switch(currentTool) {
418 case INSERTER:
419 Point p = inserterObject.getDrawing().getPosition();
420 p.x = evPoint.x;
421 p.y = evPoint.y;
423 updateWorkspace();
424 break;
428 public void actionPerformed(ActionEvent e) {
429 if (selectedList.size() > 0) {
430 if (e.getSource() == cutItem) {
431 clipboardCopy = false;
432 clipboard.clear();
433 pasteItem.setEnabled(true);
434 clipboard.addAll(selectedList);
435 deleteSelected();
436 unselectAll();
437 Point mousePosition = workarea.getMousePosition();
438 for (DiagramObject o : clipboard) {
439 Point p = o.getDrawing().getPosition();
440 p.x -= mousePosition.x*(1.0/o.getDrawing().getCanvas().getZoom());
441 p.y -= mousePosition.y*(1.0/o.getDrawing().getCanvas().getZoom());
444 updateWorkspace();
445 } else if (e.getSource() == copyItem) {
446 clipboardCopy = true;
447 clipboard.clear();
448 pasteItem.setEnabled(true);
449 Point mousePosition = workarea.getMousePosition();
450 DiagramObject clonedO;
451 for (DiagramObject o : selectedList) {
452 try {
453 o.unselect();
454 clonedO = (DiagramObject) o.clone();
455 o.select();
456 Point p = clonedO.getDrawing().getPosition();
457 p.x -= mousePosition.x * (1.0 / o.getDrawing().getCanvas().getZoom());
458 p.y -= mousePosition.y * (1.0 / o.getDrawing().getCanvas().getZoom());
459 clipboard.add(clonedO);
460 } catch (CloneNotSupportedException ex) {
461 Logger.getLogger(Workspace.class.getName()).log(Level.SEVERE, null, ex);
463 System.out.println("Copiado");
467 } else if (e.getSource() == deleteItem) {
468 deleteSelected();
469 unselectAll();
470 updateWorkspace();
473 if (clipboard.size() > 0) {
474 if (e.getSource() == pasteItem) {
475 unselectAll();
476 Point mousePosition = getViewport().getMousePosition();
477 selectedList.addAll(clipboard);
478 clipboard.clear();
479 if(clipboardCopy) {
480 for(DiagramObject o : selectedList) {
481 try {
482 clipboard.add((DiagramObject) o.clone());
483 } catch (CloneNotSupportedException ex) {
484 Logger.getLogger(Workspace.class.getName()).log(Level.SEVERE, null, ex);
487 } else
488 pasteItem.setEnabled(false);
490 for (DiagramObject o : selectedList) {
491 diagram.addElement(o);
492 Point p = o.getDrawing().getPosition();
493 p.x += mousePosition.x*(1.0/o.getDrawing().getCanvas().getZoom());
494 p.y += mousePosition.y*(1.0/o.getDrawing().getCanvas().getZoom());
496 selectAll();
497 updateWorkspace();
502 public void setTool(Tool tool)
504 oldTool = currentTool;
505 currentTool = tool;
506 switch(tool) {
507 case SELECT:
508 workarea.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
509 break;
510 case HAND:
511 if(selectedList.size() > 0) {
512 unselectAll();
513 updateWorkspace();
515 workarea.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
516 break;
521 public Workarea getWorkarea()
523 return workarea;
526 public void setZoom(double factor)
528 Canvas canvas = diagram.getCanvas();
529 canvas.setZoom(factor);
531 updateWorkspace();
534 public void keyTyped(KeyEvent e) {
538 public void keyPressed(KeyEvent e) {
539 ActionEvent aEvent = null;
540 if(e.getModifiers() == KeyEvent.CTRL_MASK) {
541 switch(e.getKeyCode()) {
542 case KeyEvent.VK_X:
543 aEvent = new ActionEvent(cutItem, 0, null, 0);
544 break;
545 case KeyEvent.VK_V:
546 aEvent = new ActionEvent(pasteItem, 0, null, 0);
547 break;
548 case KeyEvent.VK_C:
549 aEvent = new ActionEvent(copyItem, 0, null, 0);
550 break;
552 if(aEvent != null)
553 actionPerformed(aEvent);
557 public void keyReleased(KeyEvent arg0) {