1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g2d.canvas.impl;
14 import java.awt.Cursor;
15 import java.lang.reflect.Method;
16 import java.util.HashMap;
18 import java.util.Stack;
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;
29 * @author Toni Kalajainen
31 public class MouseCursorContext implements IMouseCursorContext {
33 protected Map<Integer, Stack<CursorReserve>> mouseCursorStack =
34 new HashMap<Integer, Stack<CursorReserve>>();
36 protected SyncListenerList<IMouseCursorListener> cursorListeners =
37 new SyncListenerList<IMouseCursorListener>(IMouseCursorListener.class);
40 public void addCursorListener(IMouseCursorListener listener) {
41 cursorListeners.add(listener);
43 public void addCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {
44 cursorListeners.add(thread, listener);
46 public void removeCursorListener(IMouseCursorListener listener) {
47 cursorListeners.remove(listener);
49 public void removeCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) {
50 cursorListeners.remove(thread, listener);
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);
57 protected void fireAsyncSetCursor(int mouseId, Cursor cursor) {
58 cursorListeners.fireEventAsync(onCursorSet, this, mouseId, cursor);
62 class CursorReserve implements IMouseCursorHandle
66 ListenerList<IMouseCursorHandleListener> listeners;
67 public CursorReserve(Cursor cursor, int mouseId)
70 this.mouseId = mouseId;
73 public void remove() {
74 synchronized(MouseCursorContext.this)
76 Stack<CursorReserve> cursorStack = mouseCursorStack.get(mouseId);
77 if (cursorStack == null || !cursorStack.contains(this))
80 boolean wasLast = cursorStack.lastElement()==this;
81 cursorStack.remove(this);
82 if (cursorStack.isEmpty()) {
83 _setCursor(mouseId, null);
86 // Select the second last cursor
88 CursorReserve newLast = cursorStack.peek();
90 _setCursor(mouseId, null);
92 Cursor newCursor = newLast.cursor;
93 if (!cursor.equals(newCursor))
94 _setCursor(mouseId, newCursor);
100 public Cursor getCursor() {
104 public int getMouseId() {
107 void fireOnRemoved() {
108 ListenerList<IMouseCursorHandleListener> lis;
111 if (lis==null) return;
114 for (IMouseCursorHandleListener l : lis.getListeners())
115 l.onMouseCursorRemoved(this);
119 public synchronized void addMouseCursorHandleListener(IMouseCursorHandleListener listener) {
120 if (listeners == null) {
121 listeners = new ListenerList<IMouseCursorHandleListener>(IMouseCursorHandleListener.class);
123 listeners.add(listener);
126 public synchronized void removeMouseCursorHandleListener(IMouseCursorHandleListener listener) {
127 if (listeners == null) return;
128 listeners.remove(listener);
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);
140 CursorReserve cr = new CursorReserve(cursor, mouseId);
141 cursorStack.push(cr);
142 _setCursor(mouseId, cursor);
146 protected void _setCursor(int mouseId, Cursor cursor)
148 fireAsyncSetCursor(mouseId, cursor);