]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/utils/CanvasUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / utils / CanvasUtils.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.utils;\r
13 \r
14 import java.util.function.Supplier;\r
15 \r
16 import org.simantics.g2d.canvas.Hints;\r
17 import org.simantics.g2d.canvas.ICanvasContext;\r
18 import org.simantics.g2d.diagram.DiagramHints;\r
19 import org.simantics.g2d.diagram.IDiagram;\r
20 import org.simantics.scenegraph.g2d.events.command.Command;\r
21 import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
22 import org.simantics.scenegraph.g2d.events.command.Commands;\r
23 import org.simantics.utils.threads.IThreadWorkQueue;\r
24 import org.simantics.utils.threads.ThreadUtils;\r
25 \r
26 /**\r
27  * @author Toni Kalajainen\r
28  * @author Tuukka Lehtonen\r
29  */\r
30 public class CanvasUtils {\r
31 \r
32     /**\r
33      * Enqueue a command in the event queue of the specified canvas context.\r
34      * \r
35      * @param ctx queue context\r
36      * @param commandId ID of the command to queue\r
37      * \r
38      * @see #sendCommand(ICanvasContext, Command)\r
39      */\r
40     public static void sendCommand(ICanvasContext ctx, String commandId)\r
41     {\r
42         sendCommand(ctx, new Command(commandId));\r
43     }\r
44 \r
45     /**\r
46      * Enqueue a command in the event queue of the specified canvas context.\r
47      * \r
48      * @param ctx queue context\r
49      * @param cmd the command to queue\r
50      */\r
51     public static void sendCommand(ICanvasContext ctx, Command cmd)\r
52     {\r
53         CommandEvent e = new CommandEvent(ctx, System.currentTimeMillis(), cmd);\r
54         ctx.getEventQueue().queueEvent(e);\r
55     }\r
56 \r
57     /**\r
58      * A utility for scheduling a zoom-to-fit operation when an Eclipse\r
59      * workbench editor is initially opened.\r
60      * \r
61      * <p>\r
62      * There are two asynchronous calls, first into the workbench (SWT) UI\r
63      * thread and then into the canvas context thread. This will guarantee that\r
64      * the parenting SWT control has been resized to its actual size instead of\r
65      * the initial (0,0) size which widgets start out at. In order to perform a\r
66      * zoom-to-fit operation we simply have to know the bounds of the parenting\r
67      * control. Thus, we need to ensure that this information is available and\r
68      * correct.\r
69      * \r
70      * @param swtThread\r
71      * @param disposed\r
72      * @param canvasContext\r
73      * @param diagramToFit\r
74      */\r
75     public static void scheduleZoomToFit(IThreadWorkQueue swtThread, final Supplier<Boolean> disposed,\r
76             final ICanvasContext canvasContext, final IDiagram diagramToFit)\r
77     {\r
78         scheduleZoomToFit(swtThread, disposed, canvasContext, diagramToFit, true);\r
79     }\r
80 \r
81     /**\r
82      * A utility for scheduling a zoom-to-fit operation when an Eclipse\r
83      * workbench editor is initially opened.\r
84      * \r
85      * <p>\r
86      * There are two asynchronous calls, first into the workbench (SWT) UI\r
87      * thread and then into the canvas context thread. This will guarantee that\r
88      * the parenting SWT control has been resized to its actual size instead of\r
89      * the initial (0,0) size which widgets start out at. In order to perform a\r
90      * zoom-to-fit operation we simply have to know the bounds of the parenting\r
91      * control. Thus, we need to ensure that this information is available and\r
92      * correct.\r
93      * \r
94      * @param swtThread\r
95      * @param disposed\r
96      * @param canvasContext\r
97      * @param diagramToFit\r
98      * @param zoomToFit\r
99      */\r
100     public static void scheduleZoomToFit(IThreadWorkQueue swtThread, final Supplier<Boolean> disposed,\r
101             final ICanvasContext canvasContext, final IDiagram diagramToFit, boolean zoomToFit)\r
102     {\r
103         if (diagramToFit == null)\r
104             throw new IllegalStateException("source diagram is null");\r
105 \r
106         Boolean canvasZoomToFit = canvasContext.getHintStack().getHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);\r
107         diagramToFit.setHint(Hints.KEY_DISABLE_PAINTING, Boolean.TRUE);\r
108         if (zoomToFit && !Boolean.FALSE.equals(canvasZoomToFit))\r
109             diagramToFit.setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.TRUE);\r
110 \r
111         ThreadUtils.asyncExec(swtThread, new Runnable() {\r
112             @Override\r
113             public void run() {\r
114                 if (disposed.get() || canvasContext.isDisposed())\r
115                     return;\r
116 \r
117                 ThreadUtils.asyncExec(canvasContext.getThreadAccess(), new Runnable() {\r
118                     @Override\r
119                     public void run() {\r
120                         if (disposed.get() || canvasContext.isDisposed())\r
121                             return;\r
122 \r
123                         Boolean zoomToFit = diagramToFit.removeHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT);\r
124                         diagramToFit.removeHint(Hints.KEY_DISABLE_PAINTING);\r
125 \r
126                         if (Boolean.TRUE.equals(zoomToFit))\r
127                             CanvasUtils.sendCommand(canvasContext, Commands.ZOOM_TO_FIT);\r
128                         CanvasUtils.sendCommand(canvasContext, Commands.ENABLE_PAINTING);\r
129                     }\r
130                 });\r
131             }\r
132         });\r
133     }\r
134 \r
135 }\r