001: /*
002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/scenegrapheditor/J3dTreePanel.java,v 1.1 2005/04/20 22:20:46 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dedit.scenegrapheditor;
019:
020: import java.awt.Rectangle;
021: import java.awt.Dimension;
022: import java.awt.Graphics;
023: import java.awt.Point;
024: import java.awt.event.MouseMotionListener;
025: import java.awt.event.MouseListener;
026: import javax.swing.JViewport;
027: import javax.swing.JScrollPane;
028:
029: import org.jdesktop.j3dedit.treelayout.SimpleTreeLayout;
030: import org.jdesktop.j3dedit.treelayout.CircularTreeLayout;
031: import org.jdesktop.j3dedit.treelayout.TreeNode;
032: import org.jdesktop.j3dedit.scenegraph.SGBehavior;
033: import org.jdesktop.j3dedit.scenegrapheditor.treeview.TVObject;
034: import org.jdesktop.j3dedit.scenegrapheditor.treeview.TVBehavior;
035: import java.awt.event.MouseWheelListener;
036:
037: /**
038: * Specialisation of TreePanel that provides tooltips dependent on
039: * mouse location
040: *
041: * Also provides zoom functionality
042: */
043: public class J3dTreePanel extends
044: org.jdesktop.j3dedit.treelayout.TreePanel implements
045: MouseMotionListener, MouseListener, MouseWheelListener {
046:
047: private float currentZoom = 1.0f;
048: private float zoomIncrement = 0.1f;
049:
050: private JViewport viewport = null;
051: private JScrollPane scrollpane = null;
052: private SGBehavior behaviorNode = null;
053: private BehaviorDragLine behaviorDragLine = new BehaviorDragLine();
054:
055: private SimpleTreeLayout simpleTreeLayout = null;
056: private CircularTreeLayout circularTreeLayout = null;
057:
058: public static final int SIMPLE_LAYOUT = 0;
059: public static final int CIRCULAR_LAYOUT = 1;
060:
061: public J3dTreePanel() {
062: super ();
063: setToolTipText("Node");
064: simpleTreeLayout = new SimpleTreeLayout();
065: }
066:
067: /**
068: * Scroll the view so that node is visible
069: */
070: public void showNode(TreeNode node) {
071: this .scrollRectToVisible(new Rectangle(node
072: .getComputedPosition().x, node.getComputedPosition().y,
073: node.getPreferredSize().width,
074: node.getPreferredSize().height));
075: }
076:
077: /**
078: * Selected different tree layout strategies
079: * @see SIMPLE_LAYOUT CIRCULAR_LAYOUT
080: */
081: public void setTreeLayout(int layout) {
082: switch (layout) {
083: case SIMPLE_LAYOUT:
084: setTreeLayout(simpleTreeLayout);
085: break;
086: case CIRCULAR_LAYOUT:
087: if (circularTreeLayout == null)
088: circularTreeLayout = new CircularTreeLayout();
089: setTreeLayout(circularTreeLayout);
090: break;
091: }
092: layoutTree();
093: }
094:
095: public String getToolTipText(java.awt.event.MouseEvent evt) {
096: TVObject node = (TVObject) pickNode(evt.getX(), evt.getY());
097: if (node == null)
098: return null;
099: else
100: return node.getSGObject().getToolTipText();
101: }
102:
103: /**
104: * Get the currentZoom
105: */
106: public float getCurrentZoom() {
107: return currentZoom;
108: }
109:
110: // public void zoomIn() {
111: // zoomIn(new Point(0,0));
112: // }
113:
114: public void zoomIn(Point mousePos) {
115: Dimension oldPanelSize = this .getPreferredSize();
116:
117: Rectangle origView = viewport.getViewRect();
118: Point origPos = viewport.toViewCoordinates(mousePos);
119: origPos.x /= currentZoom;
120: origPos.y /= currentZoom;
121:
122: if (currentZoom + zoomIncrement > 1.0f)
123: return;
124:
125: currentZoom += zoomIncrement;
126: setScale(currentZoom);
127:
128: System.out.println("CurrentZoom " + currentZoom);
129: System.out.println("OrigView " + origView);
130: System.out.println("OrigPos " + origPos);
131: System.out.println("New View " + viewport.getViewRect());
132: System.out.println("NewPos " + (origPos.x * currentZoom) + ", "
133: + (origPos.y * currentZoom));
134: System.out.println();
135:
136: // Calculate position in new coordinate system
137: origPos.x *= currentZoom;
138: origPos.y *= currentZoom;
139:
140: // Now calculate the view position so origPos is in the center of the viewport
141: Dimension extent = viewport.getExtentSize();
142: viewport.toViewCoordinates(extent);
143: System.out.println("Extent " + extent);
144: origPos.x -= extent.width / 2;
145: origPos.y -= extent.height / 2;
146:
147: viewport.setViewPosition(origPos);
148:
149: revalidate();
150: }
151:
152: public void zoomOut(Point origPos) {
153: Dimension oldPanelSize = this .getPreferredSize();
154:
155: currentZoom -= zoomIncrement;
156: setScale(currentZoom);
157:
158: // Calculate position in new coordinate system
159: origPos.x *= currentZoom;
160: origPos.y *= currentZoom;
161:
162: // Now calculate the view position so origPos is in the center of the viewport
163: Dimension extent = viewport.getExtentSize();
164: viewport.toViewCoordinates(extent);
165: System.out.println("Extent " + extent);
166: origPos.x -= extent.width / 2;
167: origPos.y -= extent.height / 2;
168:
169: viewport.setViewPosition(origPos);
170:
171: revalidate();
172: }
173:
174: public void zoomReset() {
175: Dimension oldPanelSize = this .getPreferredSize();
176: currentZoom = 1.0f;
177: setScale(currentZoom);
178:
179: Dimension extent = viewport.getViewSize();
180: viewport.setExtentSize(extent);
181:
182: Point pos = viewport.getViewPosition();
183: pos.x /= extent.width / 2;
184: pos.y /= extent.height / 2;
185: viewport.setViewPosition(pos);
186:
187: revalidate();
188: }
189:
190: /**
191: * Set the zoom so that the whole tree is viewable
192: */
193: public void zoomShowAll() {
194: Rectangle treeSize = getTree().getSubtreeSize();
195: Dimension availableView = viewport.getExtentSize();
196:
197: float zoomWidth = (float) availableView.width
198: / (float) treeSize.width;
199: float zoomHeight = (float) availableView.height
200: / (float) treeSize.height;
201:
202: float newZoom = Math.min(zoomWidth, zoomHeight);
203:
204: if (newZoom > 1.0f)
205: return;
206:
207: currentZoom = newZoom;
208:
209: setScale(currentZoom);
210: }
211:
212: /**
213: * This method is called by the awt when this panel is made displayable
214: * It checks if this panel is contained in a viewport
215: */
216: public void addNotify() {
217: super .addNotify();
218:
219: java.awt.Container parent = getParent();
220: while (parent != null) {
221: if (parent instanceof JViewport) {
222: viewport = (JViewport) parent;
223: scrollpane = (JScrollPane) viewport.getParent();
224: parent = null;
225: } else
226: parent = parent.getParent();
227: }
228: }
229:
230: /**
231: * Put the panel in the Behavior target selection mode when
232: * selection is true.
233: * In this mode a rubberband line will be drawn fromt the behaviorNode
234: * to the mouse pointer.
235: *
236: * This panel is responsible for acting on the mouseMotion events, but the
237: * parent container will handle the mouseClick etc.
238: */
239: public void setTargetBehaviorSelection(boolean selection,
240: SGBehavior behaviorNode) {
241: if (selection) {
242: this .behaviorNode = behaviorNode;
243: this .addMouseMotionListener(this );
244: this .addMouseListener(this );
245: } else {
246: this .removeMouseMotionListener(this );
247: this .removeMouseListener(this );
248: behaviorDragLine.dragFinished(getGraphics());
249: this .behaviorNode = null;
250: this .repaint();
251: }
252: }
253:
254: /**
255: * Return true if we are currently selecting a behavior target
256: */
257: public boolean selectingBehaviorTarget() {
258: return (behaviorNode == null) ? false : true;
259: }
260:
261: public void mouseDragged(final java.awt.event.MouseEvent evt) {
262: }
263:
264: public void mouseMoved(final java.awt.event.MouseEvent evt) {
265: behaviorDragLine.mouseMoved(evt, behaviorNode, getGraphics());
266: }
267:
268: public void test(final java.awt.event.MouseEvent evt) {
269: System.out.println(viewport.toViewCoordinates(evt.getPoint()));
270: }
271:
272: public void mouseClicked(final java.awt.event.MouseEvent evt) {
273: TVObject node = (TVObject) pickNode(evt.getX(), evt.getY());
274:
275: if (node == null) {
276: setTargetBehaviorSelection(false, null);
277: return;
278: }
279:
280: if (behaviorNode.isValidTarget(node.getSGObject())) {
281: behaviorNode.setTarget(node.getSGObject());
282: setTargetBehaviorSelection(false, null);
283: } else {
284: // Actually the drag is not finished, but the mouse will have moved
285: // while the dialog message was being displayed so we need to
286: // delete the last line
287: behaviorDragLine.dragFinished(getGraphics());
288: WindowManager.getManager().showMessage("Invalid Selection",
289: "Invalid Target for this behavior");
290: }
291: }
292:
293: public void layoutTree() {
294: Dimension prefSize = this .getPreferredSize();
295: super .layoutTree();
296:
297: // IF the size of the panel has changed then update the viewport and
298: // scroll the view so the user sees the same view
299: if (!prefSize.equals(this .getPreferredSize())) {
300: Dimension newSize = this .getPreferredSize();
301:
302: viewport.setViewSize(newSize);
303: revalidate();
304: }
305:
306: repaint();
307: }
308:
309: public void mouseEntered(final java.awt.event.MouseEvent p1) {
310: }
311:
312: public void mouseExited(final java.awt.event.MouseEvent evt) {
313: }
314:
315: public void mousePressed(final java.awt.event.MouseEvent p1) {
316: }
317:
318: public void mouseReleased(final java.awt.event.MouseEvent p1) {
319: }
320:
321: public void mouseWheelMoved(java.awt.event.MouseWheelEvent e) {
322: System.out.println(e);
323: }
324:
325: }
326:
327: class BehaviorDragLine {
328:
329: private Point oldStart = new Point(-1, -1);
330: private Point oldEnd = new Point(-1, -1);
331:
332: public void mouseMoved(final java.awt.event.MouseEvent evt,
333: SGBehavior behaviorNode, Graphics g) {
334: g.setXORMode(java.awt.Color.blue);
335: Point start = ((TVBehavior) behaviorNode.getTreeViewObject())
336: .getBehaviorLinkExit(evt.getPoint());
337: Point mouse = evt.getPoint();
338:
339: java.awt.geom.AffineTransform t = ((java.awt.Graphics2D) g)
340: .getTransform();
341: try {
342: t.inverseTransform(mouse, mouse);
343: } catch (java.awt.geom.NoninvertibleTransformException e) {
344: System.out.println("Java2D Internal Error in J3dTreePanel");
345: }
346:
347: // Draw new Line
348: g.drawLine(start.x, start.y, mouse.x, mouse.y);
349:
350: // Delete previous line
351: g.drawLine(oldStart.x, oldStart.y, oldEnd.x, oldEnd.y);
352: oldStart = start;
353: oldEnd = mouse;
354: }
355:
356: public void dragFinished(Graphics g) {
357: g.setXORMode(java.awt.Color.blue);
358: g.drawLine(oldStart.x, oldStart.y, oldEnd.x, oldEnd.y);
359: oldStart.x = -1;
360: oldStart.y = -1;
361: oldEnd.x = -1;
362: oldEnd.y = -1;
363: }
364:
365: }
|