]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/TerminalInformer.java
Performance and resource consumption optimization for G2D picking
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagramEditor / TerminalInformer.java
index 03add4454f161143ed1bdaf49c7a54a83fdf289b..8a4944200dcf5bfa244749496bc0f513fd4dc783 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.modeling.ui.diagramEditor;\r
-\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.util.function.Consumer;\r
-\r
-import org.eclipse.jface.action.IStatusLineManager;\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.eclipse.jface.resource.JFaceResources;\r
-import org.eclipse.jface.resource.ResourceManager;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.ui.IWorkbenchPart;\r
-import org.simantics.databoard.util.ObjectUtils;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.common.procedure.adapter.ProcedureAdapter;\r
-import org.simantics.db.common.request.BinaryRead;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;\r
-import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;\r
-import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;\r
-import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;\r
-import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;\r
-import org.simantics.g2d.participant.TransformUtil;\r
-import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;\r
-import org.simantics.scenegraph.g2d.events.KeyEvent;\r
-import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
-import org.simantics.ui.SimanticsUI;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-import org.simantics.utils.ui.SWTUtils;\r
-import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
-\r
-/**\r
- * Shows information about the terminal under the mouse in the Workbench status\r
- * line.\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class TerminalInformer extends AbstractDiagramParticipant {\r
-\r
-    public static interface TerminalNamingStrategy {\r
-        String getName(ReadGraph graph, TerminalInfo info) throws DatabaseException;\r
-    }\r
-\r
-    /**\r
-     * If this hint is not set or set to <code>false</code>, this participant\r
-     * will show terminal information in the status bar.\r
-     */\r
-    public static final Key TERMINAL_INFO_DISABLED = new KeyOf(Boolean.class);\r
-\r
-    @Dependency\r
-    protected PointerInteractor pointerInteractor;\r
-\r
-    Control                 control;\r
-    transient Display       display;\r
-    IStatusLineManager      statusLine;\r
-    ImageDescriptor         currentImage;\r
-\r
-    @Dependency\r
-    TransformUtil           util;\r
-\r
-    Point2D                 p1                     = new Point2D.Double();\r
-    Point2D                 p2                     = new Point2D.Double();\r
-    Rectangle2D             rect                   = new Rectangle2D.Double();\r
-    String                  viewingMessage;\r
-\r
-    final TerminalNamingStrategy terminalNamingStrategy;\r
-\r
-    /**\r
-     * @param parentControl\r
-     * @param resourceManager deprecated argument, use <code>null</code>\r
-     * @param statusLine\r
-     * @param terminalNamingStrategy\r
-     */\r
-    public TerminalInformer(Control parentControl, ResourceManager resourceManager, IStatusLineManager statusLine, TerminalNamingStrategy terminalNamingStrategy) {\r
-        this.control = parentControl;\r
-        this.statusLine = statusLine;\r
-        this.terminalNamingStrategy = terminalNamingStrategy;\r
-    }\r
-\r
-    @Override\r
-    public void removedFromContext(ICanvasContext ctx) {\r
-        super.removedFromContext(ctx);\r
-\r
-        final IStatusLineManager statusLine = this.statusLine;\r
-        if (display != null && statusLine != null) {\r
-            SWTUtils.asyncExec(display, new Runnable() {\r
-                @Override\r
-                public void run() {\r
-                    if (statusLine != null) {\r
-                        statusLine.setMessage(null, null);\r
-                        statusLine.setErrorMessage(null, null);\r
-                    }\r
-                    if (currentImage != null) {\r
-                        JFaceResources.getResources().destroyImage(currentImage);\r
-                    }\r
-                }\r
-            });\r
-        }\r
-    }\r
-\r
-    public boolean infoDisabled() {\r
-        return Boolean.TRUE.equals(getHint(TERMINAL_INFO_DISABLED));\r
-    }\r
-\r
-    private boolean infoEvent(MouseMovedEvent me) {\r
-        return (me.stateMask & MouseEvent.CTRL_MASK) != 0;\r
-    }\r
-\r
-    private boolean infoEvent(KeyEvent ke) {\r
-        return ke.keyCode == java.awt.event.KeyEvent.VK_CONTROL && (ke instanceof KeyPressedEvent);\r
-    }\r
-\r
-    @EventHandler(priority = 0)\r
-    public boolean handleKeys(KeyEvent ke) {\r
-        if (infoDisabled() || !infoEvent(ke)) {\r
-            setMessage(null);\r
-            return false;\r
-        }\r
-\r
-        pickRect(rect);\r
-        return false;\r
-    }\r
-\r
-    @EventHandler(priority = 0)\r
-    public boolean handleMove(MouseMovedEvent me) {\r
-        double pickDist = pointerInteractor.getPickDistance();\r
-        p1.setLocation(me.controlPosition.getX() - pickDist, me.controlPosition.getY() - pickDist);\r
-        p2.setLocation(me.controlPosition.getX() + pickDist, me.controlPosition.getY() + pickDist);\r
-        util.controlToCanvas(p1, p1);\r
-        util.controlToCanvas(p2, p2);\r
-        rect.setFrameFromDiagonal(p1, p2);\r
-\r
-        if (infoDisabled() || !infoEvent(me)) {\r
-            setMessage(null);\r
-            return false;\r
-        }\r
-\r
-        pickRect(rect);\r
-\r
-        return false;\r
-    }\r
-\r
-    private void createMessage(TerminalInfo terminal, final Consumer<String> callback) {\r
-        SimanticsUI.getSession().asyncRequest(new TerminalInfoMessage(terminal, terminalNamingStrategy), new ProcedureAdapter<String>() {\r
-            @Override\r
-            public void exception(Throwable t) {\r
-                ErrorLogger.defaultLogError(t);\r
-            }\r
-            @Override\r
-            public void execute(String result) {\r
-                callback.accept(result);\r
-            }\r
-        });\r
-    }\r
-\r
-    private void pickRect(Rectangle2D rect) {\r
-        TerminalInfo terminal = TerminalUtil.pickTerminal(diagram, rect);\r
-        if (terminal != null) {\r
-            createMessage(terminal, message -> setMessage(null, message));\r
-        } else {\r
-            setMessage(null);\r
-        }\r
-    }\r
-\r
-    private void setMessage(String message) {\r
-        setMessage(null, message);\r
-    }\r
-\r
-    private void setMessage(final ImageDescriptor imageDescriptor, String _message) {\r
-        // Empty message equals no message.\r
-        if (_message != null && _message.isEmpty())\r
-            _message = null;\r
-        final String message = _message;\r
-\r
-        if (viewingMessage == null && message == null)\r
-            return;\r
-        if (ObjectUtils.objectEquals(viewingMessage, message))\r
-            return;\r
-\r
-        this.viewingMessage = message;\r
-\r
-        SWTUtils.asyncExec(control, new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                if (control.isDisposed())\r
-                    return;\r
-                display = control.getDisplay();\r
-\r
-                Image img = null;\r
-                ResourceManager rm = JFaceResources.getResources();\r
-                if (imageDescriptor != null) {\r
-                    if (imageDescriptor.equals(TerminalInformer.this.currentImage)) {\r
-                        img = (Image) rm.find(imageDescriptor);\r
-                    } else {\r
-                        img = (Image) rm.createImage(imageDescriptor);\r
-                        currentImage = imageDescriptor;\r
-                    }\r
-                } else {\r
-                    if (currentImage != null) {\r
-                        rm.destroyImage(currentImage);\r
-                        currentImage = null;\r
-                    }\r
-                }\r
-\r
-                IStatusLineManager statusLine = getStatusLine();\r
-                if (statusLine != null) {\r
-                    statusLine.setMessage(img, message);\r
-                    statusLine.setErrorMessage(null);\r
-                }\r
-            }\r
-        });\r
-    }\r
-\r
-    static class TerminalInfoMessage extends BinaryRead<TerminalInfo, TerminalNamingStrategy, String> {\r
-        public TerminalInfoMessage(TerminalInfo info, TerminalNamingStrategy strategy) {\r
-            super(info, strategy);\r
-        }\r
-        @Override\r
-        public String perform(ReadGraph graph) throws DatabaseException {\r
-            return parameter2.getName(graph, parameter);\r
-        }\r
-    }\r
-\r
-    protected IStatusLineManager getStatusLine() {\r
-        IWorkbenchPart activePart = WorkbenchUtils.getActiveWorkbenchPart();\r
-        if (activePart != null) {\r
-            TerminalInformer.this.statusLine = statusLine = WorkbenchUtils.getStatusLine(activePart);\r
-            return statusLine;\r
-        }\r
-        return null;\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.ui.diagramEditor;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.function.Consumer;
+
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPart;
+import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.canvas.impl.DependencyReflection.Dependency;
+import org.simantics.g2d.diagram.participant.AbstractDiagramParticipant;
+import org.simantics.g2d.diagram.participant.pointertool.PointerInteractor;
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil;
+import org.simantics.g2d.diagram.participant.pointertool.TerminalUtil.TerminalInfo;
+import org.simantics.g2d.participant.TransformUtil;
+import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler;
+import org.simantics.scenegraph.g2d.events.KeyEvent;
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
+import org.simantics.ui.SimanticsUI;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+import org.simantics.utils.datastructures.hints.IHintContext.KeyOf;
+import org.simantics.utils.ui.ErrorLogger;
+import org.simantics.utils.ui.SWTUtils;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+/**
+ * Shows information about the terminal under the mouse in the Workbench status
+ * line.
+ * 
+ * @author Tuukka Lehtonen
+ */
+public class TerminalInformer extends AbstractDiagramParticipant {
+
+    public static interface TerminalNamingStrategy {
+        String getName(ReadGraph graph, TerminalInfo info) throws DatabaseException;
+    }
+
+    /**
+     * If this hint is not set or set to <code>false</code>, this participant
+     * will show terminal information in the status bar.
+     */
+    public static final Key TERMINAL_INFO_DISABLED = new KeyOf(Boolean.class);
+
+    @Dependency
+    protected PointerInteractor pointerInteractor;
+
+    Control                 control;
+    transient Display       display;
+    IStatusLineManager      statusLine;
+    ImageDescriptor         currentImage;
+
+    @Dependency
+    TransformUtil           util;
+
+    Point2D                 p1                     = new Point2D.Double();
+    Point2D                 p2                     = new Point2D.Double();
+    Rectangle2D             rect                   = new Rectangle2D.Double();
+    String                  viewingMessage;
+
+    final TerminalNamingStrategy terminalNamingStrategy;
+
+    /**
+     * @param parentControl
+     * @param resourceManager deprecated argument, use <code>null</code>
+     * @param statusLine
+     * @param terminalNamingStrategy
+     */
+    public TerminalInformer(Control parentControl, ResourceManager resourceManager, IStatusLineManager statusLine, TerminalNamingStrategy terminalNamingStrategy) {
+        this.control = parentControl;
+        this.statusLine = statusLine;
+        this.terminalNamingStrategy = terminalNamingStrategy;
+    }
+
+    @Override
+    public void removedFromContext(ICanvasContext ctx) {
+        super.removedFromContext(ctx);
+
+        final IStatusLineManager statusLine = this.statusLine;
+        if (display != null && statusLine != null) {
+            SWTUtils.asyncExec(display, new Runnable() {
+                @Override
+                public void run() {
+                    if (statusLine != null) {
+                        statusLine.setMessage(null, null);
+                        statusLine.setErrorMessage(null, null);
+                    }
+                    if (currentImage != null) {
+                        JFaceResources.getResources().destroyImage(currentImage);
+                    }
+                }
+            });
+        }
+    }
+
+    public boolean infoDisabled() {
+        return Boolean.TRUE.equals(getHint(TERMINAL_INFO_DISABLED));
+    }
+
+    private boolean infoEvent(MouseMovedEvent me) {
+        return (me.stateMask & MouseEvent.CTRL_MASK) != 0;
+    }
+
+    private boolean infoEvent(KeyEvent ke) {
+        return ke.keyCode == java.awt.event.KeyEvent.VK_CONTROL && (ke instanceof KeyPressedEvent);
+    }
+
+    @EventHandler(priority = 0)
+    public boolean handleKeys(KeyEvent ke) {
+        if (infoDisabled() || !infoEvent(ke)) {
+            setMessage(null);
+            return false;
+        }
+
+        pickRect(rect);
+        return false;
+    }
+
+    @EventHandler(priority = 0)
+    public boolean handleMove(MouseMovedEvent me) {
+        double pickDist = pointerInteractor.getPickDistance();
+        p1.setLocation(me.controlPosition.getX() - pickDist, me.controlPosition.getY() - pickDist);
+        p2.setLocation(me.controlPosition.getX() + pickDist, me.controlPosition.getY() + pickDist);
+        util.controlToCanvas(p1, p1);
+        util.controlToCanvas(p2, p2);
+        rect.setFrameFromDiagonal(p1, p2);
+
+        if (infoDisabled() || !infoEvent(me)) {
+            setMessage(null);
+            return false;
+        }
+
+        pickRect(rect);
+
+        return false;
+    }
+
+    private void createMessage(TerminalInfo terminal, final Consumer<String> callback) {
+        SimanticsUI.getSession().asyncRequest(new TerminalInfoMessage(terminal, terminalNamingStrategy), new ProcedureAdapter<String>() {
+            @Override
+            public void exception(Throwable t) {
+                ErrorLogger.defaultLogError(t);
+            }
+            @Override
+            public void execute(String result) {
+                callback.accept(result);
+            }
+        });
+    }
+
+    private void pickRect(Rectangle2D rect) {
+        TerminalInfo terminal = TerminalUtil.pickTerminal(getContext(), diagram, rect);
+        if (terminal != null) {
+            createMessage(terminal, message -> setMessage(null, message));
+        } else {
+            setMessage(null);
+        }
+    }
+
+    private void setMessage(String message) {
+        setMessage(null, message);
+    }
+
+    private void setMessage(final ImageDescriptor imageDescriptor, String _message) {
+        // Empty message equals no message.
+        if (_message != null && _message.isEmpty())
+            _message = null;
+        final String message = _message;
+
+        if (viewingMessage == null && message == null)
+            return;
+        if (ObjectUtils.objectEquals(viewingMessage, message))
+            return;
+
+        this.viewingMessage = message;
+
+        SWTUtils.asyncExec(control, new Runnable() {
+            @Override
+            public void run() {
+                if (control.isDisposed())
+                    return;
+                display = control.getDisplay();
+
+                Image img = null;
+                ResourceManager rm = JFaceResources.getResources();
+                if (imageDescriptor != null) {
+                    if (imageDescriptor.equals(TerminalInformer.this.currentImage)) {
+                        img = (Image) rm.find(imageDescriptor);
+                    } else {
+                        img = (Image) rm.createImage(imageDescriptor);
+                        currentImage = imageDescriptor;
+                    }
+                } else {
+                    if (currentImage != null) {
+                        rm.destroyImage(currentImage);
+                        currentImage = null;
+                    }
+                }
+
+                IStatusLineManager statusLine = getStatusLine();
+                if (statusLine != null) {
+                    statusLine.setMessage(img, message);
+                    statusLine.setErrorMessage(null);
+                }
+            }
+        });
+    }
+
+    static class TerminalInfoMessage extends BinaryRead<TerminalInfo, TerminalNamingStrategy, String> {
+        public TerminalInfoMessage(TerminalInfo info, TerminalNamingStrategy strategy) {
+            super(info, strategy);
+        }
+        @Override
+        public String perform(ReadGraph graph) throws DatabaseException {
+            return parameter2.getName(graph, parameter);
+        }
+    }
+
+    protected IStatusLineManager getStatusLine() {
+        IWorkbenchPart activePart = WorkbenchUtils.getActiveWorkbenchPart();
+        if (activePart != null) {
+            TerminalInformer.this.statusLine = statusLine = WorkbenchUtils.getStatusLine(activePart);
+            return statusLine;
+        }
+        return null;
+    }
+
+}