X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fcanvas%2Fimpl%2FMouseCursorContext.java;fp=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fcanvas%2Fimpl%2FMouseCursorContext.java;h=a0f354152402c78cd7e4e10d23605e444819f346;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git 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 index 000000000..a0f354152 --- /dev/null +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/canvas/impl/MouseCursorContext.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * 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.g2d.canvas.impl; + +import java.awt.Cursor; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +import org.simantics.g2d.canvas.IMouseCursorContext; +import org.simantics.g2d.canvas.IMouseCursorHandle; +import org.simantics.g2d.canvas.IMouseCursorHandleListener; +import org.simantics.g2d.canvas.IMouseCursorListener; +import org.simantics.utils.datastructures.ListenerList; +import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.SyncListenerList; + +/** + * @author Toni Kalajainen + */ +public class MouseCursorContext implements IMouseCursorContext { + + protected Map> mouseCursorStack = + new HashMap>(); + + protected SyncListenerList cursorListeners = + new SyncListenerList(IMouseCursorListener.class); + + + public void addCursorListener(IMouseCursorListener listener) { + cursorListeners.add(listener); + } + public void addCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) { + cursorListeners.add(thread, listener); + } + public void removeCursorListener(IMouseCursorListener listener) { + cursorListeners.remove(listener); + } + public void removeCursorListener(IMouseCursorListener listener, IThreadWorkQueue thread) { + cursorListeners.remove(thread, listener); + } + + private final static Method onCursorSet = SyncListenerList.getMethod(IMouseCursorListener.class, "onCursorSet"); + protected void fireSetCursor(int mouseId, Cursor cursor) { + cursorListeners.fireEventSync(onCursorSet, this, mouseId, cursor); + } + protected void fireAsyncSetCursor(int mouseId, Cursor cursor) { + cursorListeners.fireEventAsync(onCursorSet, this, mouseId, cursor); + } + + + class CursorReserve implements IMouseCursorHandle + { + Cursor cursor; + int mouseId; + ListenerList listeners; + public CursorReserve(Cursor cursor, int mouseId) + { + this.cursor = cursor; + this.mouseId = mouseId; + } + @Override + public void remove() { + synchronized(MouseCursorContext.this) + { + Stack cursorStack = mouseCursorStack.get(mouseId); + if (cursorStack == null || !cursorStack.contains(this)) + return; + + boolean wasLast = cursorStack.lastElement()==this; + cursorStack.remove(this); + if (cursorStack.isEmpty()) { + _setCursor(mouseId, null); + return; + } + // Select the second last cursor + if (wasLast) { + CursorReserve newLast = cursorStack.peek(); + if (newLast==null) { + _setCursor(mouseId, null); + } else { + Cursor newCursor = newLast.cursor; + if (!cursor.equals(newCursor)) + _setCursor(mouseId, newCursor); + } + } + } + } + @Override + public Cursor getCursor() { + return cursor; + } + @Override + public int getMouseId() { + return mouseId; + } + void fireOnRemoved() { + ListenerList lis; + synchronized(this) { + lis = listeners; + if (lis==null) return; + } + + for (IMouseCursorHandleListener l : lis.getListeners()) + l.onMouseCursorRemoved(this); + } + + @Override + public synchronized void addMouseCursorHandleListener(IMouseCursorHandleListener listener) { + if (listeners == null) { + listeners = new ListenerList(IMouseCursorHandleListener.class); + } + listeners.add(listener); + } + @Override + public synchronized void removeMouseCursorHandleListener(IMouseCursorHandleListener listener) { + if (listeners == null) return; + listeners.remove(listener); + } + } + + @Override + public synchronized IMouseCursorHandle setCursor(int mouseId, Cursor cursor) { + assert(cursor!=null); + Stack cursorStack = mouseCursorStack.get(mouseId); + if (cursorStack == null) { + cursorStack = new Stack(); + mouseCursorStack.put(mouseId, cursorStack); + } + CursorReserve cr = new CursorReserve(cursor, mouseId); + cursorStack.push(cr); + _setCursor(mouseId, cursor); + return cr; + } + + protected void _setCursor(int mouseId, Cursor cursor) + { + fireAsyncSetCursor(mouseId, cursor); + } + + +}