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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g2d.canvas.impl;
\r
14 import java.awt.Cursor;
\r
15 import java.lang.reflect.Method;
\r
16 import java.util.HashMap;
\r
17 import java.util.Map;
\r
18 import java.util.Stack;
\r
20 import org.simantics.g2d.canvas.IMouseCursorContext;
\r
21 import org.simantics.g2d.canvas.IMouseCursorHandle;
\r
22 import org.simantics.g2d.canvas.IMouseCursorHandleListener;
\r
23 import org.simantics.g2d.canvas.IMouseCursorListener;
\r
24 import org.simantics.utils.datastructures.ListenerList;
\r
25 import org.simantics.utils.threads.IThreadWorkQueue;
\r
26 import org.simantics.utils.threads.SyncListenerList;
\r
29 * @author Toni Kalajainen
\r
31 public class MouseCursorContext implements IMouseCursorContext {
\r
33 protected Map<Integer, Stack<CursorReserve>> mouseCursorStack =
\r
34 new HashMap<Integer, Stack<CursorReserve>>();
\r
36 protected SyncListenerList<IMouseCursorListener> cursorListeners =
\r
37 new SyncListenerList<IMouseCursorListener>(IMouseCursorListener.class);
\r
40 public void addCursorListener(IMouseCursorListener listener) {
\r
41 cursorListeners.add(listener);
\r
43 public void addCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {
\r
44 cursorListeners.add(thread, listener);
\r
46 public void removeCursorListener(IMouseCursorListener listener) {
\r
47 cursorListeners.remove(listener);
\r
49 public void removeCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {
\r
50 cursorListeners.remove(thread, listener);
\r
53 private final static Method onCursorSet = SyncListenerList.getMethod(IMouseCursorListener.class, "onCursorSet");
\r
54 protected void fireSetCursor(int mouseId, Cursor cursor) {
\r
55 cursorListeners.fireEventSync(onCursorSet, this, mouseId, cursor);
\r
57 protected void fireAsyncSetCursor(int mouseId, Cursor cursor) {
\r
58 cursorListeners.fireEventAsync(onCursorSet, this, mouseId, cursor);
\r
62 class CursorReserve implements IMouseCursorHandle
\r
66 ListenerList<IMouseCursorHandleListener> listeners;
\r
67 public CursorReserve(Cursor cursor, int mouseId)
\r
69 this.cursor = cursor;
\r
70 this.mouseId = mouseId;
\r
73 public void remove() {
\r
74 synchronized(MouseCursorContext.this)
\r
76 Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);
\r
77 if (cursorStack == null || !cursorStack.contains(this))
\r
80 boolean wasLast = cursorStack.lastElement()==this;
\r
81 cursorStack.remove(this);
\r
82 if (cursorStack.isEmpty()) {
\r
83 _setCursor(mouseId, null);
\r
86 // Select the second last cursor
\r
88 CursorReserve newLast = cursorStack.peek();
\r
89 if (newLast==null) {
\r
90 _setCursor(mouseId, null);
\r
92 Cursor newCursor = newLast.cursor;
\r
93 if (!cursor.equals(newCursor))
\r
94 _setCursor(mouseId, newCursor);
\r
100 public Cursor getCursor() {
\r
104 public int getMouseId() {
\r
107 void fireOnRemoved() {
\r
108 ListenerList<IMouseCursorHandleListener> lis;
\r
109 synchronized(this) {
\r
111 if (lis==null) return;
\r
114 for (IMouseCursorHandleListener l : lis.getListeners())
\r
115 l.onMouseCursorRemoved(this);
\r
119 public synchronized void addMouseCursorHandleListener(IMouseCursorHandleListener listener) {
\r
120 if (listeners == null) {
\r
121 listeners = new ListenerList<IMouseCursorHandleListener>(IMouseCursorHandleListener.class);
\r
123 listeners.add(listener);
\r
126 public synchronized void removeMouseCursorHandleListener(IMouseCursorHandleListener listener) {
\r
127 if (listeners == null) return;
\r
128 listeners.remove(listener);
\r
133 public synchronized IMouseCursorHandle setCursor(int mouseId, Cursor cursor) {
\r
134 assert(cursor!=null);
\r
135 Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);
\r
136 if (cursorStack == null) {
\r
137 cursorStack = new Stack<CursorReserve>();
\r
138 mouseCursorStack.put(mouseId, cursorStack);
\r
140 CursorReserve cr = new CursorReserve(cursor, mouseId);
\r
141 cursorStack.push(cr);
\r
142 _setCursor(mouseId, cursor);
\r
146 protected void _setCursor(int mouseId, Cursor cursor)
\r
148 fireAsyncSetCursor(mouseId, cursor);
\r