]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/canvas/impl/MouseCursorContext.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / canvas / impl / MouseCursorContext.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g2d.canvas.impl;
13
14 import java.awt.Cursor;
15 import java.lang.reflect.Method;
16 import java.util.HashMap;
17 import java.util.Map;
18 import java.util.Stack;
19
20 import org.simantics.g2d.canvas.IMouseCursorContext;
21 import org.simantics.g2d.canvas.IMouseCursorHandle;
22 import org.simantics.g2d.canvas.IMouseCursorHandleListener;
23 import org.simantics.g2d.canvas.IMouseCursorListener;
24 import org.simantics.utils.datastructures.ListenerList;
25 import org.simantics.utils.threads.IThreadWorkQueue;
26 import org.simantics.utils.threads.SyncListenerList;
27
28 /**
29  * @author Toni Kalajainen
30  */
31 public class MouseCursorContext implements IMouseCursorContext {
32
33     protected Map<Integer, Stack<CursorReserve>> mouseCursorStack =
34         new HashMap<Integer, Stack<CursorReserve>>();
35
36     protected SyncListenerList<IMouseCursorListener> cursorListeners =
37         new SyncListenerList<IMouseCursorListener>(IMouseCursorListener.class);
38     
39
40     public void addCursorListener(IMouseCursorListener listener) {
41         cursorListeners.add(listener);
42     }
43     public void addCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {
44         cursorListeners.add(thread, listener);
45     }    
46     public void removeCursorListener(IMouseCursorListener listener) {
47         cursorListeners.remove(listener);
48     }
49     public void removeCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {
50         cursorListeners.remove(thread, listener);
51     }
52     
53     private final static Method onCursorSet = SyncListenerList.getMethod(IMouseCursorListener.class, "onCursorSet");
54     protected void fireSetCursor(int mouseId, Cursor cursor) {
55         cursorListeners.fireEventSync(onCursorSet, this, mouseId, cursor);
56     }
57     protected void fireAsyncSetCursor(int mouseId, Cursor cursor) {
58         cursorListeners.fireEventAsync(onCursorSet, this, mouseId, cursor);
59     }
60         
61     
62     class CursorReserve implements IMouseCursorHandle
63     {
64         Cursor cursor;
65         int mouseId;
66         ListenerList<IMouseCursorHandleListener> listeners;        
67         public CursorReserve(Cursor cursor, int mouseId)
68         {
69             this.cursor = cursor;
70             this.mouseId = mouseId;
71         }
72         @Override        
73         public void remove() {
74             synchronized(MouseCursorContext.this)
75             {
76                 Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);
77                 if (cursorStack == null || !cursorStack.contains(this))
78                     return;
79                 
80                 boolean wasLast = cursorStack.lastElement()==this;
81                 cursorStack.remove(this);
82                 if (cursorStack.isEmpty()) {
83                     _setCursor(mouseId, null);
84                     return;
85                 }
86                 // Select the second last cursor
87                 if (wasLast) {
88                     CursorReserve newLast = cursorStack.peek();
89                     if (newLast==null) {
90                         _setCursor(mouseId, null);
91                     } else {
92                         Cursor newCursor = newLast.cursor;
93                         if (!cursor.equals(newCursor))
94                             _setCursor(mouseId, newCursor);                        
95                     }
96                 }
97             }
98         }
99         @Override
100         public Cursor getCursor() {
101             return cursor;
102         }
103         @Override
104         public int getMouseId() {
105             return mouseId;
106         }
107         void fireOnRemoved() {
108             ListenerList<IMouseCursorHandleListener> lis;
109             synchronized(this) {
110                 lis = listeners;
111                 if (lis==null) return;
112             }
113             
114             for (IMouseCursorHandleListener l : lis.getListeners())
115                 l.onMouseCursorRemoved(this);
116         }
117         
118         @Override
119         public synchronized void addMouseCursorHandleListener(IMouseCursorHandleListener listener) {
120             if (listeners == null) {
121                 listeners = new ListenerList<IMouseCursorHandleListener>(IMouseCursorHandleListener.class);
122             }
123             listeners.add(listener);
124         }
125         @Override
126         public synchronized void removeMouseCursorHandleListener(IMouseCursorHandleListener listener) {
127             if (listeners == null) return;
128             listeners.remove(listener);
129         }      
130     }
131     
132     @Override
133     public synchronized IMouseCursorHandle setCursor(int mouseId, Cursor cursor) {
134         assert(cursor!=null);
135         Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);
136         if (cursorStack == null) {
137             cursorStack = new Stack<CursorReserve>();
138             mouseCursorStack.put(mouseId, cursorStack);
139         }
140         CursorReserve cr = new CursorReserve(cursor, mouseId);
141         cursorStack.push(cr);
142         _setCursor(mouseId, cursor);
143         return cr;
144     }
145     
146     protected void _setCursor(int mouseId, Cursor cursor)
147     {
148         fireAsyncSetCursor(mouseId, cursor);    
149     }
150     
151     
152 }