]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/canvas/impl/MouseCursorContext.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / canvas / impl / MouseCursorContext.java
diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/canvas/impl/MouseCursorContext.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/canvas/impl/MouseCursorContext.java
new file mode 100644 (file)
index 0000000..a0f3541
--- /dev/null
@@ -0,0 +1,152 @@
+/*******************************************************************************\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.g2d.canvas.impl;\r
+\r
+import java.awt.Cursor;\r
+import java.lang.reflect.Method;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.Stack;\r
+\r
+import org.simantics.g2d.canvas.IMouseCursorContext;\r
+import org.simantics.g2d.canvas.IMouseCursorHandle;\r
+import org.simantics.g2d.canvas.IMouseCursorHandleListener;\r
+import org.simantics.g2d.canvas.IMouseCursorListener;\r
+import org.simantics.utils.datastructures.ListenerList;\r
+import org.simantics.utils.threads.IThreadWorkQueue;\r
+import org.simantics.utils.threads.SyncListenerList;\r
+\r
+/**\r
+ * @author Toni Kalajainen\r
+ */\r
+public class MouseCursorContext implements IMouseCursorContext {\r
+\r
+    protected Map<Integer, Stack<CursorReserve>> mouseCursorStack =\r
+        new HashMap<Integer, Stack<CursorReserve>>();\r
+\r
+    protected SyncListenerList<IMouseCursorListener> cursorListeners =\r
+        new SyncListenerList<IMouseCursorListener>(IMouseCursorListener.class);\r
+    \r
+\r
+    public void addCursorListener(IMouseCursorListener listener) {\r
+        cursorListeners.add(listener);\r
+    }\r
+    public void addCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {\r
+        cursorListeners.add(thread, listener);\r
+    }    \r
+    public void removeCursorListener(IMouseCursorListener listener) {\r
+        cursorListeners.remove(listener);\r
+    }\r
+    public void removeCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {\r
+        cursorListeners.remove(thread, listener);\r
+    }\r
+    \r
+    private final static Method onCursorSet = SyncListenerList.getMethod(IMouseCursorListener.class, "onCursorSet");\r
+    protected void fireSetCursor(int mouseId, Cursor cursor) {\r
+        cursorListeners.fireEventSync(onCursorSet, this, mouseId, cursor);\r
+    }\r
+    protected void fireAsyncSetCursor(int mouseId, Cursor cursor) {\r
+        cursorListeners.fireEventAsync(onCursorSet, this, mouseId, cursor);\r
+    }\r
+        \r
+    \r
+    class CursorReserve implements IMouseCursorHandle\r
+    {\r
+        Cursor cursor;\r
+        int mouseId;\r
+        ListenerList<IMouseCursorHandleListener> listeners;        \r
+        public CursorReserve(Cursor cursor, int mouseId)\r
+        {\r
+            this.cursor = cursor;\r
+            this.mouseId = mouseId;\r
+        }\r
+        @Override        \r
+        public void remove() {\r
+            synchronized(MouseCursorContext.this)\r
+            {\r
+                Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);\r
+                if (cursorStack == null || !cursorStack.contains(this))\r
+                    return;\r
+                \r
+                boolean wasLast = cursorStack.lastElement()==this;\r
+                cursorStack.remove(this);\r
+                if (cursorStack.isEmpty()) {\r
+                    _setCursor(mouseId, null);\r
+                    return;\r
+                }\r
+                // Select the second last cursor\r
+                if (wasLast) {\r
+                    CursorReserve newLast = cursorStack.peek();\r
+                    if (newLast==null) {\r
+                        _setCursor(mouseId, null);\r
+                    } else {\r
+                        Cursor newCursor = newLast.cursor;\r
+                        if (!cursor.equals(newCursor))\r
+                            _setCursor(mouseId, newCursor);                        \r
+                    }\r
+                }\r
+            }\r
+        }\r
+        @Override\r
+        public Cursor getCursor() {\r
+            return cursor;\r
+        }\r
+        @Override\r
+        public int getMouseId() {\r
+            return mouseId;\r
+        }\r
+        void fireOnRemoved() {\r
+            ListenerList<IMouseCursorHandleListener> lis;\r
+            synchronized(this) {\r
+                lis = listeners;\r
+                if (lis==null) return;\r
+            }\r
+            \r
+            for (IMouseCursorHandleListener l : lis.getListeners())\r
+                l.onMouseCursorRemoved(this);\r
+        }\r
+        \r
+        @Override\r
+        public synchronized void addMouseCursorHandleListener(IMouseCursorHandleListener listener) {\r
+            if (listeners == null) {\r
+                listeners = new ListenerList<IMouseCursorHandleListener>(IMouseCursorHandleListener.class);\r
+            }\r
+            listeners.add(listener);\r
+        }\r
+        @Override\r
+        public synchronized void removeMouseCursorHandleListener(IMouseCursorHandleListener listener) {\r
+            if (listeners == null) return;\r
+            listeners.remove(listener);\r
+        }      \r
+    }\r
+    \r
+    @Override\r
+    public synchronized IMouseCursorHandle setCursor(int mouseId, Cursor cursor) {\r
+        assert(cursor!=null);\r
+        Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);\r
+        if (cursorStack == null) {\r
+            cursorStack = new Stack<CursorReserve>();\r
+            mouseCursorStack.put(mouseId, cursorStack);\r
+        }\r
+        CursorReserve cr = new CursorReserve(cursor, mouseId);\r
+        cursorStack.push(cr);\r
+        _setCursor(mouseId, cursor);\r
+        return cr;\r
+    }\r
+    \r
+    protected void _setCursor(int mouseId, Cursor cursor)\r
+    {\r
+        fireAsyncSetCursor(mouseId, cursor);    \r
+    }\r
+    \r
+    \r
+}\r