| NetworkInteractionMode.java |
1 /****************************************************************************
2 * This demo file is part of yFiles for Java 2.14.
3 * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28,
4 * 72070 Tuebingen, Germany. All rights reserved.
5 *
6 * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution
7 * of demo files in source code or binary form, with or without
8 * modification, is not permitted.
9 *
10 * Owners of a valid software license for a yFiles for Java version that this
11 * demo is shipped with are allowed to use the demo source code as basis
12 * for their own yFiles for Java powered applications. Use of such programs is
13 * governed by the rights and conditions as set out in the yFiles for Java
14 * license agreement.
15 *
16 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 ***************************************************************************/
28 package demo.view.networkmonitoring;
29
30 import y.base.DataMap;
31 import y.base.Edge;
32 import y.base.Node;
33 import y.view.EdgeLabel;
34 import y.view.Graph2D;
35 import y.view.Graph2DTraversal;
36 import y.view.HitInfo;
37 import y.view.NodeLabel;
38 import y.view.NodeRealizer;
39 import y.view.ViewMode;
40
41 import java.awt.Cursor;
42
43 /**
44 * {@link ViewMode} to disable, enable or repair network nodes and edges and to show/hide info labels.
45 */
46 public class NetworkInteractionMode extends ViewMode {
47 private final DataMap ids;
48 private final NetworkModel model;
49
50 public NetworkInteractionMode(NetworkModel model, DataMap ids) {
51 this.model = model;
52 this.ids = ids;
53 }
54
55 /**
56 * Overwritten to change the show/hide info labels when a nodes was clicked or to change the state of network elements
57 * according to the buttons that where clicked.
58 *
59 * @param x the x-coordinate of the mouse event in world coordinates.
60 * @param y the y-coordinate of the mouse event in world coordinates.
61 */
62 public void mouseClicked(double x, double y) {
63 final Graph2D graph = getGraph2D();
64 final HitInfo hit = getHitInfo(x, y);
65 if (hitErrorSign(hit, x, y)) {
66 // hit sign was clicked so repair the belonging network node or connection respectively.
67 final Node hitNode = hit.getHitNode();
68 if (hitNode != null) {
69 final NetworkData data = NetworkMonitoringFactory.getNetworkData(graph.getRealizer(hitNode));
70 if (data.isBroken()) {
71 model.repairNetworkNode(ids.get(hitNode));
72 }
73 }
74 final EdgeLabel hitLabel = hit.getHitEdgeLabel();
75 if (hitLabel != null) {
76 final Edge edge = hitLabel.getEdge();
77 final NetworkData data = NetworkMonitoringFactory.getNetworkData(graph.getRealizer(edge));
78 if (data.isBroken()) {
79 model.repairEdge(ids.get(edge));
80 }
81 }
82 } else if (view.getZoom() > NetworkMonitoringDemo.LABEL_HIDE_ZOOM_LEVEL) {
83 // info labels are visible
84 if (hit.hasHitNodeLabels()) {
85 final NodeLabel hitNodeLabel = hit.getHitNodeLabel();
86 if (NetworkInfoLabelPainter.hitsCloseIcon(hitNodeLabel, x, y)) {
87 // close icon got hit => hide info label
88 hitNodeLabel.setVisible(false);
89 } else if (NetworkInfoLabelPainter.hitsStateChangeIcon(hitNodeLabel, x, y)) {
90 // state change icon got hit => update the state of the according network node
91 final Node node = hitNodeLabel.getNode();
92 final NetworkData data = NetworkMonitoringFactory.getNetworkData(graph.getRealizer(node));
93 if (data.isBroken()) {
94 model.repairNetworkNode(ids.get(node));
95 } else if (data.isDisabled()) {
96 model.enableNetworkNode(ids.get(node));
97 } else if (data.isOK()) {
98 model.disableNetworkNode(ids.get(node));
99 }
100 }
101 } else if (hit.hasHitNodes()) {
102 // node was hit => toggle visibility of the belonging info label
103 final Node hitNode = hit.getHitNode();
104 final NodeRealizer realizer = graph.getRealizer(hitNode);
105 final NodeLabel infoLabel = realizer.getLabel();
106 infoLabel.setVisible(!infoLabel.isVisible());
107 }
108 }
109 }
110
111 /**
112 * Overwritten to indicate a possible interaction when moving the mouse over a node, an edge or an edge label by
113 * changing the mouse cursor visualization.
114 *
115 * @param x the x-coordinate of the mouse event in world coordinates.
116 * @param y the y-coordinate of the mouse event in world coordinates.
117 */
118 public void mouseMoved(double x, double y) {
119 changeCursor(x, y, Cursor.getDefaultCursor());
120 }
121
122 /**
123 * Overwritten to show panning cursor when moving the view port by changing the mouse cursor visualization.
124 *
125 * @param x the x-coordinate of the mouse event in world coordinates.
126 * @param y the y-coordinate of the mouse event in world coordinates.
127 */
128 public void mouseDraggedLeft(double x, double y) {
129 view.setViewCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
130 }
131
132 /**
133 * Overwritten to avoid panning cursor when clicking on a node, an edge or an edge label by changing the mouse cursor
134 * visualization. Sadly, there is no closed hand cursor in AWT, so the normal hand is used
135 *
136 * @param x the x-coordinate of the mouse event in world coordinates.
137 * @param y the y-coordinate of the mouse event in world coordinates.
138 */
139 public void mousePressedLeft(double x, double y) {
140 changeCursor(x, y, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
141 }
142
143 /**
144 * Overwritten to indicate a possible interaction when mouse is still over a node, an edge or an edge label by
145 * changing the mouse cursor visualization.
146 *
147 * @param x the x-coordinate of the mouse event in world coordinates.
148 * @param y the y-coordinate of the mouse event in world coordinates.
149 */
150 public void mouseReleasedLeft(double x, double y) {
151 changeCursor(x, y, Cursor.getDefaultCursor());
152 }
153
154 private void changeCursor(double x, double y, Cursor defaultCursor) {
155 final HitInfo hit = getHitInfo(x, y);
156 if (hitsButton(hit, x, y) || hit.hasHitNodes()) {
157 view.setViewCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
158 } else {
159 view.setViewCursor(defaultCursor);
160 }
161 }
162
163 /**
164 * Determines whether or not any kind of button is hit by the given coordinates.
165 *
166 * @param hit current hit information.
167 * @param x x-coordinate of the location to be checked in world-coordinates.
168 * @param y y-coordinate of the location to be checked in world-coordinates.
169 *
170 * @return <code>true</code> when a button is hit, <code>false</code> otherwise.
171 */
172 private boolean hitsButton(HitInfo hit, double x, double y) {
173 if (hitErrorSign(hit, x, y)) {
174 return true;
175 } else if (hit.hasHitNodeLabels() && view.getZoom() > NetworkMonitoringDemo.LABEL_HIDE_ZOOM_LEVEL) {
176 final NodeLabel hitNodeLabel = hit.getHitNodeLabel();
177 if (NetworkInfoLabelPainter.hitsCloseIcon(hitNodeLabel, x, y)
178 || NetworkInfoLabelPainter.hitsStateChangeIcon(hitNodeLabel, x, y)) {
179 return true;
180 }
181 }
182 return false;
183 }
184
185 /**
186 * Determines whether or not a warning sign either on a network node or connection is hit by the given coordinates.
187 *
188 * @param hit current hit information.
189 * @param x x-coordinate of the location to be checked in world-coordinates.
190 * @param y y-coordinate of the location to be checked in world-coordinates.
191 *
192 * @return <code>true</code> when a warning sign is hit, <code>false</code> otherwise.
193 */
194 private boolean hitErrorSign(HitInfo hit, double x, double y) {
195 if (view.getZoom() > view.getPaintDetailThreshold()) {
196 if (hit.hasHitNodes()) {
197 final NodeRealizer realizer = getGraph2D().getRealizer(hit.getHitNode());
198 return NetworkNodePainter.hitWarningSign(realizer, x, y);
199 } else if (hit.hasHitEdgeLabels()) {
200 return true;
201 }
202 }
203 return false;
204 }
205
206 /**
207 * Overwritten to get a {@link HitInfo} with all possible graph elements at the given coordinates.
208 */
209 protected HitInfo getHitInfo(double x, double y) {
210 return view.getHitInfoFactory().createHitInfo(x, y, Graph2DTraversal.ALL, false);
211 }
212 }
213