From 254ee6f47eebfc00462c10756a92066e82cc1a96 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Tue, 21 Jun 2011 15:46:02 +0200 Subject: Initial commit --- .../controller/MultiSelectionDragController.java | 551 +++++++++++++++++++++ 1 file changed, 551 insertions(+) create mode 100755 source/com/c2kernel/graph/controller/MultiSelectionDragController.java (limited to 'source/com/c2kernel/graph/controller/MultiSelectionDragController.java') diff --git a/source/com/c2kernel/graph/controller/MultiSelectionDragController.java b/source/com/c2kernel/graph/controller/MultiSelectionDragController.java new file mode 100755 index 0000000..8e9a2b3 --- /dev/null +++ b/source/com/c2kernel/graph/controller/MultiSelectionDragController.java @@ -0,0 +1,551 @@ +package com.c2kernel.graph.controller; + +import java.awt.Point; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +import com.c2kernel.graph.model.DirectedEdge; +import com.c2kernel.graph.model.ElasticBand; +import com.c2kernel.graph.model.GraphModelManager; +import com.c2kernel.graph.model.GraphPoint; +import com.c2kernel.graph.model.GraphableVertex; +import com.c2kernel.graph.model.Selection; +import com.c2kernel.graph.model.Vertex; +import com.c2kernel.graph.view.EditorModeListener; + + +public class MultiSelectionDragController +extends MouseAdapter +implements EditorModeListener, MouseMotionListener, KeyListener +{ + private class ResizeInf + { + public int mMousePressedX = 0; + public int mMousePressedY = 0; + public Vertex mSelectedVertex = null; + public GraphPoint[] mOldOutline = null; + public int mCentreX = 0; + public int mCentreY = 0; + public int mOldHeight = 0; + public int mOldWidth = 0; + } + private ResizeInf mResizeInf = new ResizeInf(); + + private class DispForSelection + { + public int mXDisp = 0; + public int mYDisp = 0; + } + private DispForSelection mDispForSelection = null; + + private class VertexAndDisp + { + public Vertex mVertex = null; + public int mXDisp = 0; + public int mYDisp = 0; + } + + protected GraphModelManager mGraphModelManager = null; + + + /**********/ + /* States */ + /**********/ + protected final Integer kOtherMode = new Integer(0); + protected final Integer kWaiting = new Integer(1); + protected final Integer kResizing = new Integer(2); + protected final Integer kDraggingSelection = new Integer(3); + protected final Integer kStretching = new Integer(4); + + + /**********/ + /* Events */ + /**********/ + protected final int kSelectEntered = 0; + protected final int kOtherEntered = 1; + protected final int kPressOnEdge = 2; + protected final int kPressOnVertex = 3; + protected final int kPressOnSelection = 4; + protected final int kPressOnResizePad = 5; + protected final int kCTRLPressOnVertex = 6; + protected final int kCTRL_A = 7; + protected final int kPressOnNothing = 8; + protected final int kDrag = 9; + protected final int kRelease = 10; + protected final int kZoomIn = 11; + + /***********/ + /* Actions */ + /***********/ + + protected interface Action + { + public void doIt(Object data); + } + + + protected Action mStoreResizeInf = new Action() + { + public void doIt(Object data) + { + Point mousePoint = (Point)data; + GraphPoint centre = null; + + mResizeInf.mMousePressedX = mousePoint.x; + mResizeInf.mMousePressedY = mousePoint.y; + mResizeInf.mSelectedVertex = mGraphModelManager.getModel().getSelection().mVertices[0]; + mResizeInf.mOldOutline = mResizeInf.mSelectedVertex.getOutlinePoints(); + centre = mResizeInf.mSelectedVertex.getCentrePoint(); + mResizeInf.mCentreX = centre.x; + mResizeInf.mCentreY = centre.y; + mResizeInf.mOldHeight = mResizeInf.mSelectedVertex.getHeight(); + mResizeInf.mOldWidth = mResizeInf.mSelectedVertex.getWidth(); + } + }; + + + protected Action mResizeVertex = new Action() + { + public void doIt(Object data) + { + Point mousePoint = (Point)data; + int resizeX = 0; + int resizeY = 0; + + + // Calculate how much the old outline should be resized + resizeX = mousePoint.x - mResizeInf.mMousePressedX; + resizeY = mousePoint.y - mResizeInf.mMousePressedY; + + // Clip the resize so that outline does not get any + // smaller than 10 x 10 pixels + if(resizeX < -mResizeInf.mOldWidth/2 + 10) + { + resizeX = -mResizeInf.mOldWidth/2 + 10; + } + + if(resizeY < -mResizeInf.mOldHeight/2 + 10) + { + resizeY = -mResizeInf.mOldHeight/2 + 10; + } + + if (mGraphModelManager.isEditable()) { + mResizeInf.mSelectedVertex.setOutlinePoints(newOutline(resizeX, resizeY)); + mGraphModelManager.forceNotify(); + } + } + + + private GraphPoint[] newOutline(int resizeX, int resizeY) + { + GraphPoint[] newOutline = new GraphPoint[mResizeInf.mOldOutline.length]; + int x = 0; + int y = 0; + int i = 0; + + + for(i=0; i mResizeInf.mCentreX) + { + x = mResizeInf.mOldOutline[i].x + resizeX; + } + else if(mResizeInf.mOldOutline[i].x < mResizeInf.mCentreX) + { + x = mResizeInf.mOldOutline[i].x - resizeX; + } + else + { + x = mResizeInf.mOldOutline[i].x; + } + + if(mResizeInf.mOldOutline[i].y > mResizeInf.mCentreY) + { + y = mResizeInf.mOldOutline[i].y + resizeY; + } + else if(mResizeInf.mOldOutline[i].y < mResizeInf.mCentreY) + { + y = mResizeInf.mOldOutline[i].y - resizeY; + } + else + { + y = mResizeInf.mOldOutline[i].y; + } + + newOutline[i] = new GraphPoint(x, y); + } + + return newOutline; + } + }; + + + protected Action mSelectEdge = new Action() + { + public void doIt(Object data) + { + Selection selection = new Selection((DirectedEdge)data, null, 0, 0, 0, 0); + + mGraphModelManager.getModel().setSelection(selection); + } + }; + + + protected Action mSelectVertexAndStoreDisp = new Action() + { + public void doIt(Object data) + { + VertexAndDisp vertexAndDisp = (VertexAndDisp)data; + GraphPoint centrePoint = vertexAndDisp.mVertex.getCentrePoint(); + Selection selection = new Selection(null, + new Vertex[] {vertexAndDisp.mVertex}, + centrePoint.x, + centrePoint.y, + centrePoint.x, + centrePoint.y); + + mGraphModelManager.getModel().setSelection(selection); + mDispForSelection = new DispForSelection(); + mDispForSelection.mXDisp = vertexAndDisp.mXDisp; + mDispForSelection.mYDisp = vertexAndDisp.mYDisp; + } + }; + + + protected Action mStoreDisp = new Action() + { + public void doIt(Object data) + { + mDispForSelection = (DispForSelection)data; + } + }; + + + protected Action mToggleVertex = new Action() + { + public void doIt(Object data) + { + Vertex vertex = (Vertex)data; + + if(mGraphModelManager.getModel().inSelection(vertex)) + { + mGraphModelManager.getModel().removeFromSelection(vertex); + } + else + { + mGraphModelManager.getModel().addToSelection(vertex); + } + } + }; + + + protected Action mSelectAll = new Action() + { + public void doIt(Object data) + { + mGraphModelManager.getModel().selectAll(); + } + }; + + + protected Action mCreateBand = new Action() + { + public void doIt(Object data) + { + Point fixedCorner = (Point)data; + + mGraphModelManager.getModel().setElasticBand(new ElasticBand(fixedCorner, fixedCorner)); + } + }; + + + protected Action mMoveSelection = new Action() + { + public void doIt(Object data) + { + Point mousePoint = (Point)data; + int topLeftX = mousePoint.x - mDispForSelection.mXDisp; + int topLeftY = mousePoint.y - mDispForSelection.mYDisp; + if (mGraphModelManager.isEditable()) { + mGraphModelManager.getModel().moveAbsoluteSelection(topLeftX, topLeftY); + } + } + }; + + + protected Action mResizeBand = new Action() + { + public void doIt(Object data) + { + mGraphModelManager.getModel().resizeElasticBand((Point)data); + } + }; + + + protected Action mSelectContents = new Action() + { + public void doIt(Object data) + { + mGraphModelManager.getModel().selectContentsOfElasticBand(); + } + }; + + protected Action mZoomIn = new Action() + { + public void doIt(Object data) // data is the clicked vertex + { + // Need to get child graph model out of the vertex before we can zoom in + if (data instanceof Vertex) { + Vertex zoomTo = (Vertex)data; + if (((GraphableVertex)zoomTo).getIsComposite()) mGraphModelManager.zoomIn(zoomTo); + } + } + }; + + /***********************************/ + /* Finite State Transition Network */ + /***********************************/ + + protected Object[][][] mFSTN = + {// OtherMode Waiting Resizing DraggingSelection Stretching + /* SelectEntered */ {{null, kWaiting}, null , null , null , null }, + /* OtherEntered */ { null , {null , kOtherMode }, null , null , null }, + /* PressOnEdge */ { null , {mSelectEdge , null }, null , null , null }, + /* PressOnVertex */ { null , {mSelectVertexAndStoreDisp, kDraggingSelection}, null , null , null }, + /* PressOnSelection */ { null , {mStoreDisp , kDraggingSelection}, null , null , null }, + /* PressOnResizePad */ { null , {mStoreResizeInf , kResizing }, null , null , null }, + /* CTRLPressOnVertex */ { null , {mToggleVertex , null }, null , null , null }, + /* CTRL_A */ { null , {mSelectAll , null }, null , null , null }, + /* PressOnNothing */ { null , {mCreateBand , kStretching }, null , null , null }, + /* Drag */ { null , null , {mResizeVertex, null }, {mMoveSelection, null }, {mResizeBand , null }}, + /* Release */ { null , null , {null , kWaiting}, {null , kWaiting}, {mSelectContents, kWaiting}}, + /* Double Click */ { null , {mZoomIn , null }, null , null , null }, + }; + + + /*****************/ + /* Current state */ + /*****************/ + + private Integer mState = kWaiting; + + + /**************************/ + /* Event processing logic */ + /**************************/ + + protected void processEvent(int event, Object data) + { + Object[] transition = mFSTN[event][mState.intValue()]; + Action action = null; + Integer nextState = null; + + if(transition != null) + { + action = (Action)transition[0]; + nextState = (Integer)transition[1]; + + if(action != null) + { + action.doIt(data); + } + + if(nextState != null) + { + mState = nextState; + } + } + } + + + /********************/ + /* Public interface */ + /********************/ + + public void setGraphModelManager(GraphModelManager graphModelManager) + { + mGraphModelManager = graphModelManager; + } + + + public void editorModeChanged(String idOfNewMode) + { + if(idOfNewMode.equals("Select")) + { + processEvent(kSelectEntered, null); + } + else + { + processEvent(kOtherEntered, null); + } + } + + + public void mousePressed(MouseEvent me) + { + int modifiers = me.getModifiers(); + + if(mGraphModelManager != null) + { + if((modifiers & InputEvent.CTRL_MASK) == 0) + { + mousePressedWithoutCTRL(me.getPoint()); + } + else + { + mousePressedWithCTRL(me.getPoint()); + } + } + } + + public void mouseClicked(MouseEvent me) + { + if (me.getClickCount() == 2) { // want double click + Point clickedSpot = me.getPoint(); + GraphPoint mouseGPoint = new GraphPoint(clickedSpot.x, clickedSpot.y); + Vertex clicked = mGraphModelManager.getModel().getVertex(mouseGPoint); + if (clicked != null) + processEvent(kZoomIn, clicked); + } + } + + private void mousePressedWithoutCTRL(Point mousePoint) + { + GraphPoint mouseGPoint = new GraphPoint(mousePoint.x, mousePoint.y); + DirectedEdge edge = mGraphModelManager.getModel().getEdge(mouseGPoint); + Vertex vertex = mGraphModelManager.getModel().getVertex(mouseGPoint); + GraphPoint vertexCentrePoint = null; + VertexAndDisp vertexAndDisp = null; + Selection selection = null; + DispForSelection dispForSelection = null; + + + // In order of priority: + // 1. Click on resize pad + // 2. Click on vertex + // 3. Click on edge + if(onResizePad(mouseGPoint)) + { + processEvent(kPressOnResizePad, mousePoint); + } + else if(vertex != null) + { + if(mGraphModelManager.getModel().inSelection(vertex)) + { + selection = mGraphModelManager.getModel().getSelection(); + dispForSelection = new DispForSelection(); + dispForSelection.mXDisp = mousePoint.x - selection.mTopLeftX; + dispForSelection.mYDisp = mousePoint.y - selection.mTopLeftY; + + processEvent(kPressOnSelection, dispForSelection); + } + else + { + vertexCentrePoint = vertex.getCentrePoint(); + + vertexAndDisp = new VertexAndDisp(); + vertexAndDisp.mVertex = vertex; + vertexAndDisp.mXDisp = mousePoint.x - vertexCentrePoint.x; + vertexAndDisp.mYDisp = mousePoint.y - vertexCentrePoint.y; + + processEvent(kPressOnVertex, vertexAndDisp); + } + } + // vertex == null + else + { + if(edge == null) + { + processEvent(kPressOnNothing, mousePoint); + } + else + { + processEvent(kPressOnEdge, edge); + } + } + } + + + private boolean onResizePad(GraphPoint mouseGPoint) + { + Selection selection = mGraphModelManager.getModel().getSelection(); + GraphPoint vertexCentre = null; + int bottomRightX = 0; + int bottomRightY = 0; + + + if(selection.mVertices == null) return false; + + if(selection.mVertices.length == 1) + { + vertexCentre = selection.mVertices[0].getCentrePoint(); + if (vertexCentre == null) return false; + bottomRightX = vertexCentre.x + selection.mVertices[0].getWidth()/2; + bottomRightY = vertexCentre.y + selection.mVertices[0].getHeight()/2; + + return + ( + (mouseGPoint.x > bottomRightX) && + (mouseGPoint.x < bottomRightX + 10) && + (mouseGPoint.y > bottomRightY) && + (mouseGPoint.y < bottomRightY + 10) + ); + } + else + { + return false; + } + } + + + private void mousePressedWithCTRL(Point mousePoint) + { + Vertex vertex = mGraphModelManager.getModel().getVertex(new GraphPoint(mousePoint.x, mousePoint.y)); + + if(vertex != null) + { + processEvent(kCTRLPressOnVertex, vertex); + } + } + + + public void mouseReleased(MouseEvent me) + { + processEvent(kRelease, null); + } + + + public void mouseMoved(MouseEvent me) + { + } + + + public void mouseDragged(MouseEvent e) + { + processEvent(kDrag, e.getPoint()); + } + + + public void keyPressed(KeyEvent e) + { + if((e.getKeyCode() == KeyEvent.VK_A) && e.isControlDown()) + { + processEvent(kCTRL_A, null); + } + } + + + public void keyReleased(KeyEvent e) + { + } + + + public void keyTyped(KeyEvent e) + { + } + +} -- cgit v1.2.3