001: package com.opensymphony.workflow.designer;
002:
003: import java.awt.*;
004: import java.awt.event.MouseEvent;
005: import java.awt.geom.Point2D;
006: import java.awt.geom.Rectangle2D;
007: import javax.swing.*;
008:
009: import org.jgraph.graph.BasicMarqueeHandler;
010: import org.jgraph.graph.PortView;
011:
012: /**
013: * @author Hani Suleiman (hani@formicary.net) Date: Oct 25 2003 Time: 6:56:10 PM
014: */
015: public class WorkflowMarqueeHandler extends BasicMarqueeHandler {
016: // Holds the Start and the Current Point
017: protected Point2D start, current;
018:
019: // Holds the First and the Current Port
020: protected PortView port, firstPort;
021: private WorkflowGraph graph;
022:
023: //
024: protected boolean readyToConnect = false;
025:
026: public WorkflowMarqueeHandler(WorkflowGraph graph) {
027: this .graph = graph;
028: }
029:
030: // Override to Gain Control (for PopupMenu and ConnectMode)
031: public boolean isForceMarqueeEvent(MouseEvent e) {
032: // If Right Mouse Button we want to Display the PopupMenu
033: if (SwingUtilities.isRightMouseButton(e) || e.isPopupTrigger())
034: // Return Immediately
035: return true;
036: // Find and Remember Port
037: port = graph.getPortViewAt(e.getX(), e.getY());
038: // If Port Found and in ConnectMode (=Ports Visible)
039: if (port != null && graph.isPortsVisible()) {
040: WorkflowPort workflowPort = (WorkflowPort) port.getCell();
041: //int edgeCount = workflowPort.getEdgeCount();
042: //if we have any edges on this port, then assume we're trying to move the edge, rather
043: //than create a new one
044: if (workflowPort.getIndex() == 0) {
045: return true;
046: }
047: }
048: // Else Call Superclass
049: return super .isForceMarqueeEvent(e);
050: }
051:
052: // Use Xor-Mode on Graphics to Paint Connector
053: protected void paintConnector(Color fg, Color bg, Graphics g) {
054: // Set Foreground
055: g.setColor(fg);
056: // Set Xor-Mode Color
057: g.setXORMode(bg);
058: // Highlight the Current Port
059: paintPort(graph.getGraphics());
060: // If Valid First Port, Start and Current Point
061: if (firstPort != null && start != null && current != null)
062: // Then Draw A Line From Start to Current Point
063: g.drawLine((int) start.getX(), (int) start.getY(),
064: (int) current.getX(), (int) current.getY());
065: }
066:
067: // Use the Preview Flag to Draw a Highlighted Port
068: protected void paintPort(Graphics g) {
069: // If Current Port is Valid
070: if (port != null) {
071: // If Not Floating Port...
072: //boolean isFloating = (GraphConstants.getOffset(port.getAttributes()) != null);
073: // ...Then use Parent's Bounds
074: //Rectangle2D r = isFloating ? port.getBounds() : port.getParentView().getBounds();
075: Rectangle2D r = port.getBounds();
076: // Scale from Model to Screen
077: r = graph.toScreen(r);
078: // Add Space For the Highlight Border
079: Rectangle2D growRect = new Rectangle2D.Double(r.getX() - 3,
080: r.getY() - 3, r.getWidth() + 6, r.getHeight() + 6);
081: //r.setFrame(r.getX() - 3, r.getY() - 3, r.getWidth() + 6, r.getHeight() + 6);
082: // Paint Port in Preview (=Highlight) Mode
083: graph.getUI().paintCell(g, port, growRect, true);
084: }
085: }
086:
087: // Display PopupMenu or Remember Start Location and First Port
088: public void mousePressed(final MouseEvent e) {
089: // If Right Mouse Button
090: if (SwingUtilities.isRightMouseButton(e) || e.isPopupTrigger())
091: // if(e.isPopupTrigger())
092: {
093: // Scale From Screen to Model
094: //Point loc = fromScreen(e.getPoint());
095: // Find Cell in Model Coordinates
096: Object cell = graph.getFirstCellForLocation(e.getX(), e
097: .getY());
098: // Create PopupMenu for the Cell
099: if (cell == null) {
100: graph.showMenu(e.getX(), e.getY());
101: } else {
102: if (!(cell instanceof InitialActionCell)) {
103: // System.out.println(cell);
104: if (cell instanceof WorkflowEdge) {
105: graph.showEdgeMenu(e.getX(), e.getY());
106: } else {
107: graph.showDelete(e.getX(), e.getY());
108: }
109: }
110: }
111:
112: // Else if in ConnectMode and Remembered Port is Valid
113: } else if (port != null && !e.isConsumed()
114: && graph.isPortsVisible()) {
115: // Remember Start Location
116: start = graph.toScreen(port.getLocation(null));
117: // Remember First Port
118: firstPort = port;
119: // Consume Event
120: e.consume();
121: readyToConnect = false;
122: } else
123: // Call Superclass
124: super .mousePressed(e);
125: }
126:
127: // Find Port under Mouse and Repaint Connector
128: public void mouseDragged(MouseEvent e) {
129: // If remembered Start Point is Valid
130: if (start != null && !e.isConsumed()) {
131: // ready to connect
132: readyToConnect = true;
133:
134: // Fetch Graphics from Graph
135: Graphics g = graph.getGraphics();
136: // Xor-Paint the old Connector (Hide old Connector)
137: paintConnector(Color.black, graph.getBackground(), g);
138: // Reset Remembered Port
139: PortView newPort = graph.getPortViewAt(e.getX(), e.getY());
140: if (port != newPort && port != null) {
141: paintPort(g);
142: }
143: port = newPort;
144: // If Port was found then Point to Port Location
145: if (port != null)
146: current = graph.toScreen(port.getLocation(null));
147: // Else If no Port was found then Point to Mouse Location
148: else
149: current = graph.snap(e.getPoint());
150: // Xor-Paint the new Connector
151: paintConnector(graph.getBackground(), Color.black, g);
152: // Consume Event
153: e.consume();
154: }
155: // Call Superclass
156: super .mouseDragged(e);
157: }
158:
159: // Connect the First Port and the Current Port in the Graph or Repaint
160: public void mouseReleased(MouseEvent e) {
161: // If Valid Event, Current and First Port
162: // first connect first is OK
163: if (e != null && !e.isConsumed() && port != null
164: && firstPort != null && readyToConnect) {
165: readyToConnect = false;
166: // Then Establish Connection
167: WorkflowPort sourcePort = (WorkflowPort) firstPort
168: .getCell();
169: WorkflowCell source = (WorkflowCell) sourcePort.getParent();
170: WorkflowPort targetPort = (WorkflowPort) port.getCell();
171: WorkflowCell target = (WorkflowCell) targetPort.getParent();
172: source.setSelectedPort(source.getIndex(sourcePort));
173: target.setSelectedPort(target.getIndex(targetPort));
174: ConnectHelper.connect(source, target,
175: (WorkflowGraphModel) graph.getModel());
176: // System.out.println("connectable "+ ConnectHelper.connect(source, target, (WorkflowGraphModel)graph.getModel()));
177:
178: // connect((Port) firstPort.getCell(), (Port) port.getCell());
179: // Consume Event
180: e.consume();
181: }
182: graph.repaint();
183: // Reset Global Vars
184: firstPort = port = null;
185: start = current = null;
186: // Call Superclass
187: super .mouseReleased(e);
188: }
189:
190: // Show Special Cursor if Over Port
191: public void mouseMoved(MouseEvent e) {
192: // Check Mode and Find Port
193: PortView portView = graph.getPortViewAt(e.getX(), e.getY());
194: if (portView != null && !e.isConsumed()) {
195: // Set Cusor on Graph (Automatically Reset)
196: WorkflowPort workflowPort = (WorkflowPort) portView
197: .getCell();
198: if (workflowPort.getIndex() == 0)
199: //
200: //int edgeCount = workflowPort.getEdgeCount();
201: //if(edgeCount == 0)
202: {
203: graph.setCursor(new Cursor(Cursor.HAND_CURSOR));
204: e.consume();
205: }
206: }
207: // Call Superclass
208: super.mouseReleased(e);
209: }
210: }
|