2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010 - DIGITEO - Clement DAVID
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
13 package org.scilab.modules.graph;
15 import java.awt.Color;
16 import java.awt.Dimension;
17 import java.awt.Graphics;
18 import java.awt.GraphicsEnvironment;
20 import com.mxgraph.model.mxICell;
21 import com.mxgraph.model.mxIGraphModel;
22 import com.mxgraph.swing.mxGraphComponent;
23 import com.mxgraph.util.mxEvent;
24 import com.mxgraph.util.mxEventObject;
25 import com.mxgraph.util.mxEventSource;
26 import com.mxgraph.util.mxRectangle;
27 import com.mxgraph.view.mxCellState;
28 import com.mxgraph.view.mxGraphView;
31 * Implement the default component for the {@link ScilabGraph}.
33 @SuppressWarnings(value = { "serial" })
34 public class ScilabComponent extends mxGraphComponent {
36 * Color use to mask the graph when the graph is locked
38 private static final Color MASK_COLOR = new Color(240, 240, 240, 100);
40 private static final double SCALE_MULTIPLIER = 1.1;
43 * Construct the component with the associated graph
46 * The associated graph
48 public ScilabComponent(ScilabGraph graph) {
53 * @return the associated graph control
54 * @see com.mxgraph.swing.mxGraphComponent#createGraphControl()
57 protected mxGraphControl createGraphControl() {
58 return new ScilabGraphControl();
62 * Create the associated canvas
67 public ScilabCanvas createCanvas() {
68 return new ScilabCanvas();
72 * Zoom the whole graph and center the view on it.
75 * the cells to center on
77 public void zoomAndCenterToCells(final Object[] cells) {
78 final mxRectangle preference = zoomBounds(cells);
79 final Dimension actual = getViewport().getSize();
81 final double newScale;
82 final double heightScale = actual.getHeight() / preference.getHeight();
83 final double widthScale = actual.getWidth() / preference.getWidth();
85 if (heightScale > 1.0) {
86 if (widthScale > 1.0) {
87 // We need to zoom in (the max applicable zoom is the lowest)
88 newScale = Math.min(heightScale, widthScale);
90 // we need to zoom out (only widthScale is < 1.0)
91 newScale = widthScale;
94 if (widthScale > 1.0) {
95 // we need to zoom out (only heightScale is < 1.0)
96 newScale = heightScale;
98 // We need to zoom out (the max applicable zoom is the lowest)
99 newScale = Math.min(heightScale, widthScale);
103 // do not apply small zoom values
104 if (Math.abs(1.0 - newScale) < 0.2) {
105 getGraphControl().scrollRectToVisible(zoomBounds(cells).getRectangle(), true);
109 zoom(newScale / SCALE_MULTIPLIER);
110 getGraphControl().scrollRectToVisible(zoomBounds(cells).getRectangle(), true);
113 private final mxRectangle zoomBounds(final Object[] cells) {
114 final mxRectangle preference;
116 if (cells == null || cells.length == 0) {
117 c = graph.getChildCells(graph.getDefaultParent());
121 preference = getChildrenBounds(c);
127 * Get the children bound for the cells
130 * the root of the graph
131 * @return the rectangle or null if not applicable
133 private mxRectangle getChildrenBounds(final Object[] cells) {
134 mxRectangle result = null;
136 if (cells != null && cells.length > 0) {
137 final mxGraphView view = graph.getView();
138 final mxIGraphModel model = graph.getModel();
140 for (int i = 0; i < cells.length; i++) {
141 if (model.isVertex(cells[i]) || model.isEdge(cells[i])) {
142 final mxICell parent = ((mxICell) cells[i]);
143 final int childCount = parent.getChildCount();
145 for (int j = 0; j < childCount; j++) {
146 final mxICell child = parent.getChildAt(j);
148 result = updateRectangle(result, view, child);
151 result = updateRectangle(result, view, parent);
160 * Update the rectangle parameter with the cell status
163 * the previous result
167 * the child we have to work on
168 * @return the updated rectangle
170 private mxRectangle updateRectangle(mxRectangle result, final mxGraphView view, final mxICell child) {
171 final mxCellState state = view.getState(child);
172 mxRectangle rect = result;
176 rect = new mxRectangle(state);
185 * Implement a graph control which paint a foreground on top of the view
186 * when the graph is locked.
188 @SuppressWarnings(value = { "serial" })
189 public class ScilabGraphControl extends mxGraphControl {
192 * Default constructor
194 public ScilabGraphControl() {
197 // Paint the foreground color after the real paint
198 addListener(mxEvent.AFTER_PAINT, new mxEventSource.mxIEventListener() {
200 public void invoke(Object sender, mxEventObject evt) {
202 Graphics g = (Graphics) evt.getProperty("g");
203 if (getGraph().isCellsLocked()) {
204 g.setColor(MASK_COLOR);
206 Dimension b = getGraphControl().getSize();
208 g.fillRect(0, 0, b.width, b.height);
216 * Disable some handlers in case of an headless env.
220 protected void createHandlers() {
221 if (GraphicsEnvironment.isHeadless()) {
225 super.createHandlers();