X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.g2d%2Fsrc%2Forg%2Fsimantics%2Fg2d%2Fdiagram%2Fparticipant%2FSelection.java;h=c7aa7872da2a7e21d94f80ed4e411f4d91fa0c49;hp=c77584825526b4bdc4e69fc0cdd6351bae613d63;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/Selection.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/Selection.java index c77584825..c7aa7872d 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/Selection.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/Selection.java @@ -1,376 +1,376 @@ -/******************************************************************************* - * 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.diagram.participant; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; -import org.simantics.g2d.diagram.DiagramHints; -import org.simantics.g2d.diagram.IDiagram; -import org.simantics.g2d.element.IElement; -import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; -import org.simantics.scenegraph.g2d.events.command.CommandEvent; -import org.simantics.scenegraph.g2d.events.command.Commands; -import org.simantics.utils.DataContainer; -import org.simantics.utils.datastructures.collections.CollectionUtils; -import org.simantics.utils.datastructures.hints.IHintContext.Key; -import org.simantics.utils.datastructures.hints.IHintContext.MouseSpecificKeyOf; -import org.simantics.utils.threads.ThreadUtils; - -/** - * Selection is a canvas utility used for managing selected elements. - *

- * There are multiple selection context. They are differentiated with selectionId. - * Multiple selections are used in multi-user environments (such as multi touch screen). - * In normal diagram setup SELECTION0 is the default selection. - * - * @author Toni Kalajainen - */ -public class Selection extends AbstractCanvasParticipant { - - /** Key for the most common Selection0 */ - public static final SelectionHintKey SELECTION0 = new SelectionHintKey(0); - - private static final Set NO_SELECTION = Collections - .unmodifiableSet(new HashSet(0)); - - public static SelectionHintKey getKeyForSelectionId(int selectionId) { - if (selectionId == 0) - return SELECTION0; - return new SelectionHintKey(selectionId); - } - - @EventHandler(priority = 0) - public boolean handleCommand(CommandEvent e) - { - if (e.command.equals( Commands.SELECT_ALL )) { - IDiagram d = getHint( DiagramHints.KEY_DIAGRAM ); - if (d==null) return true; - addAll(0, d.getElements()); - return true; - } - if (e.command.equals( Commands.INVERT_SELECTION )) { - IDiagram d = getHint( DiagramHints.KEY_DIAGRAM ); - if (d==null) return true; - Set current = getSelection(0); - Set inverted = new HashSet(d.getElements()); - inverted.removeAll(current); - setSelection(0, inverted); - return true; - } - return false; - } - - - /** - * Get selection - * - * @param selectionId - * selectionId - * @return returns a set of pickables - */ - public Set getSelection(int selectionId) { - Key key = getKeyForSelectionId(selectionId); - Set selection = getHint(key); - if (selection == null) - return NO_SELECTION; - return new HashSet(selection); - } - - /** - * Get all selections of all selection ids - * @return all selections - */ - public Set getAllSelections() { - Set result = new HashSet(); - for (Entry entry : getContext() - .getHintStack().getHintsOfClass(SelectionHintKey.class) - .entrySet()) { - @SuppressWarnings("unchecked") - Set set = (Set) entry.getValue(); - if (set == null || set.isEmpty()) - continue; - result.addAll(set); - } - return result; - - } - - /** - * Get selections by selection id - * - * @return map of selection ids and selections - */ - @SuppressWarnings("unchecked") - public Map> getSelections() { - Map> result = new HashMap>(); - for (Entry entry : getContext() - .getHintStack().getHintsOfClass(SelectionHintKey.class) - .entrySet()) { - Set set = (Set) entry.getValue(); - if (set == null || set.isEmpty()) - continue; - result.put(entry.getKey().mouseId, set); - } - return result; - } - - public int[] getSelectionIds() { - Map map = getContext().getHintStack() - .getHintsOfClass(SelectionHintKey.class); - int result[] = new int[map.size()]; - int i = 0; - for (SelectionHintKey key : map.keySet()) - result[i++] = key.mouseId; - return result; - } - - public boolean setSelection(final int selectionId, - final Collection _selection) { - final DataContainer result = new DataContainer(false); - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - Collection selection = _selection; - Key key = getKeyForSelectionId(selectionId); - if (selection == null || selection.isEmpty()) - selection = NO_SELECTION; - Set oldSelection = getHint(key); - if (oldSelection == null) - oldSelection = NO_SELECTION; - if (oldSelection.equals(selection)) - return; - if (selection == NO_SELECTION) { - removeHint(key); - result.set(true); - } - Set newSelection = Collections - .unmodifiableSet(new HashSet(selection)); - setHint(key, newSelection); - result.set(true); - } - }); - return result.get(); - } - - public boolean setSelection(int selectionId, IElement selection) { - ArrayList list = new ArrayList(1); - list.add(selection); - return setSelection(selectionId, list); - } - - /** - * Add item to selection - * - * @param pickable - */ - public boolean add(final int selectionId, final IElement pickable) { - final DataContainer result = new DataContainer(false); - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - Key key = getKeyForSelectionId(selectionId); - Set oldSelection = getSelection(selectionId); - if (oldSelection.contains(pickable)) - return; - Set newSelection = new HashSet( - oldSelection); - newSelection.add(pickable); - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - result.set(true); - } - }); - return result.get(); - } - - /** - * Add items to mouse0's selection - * - * @param pickables - * @return - */ - public boolean addAll(final int selectionId, - final Collection pickables) { - final DataContainer result = new DataContainer(false); - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - - Key key = getKeyForSelectionId(selectionId); - Set selection = getSelection(selectionId); - if (selection.containsAll(pickables)) - return; - Set newSelection = new HashSet(selection); - newSelection.addAll(pickables); - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - result.set(true); - } - }); - return result.get(); - } - - /** - * Remove an item from mouse0's selection - * - * @param pickable - * @return - */ - public boolean remove(final int selectionId, final IElement pickable) { - final DataContainer result = new DataContainer(false); - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - Key key = getKeyForSelectionId(selectionId); - Set oldSelection = getSelection(selectionId); - if (!oldSelection.contains(pickable)) - return; - Set newSelection = new HashSet( - oldSelection); - newSelection.remove(pickable); - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - result.set(true); - } - }); - return result.get(); - } - - /** - * Returns true if two collections have a common object - * - * @param x - * @param y - * @return - */ - public static boolean containsAny(Collection x, Collection y) { - for (Object o : x) - if (y.contains(o)) - return true; - return false; - } - - /** - * Remove items from mouse0's selection - * - * @param pickables - * @return - */ - public boolean removeAll(final int selectionId, - final Collection pickables) { - final DataContainer result = new DataContainer(false); - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - Key key = getKeyForSelectionId(selectionId); - Set oldSelection = getSelection(selectionId); - if (!containsAny(oldSelection, pickables)) - return; - Set newSelection = new HashSet( - oldSelection); - newSelection.removeAll(pickables); - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - result.set(true); - } - }); - return result.get(); - } - - /** - * Retain items in mouse0's selection - * - * @param pickable - * @return - */ - public boolean retainAll(final int selectionId, - final Collection pickable) { - final DataContainer result = new DataContainer(false); - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - Key key = getKeyForSelectionId(selectionId); - Set oldSelection = getSelection(selectionId); - Set newSelection = new HashSet( - oldSelection); - newSelection.retainAll(pickable); - if (oldSelection.equals(newSelection)) - return; - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - result.set(true); - } - }); - return result.get(); - } - - public boolean contains(int selectionId, IElement pickable) { - Set oldSelection = getSelection(selectionId); - return oldSelection.contains(pickable); - } - - public synchronized void toggle(final int selectionId, final Set toggleSet) { - ThreadUtils.syncExec(getThread(), new Runnable() { - @Override - public void run() { - Key key = getKeyForSelectionId(selectionId); - Set oldSelection = getSelection(selectionId); - Set newSelection = new HashSet(oldSelection); - CollectionUtils.toggle(newSelection, toggleSet); - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - } - }); - } - - /** - * Toggle an item in a selection. - */ - public synchronized void toggle(int selectionId, IElement pickable) { - Key key = getKeyForSelectionId(selectionId); - Set oldSelection = getSelection(selectionId); - Set newSelection = new HashSet(oldSelection); - - if (oldSelection.contains(pickable)) - newSelection.remove(pickable); - else - newSelection.add(pickable); - - newSelection = Collections.unmodifiableSet(newSelection); - setHint(key, newSelection); - } - - /** - * Clear selection - */ - public void clear(int selectionId) { - Key key = getKeyForSelectionId(selectionId); - removeHint(key); - } - - /** Class for mouse specific hint keys */ - public static class SelectionHintKey extends MouseSpecificKeyOf { - public SelectionHintKey(int mouseId) { - super(mouseId, Set.class); - } - } - - -} +/******************************************************************************* + * 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.diagram.participant; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import org.simantics.g2d.canvas.impl.AbstractCanvasParticipant; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.element.IElement; +import org.simantics.scenegraph.g2d.events.EventHandlerReflection.EventHandler; +import org.simantics.scenegraph.g2d.events.command.CommandEvent; +import org.simantics.scenegraph.g2d.events.command.Commands; +import org.simantics.utils.DataContainer; +import org.simantics.utils.datastructures.collections.CollectionUtils; +import org.simantics.utils.datastructures.hints.IHintContext.Key; +import org.simantics.utils.datastructures.hints.IHintContext.MouseSpecificKeyOf; +import org.simantics.utils.threads.ThreadUtils; + +/** + * Selection is a canvas utility used for managing selected elements. + *

+ * There are multiple selection context. They are differentiated with selectionId. + * Multiple selections are used in multi-user environments (such as multi touch screen). + * In normal diagram setup SELECTION0 is the default selection. + * + * @author Toni Kalajainen + */ +public class Selection extends AbstractCanvasParticipant { + + /** Key for the most common Selection0 */ + public static final SelectionHintKey SELECTION0 = new SelectionHintKey(0); + + private static final Set NO_SELECTION = Collections + .unmodifiableSet(new HashSet(0)); + + public static SelectionHintKey getKeyForSelectionId(int selectionId) { + if (selectionId == 0) + return SELECTION0; + return new SelectionHintKey(selectionId); + } + + @EventHandler(priority = 0) + public boolean handleCommand(CommandEvent e) + { + if (e.command.equals( Commands.SELECT_ALL )) { + IDiagram d = getHint( DiagramHints.KEY_DIAGRAM ); + if (d==null) return true; + addAll(0, d.getElements()); + return true; + } + if (e.command.equals( Commands.INVERT_SELECTION )) { + IDiagram d = getHint( DiagramHints.KEY_DIAGRAM ); + if (d==null) return true; + Set current = getSelection(0); + Set inverted = new HashSet(d.getElements()); + inverted.removeAll(current); + setSelection(0, inverted); + return true; + } + return false; + } + + + /** + * Get selection + * + * @param selectionId + * selectionId + * @return returns a set of pickables + */ + public Set getSelection(int selectionId) { + Key key = getKeyForSelectionId(selectionId); + Set selection = getHint(key); + if (selection == null) + return NO_SELECTION; + return new HashSet(selection); + } + + /** + * Get all selections of all selection ids + * @return all selections + */ + public Set getAllSelections() { + Set result = new HashSet(); + for (Entry entry : getContext() + .getHintStack().getHintsOfClass(SelectionHintKey.class) + .entrySet()) { + @SuppressWarnings("unchecked") + Set set = (Set) entry.getValue(); + if (set == null || set.isEmpty()) + continue; + result.addAll(set); + } + return result; + + } + + /** + * Get selections by selection id + * + * @return map of selection ids and selections + */ + @SuppressWarnings("unchecked") + public Map> getSelections() { + Map> result = new HashMap>(); + for (Entry entry : getContext() + .getHintStack().getHintsOfClass(SelectionHintKey.class) + .entrySet()) { + Set set = (Set) entry.getValue(); + if (set == null || set.isEmpty()) + continue; + result.put(entry.getKey().mouseId, set); + } + return result; + } + + public int[] getSelectionIds() { + Map map = getContext().getHintStack() + .getHintsOfClass(SelectionHintKey.class); + int result[] = new int[map.size()]; + int i = 0; + for (SelectionHintKey key : map.keySet()) + result[i++] = key.mouseId; + return result; + } + + public boolean setSelection(final int selectionId, + final Collection _selection) { + final DataContainer result = new DataContainer(false); + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + Collection selection = _selection; + Key key = getKeyForSelectionId(selectionId); + if (selection == null || selection.isEmpty()) + selection = NO_SELECTION; + Set oldSelection = getHint(key); + if (oldSelection == null) + oldSelection = NO_SELECTION; + if (oldSelection.equals(selection)) + return; + if (selection == NO_SELECTION) { + removeHint(key); + result.set(true); + } + Set newSelection = Collections + .unmodifiableSet(new HashSet(selection)); + setHint(key, newSelection); + result.set(true); + } + }); + return result.get(); + } + + public boolean setSelection(int selectionId, IElement selection) { + ArrayList list = new ArrayList(1); + list.add(selection); + return setSelection(selectionId, list); + } + + /** + * Add item to selection + * + * @param pickable + */ + public boolean add(final int selectionId, final IElement pickable) { + final DataContainer result = new DataContainer(false); + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + Key key = getKeyForSelectionId(selectionId); + Set oldSelection = getSelection(selectionId); + if (oldSelection.contains(pickable)) + return; + Set newSelection = new HashSet( + oldSelection); + newSelection.add(pickable); + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + result.set(true); + } + }); + return result.get(); + } + + /** + * Add items to mouse0's selection + * + * @param pickables + * @return + */ + public boolean addAll(final int selectionId, + final Collection pickables) { + final DataContainer result = new DataContainer(false); + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + + Key key = getKeyForSelectionId(selectionId); + Set selection = getSelection(selectionId); + if (selection.containsAll(pickables)) + return; + Set newSelection = new HashSet(selection); + newSelection.addAll(pickables); + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + result.set(true); + } + }); + return result.get(); + } + + /** + * Remove an item from mouse0's selection + * + * @param pickable + * @return + */ + public boolean remove(final int selectionId, final IElement pickable) { + final DataContainer result = new DataContainer(false); + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + Key key = getKeyForSelectionId(selectionId); + Set oldSelection = getSelection(selectionId); + if (!oldSelection.contains(pickable)) + return; + Set newSelection = new HashSet( + oldSelection); + newSelection.remove(pickable); + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + result.set(true); + } + }); + return result.get(); + } + + /** + * Returns true if two collections have a common object + * + * @param x + * @param y + * @return + */ + public static boolean containsAny(Collection x, Collection y) { + for (Object o : x) + if (y.contains(o)) + return true; + return false; + } + + /** + * Remove items from mouse0's selection + * + * @param pickables + * @return + */ + public boolean removeAll(final int selectionId, + final Collection pickables) { + final DataContainer result = new DataContainer(false); + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + Key key = getKeyForSelectionId(selectionId); + Set oldSelection = getSelection(selectionId); + if (!containsAny(oldSelection, pickables)) + return; + Set newSelection = new HashSet( + oldSelection); + newSelection.removeAll(pickables); + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + result.set(true); + } + }); + return result.get(); + } + + /** + * Retain items in mouse0's selection + * + * @param pickable + * @return + */ + public boolean retainAll(final int selectionId, + final Collection pickable) { + final DataContainer result = new DataContainer(false); + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + Key key = getKeyForSelectionId(selectionId); + Set oldSelection = getSelection(selectionId); + Set newSelection = new HashSet( + oldSelection); + newSelection.retainAll(pickable); + if (oldSelection.equals(newSelection)) + return; + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + result.set(true); + } + }); + return result.get(); + } + + public boolean contains(int selectionId, IElement pickable) { + Set oldSelection = getSelection(selectionId); + return oldSelection.contains(pickable); + } + + public synchronized void toggle(final int selectionId, final Set toggleSet) { + ThreadUtils.syncExec(getThread(), new Runnable() { + @Override + public void run() { + Key key = getKeyForSelectionId(selectionId); + Set oldSelection = getSelection(selectionId); + Set newSelection = new HashSet(oldSelection); + CollectionUtils.toggle(newSelection, toggleSet); + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + } + }); + } + + /** + * Toggle an item in a selection. + */ + public synchronized void toggle(int selectionId, IElement pickable) { + Key key = getKeyForSelectionId(selectionId); + Set oldSelection = getSelection(selectionId); + Set newSelection = new HashSet(oldSelection); + + if (oldSelection.contains(pickable)) + newSelection.remove(pickable); + else + newSelection.add(pickable); + + newSelection = Collections.unmodifiableSet(newSelection); + setHint(key, newSelection); + } + + /** + * Clear selection + */ + public void clear(int selectionId) { + Key key = getKeyForSelectionId(selectionId); + removeHint(key); + } + + /** Class for mouse specific hint keys */ + public static class SelectionHintKey extends MouseSpecificKeyOf { + public SelectionHintKey(int mouseId) { + super(mouseId, Set.class); + } + } + + +}