X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.browsing.ui.swt%2Fsrc%2Forg%2Fsimantics%2Fbrowsing%2Fui%2Fswt%2FGraphExplorerImpl.java;h=0168ad864ae5e98258498d76fef7f04f42ee4282;hp=df736c1e6dc2603315bea23f47b46a2170a52f55;hb=270834ce3962a4bca3945d06e642a99d21688c16;hpb=79b952a1ea3ae3f299c6d7aa612a98b7ae5db51a diff --git a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java index df736c1e6..0168ad864 100644 --- a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java +++ b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/GraphExplorerImpl.java @@ -50,6 +50,7 @@ import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.resource.ResourceManager; +import org.eclipse.jface.util.OpenStrategy; import org.eclipse.jface.viewers.IPostSelectionProvider; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -68,7 +69,6 @@ import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; @@ -289,24 +289,6 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph public static final int DEFAULT_MAX_CHILDREN = 1000; - private static final long POST_SELECTION_DELAY = 300; - - /** - * The time in milliseconds that must elapse between consecutive - * {@link Tree} {@link SelectionListener#widgetSelected(SelectionEvent)} - * invocations in order for this class to construct a new selection. - * - *

- * This is done because selection construction can be very expensive as the - * selected set grows larger when the user is pressing shift+arrow keys. - * GraphExplorerImpl will naturally listen to all changes in the tree - * selection, but as an optimization will not construct new - * StructuredSelection instances for every selection change event. A new - * selection will be constructed and set only if the selection hasn't - * changed for the amount of milliseconds specified by this constant. - */ - private static final long SELECTION_CHANGE_QUIET_TIME = 150; - private final IThreadWorkQueue thread; /** @@ -328,11 +310,11 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph Tree tree; @SuppressWarnings({ "rawtypes" }) - final HashMap, NodeQueryProcessor> processors = new HashMap, NodeQueryProcessor>(); + final HashMap, NodeQueryProcessor> processors = new HashMap<>(); @SuppressWarnings({ "rawtypes" }) - final HashMap primitiveProcessors = new HashMap(); + final HashMap primitiveProcessors = new HashMap<>(); @SuppressWarnings({ "rawtypes" }) - final HashMap dataSources = new HashMap(); + final HashMap dataSources = new HashMap<>(); class GraphExplorerContext extends AbstractDisposable implements IGraphExplorerContext { // This is for query debugging only. @@ -351,7 +333,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph * null there's nothing scheduled yet in which case * scheduling can commence. Otherwise the update should be skipped. */ - AtomicReference currentQueryUpdater = new AtomicReference(); + AtomicReference currentQueryUpdater = new AtomicReference<>(); /** * Keeps track of nodes that have already been auto-expanded. After @@ -359,7 +341,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph * expanded state after that. This makes it possible for the user to * close auto-expanded nodes. */ - Map autoExpanded = new WeakHashMap(); + Map autoExpanded = new WeakHashMap<>(); @Override @@ -482,7 +464,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph GraphExplorerContext explorerContext = new GraphExplorerContext(); - HashSet pendingItems = new HashSet(); + HashSet pendingItems = new HashSet<>(); boolean updating = false; boolean pendingRoot = false; @@ -503,14 +485,14 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph * Access this map only in the SWT thread to keep it thread-safe. *

*/ - BijectionMap contextToItem = new BijectionMap(); + BijectionMap contextToItem = new BijectionMap<>(); /** * Columns of the UI viewer. Use {@link #setColumns(Column[])} to * initialize. */ Column[] columns = new Column[0]; - Map columnKeyToIndex = new HashMap(); + Map columnKeyToIndex = new HashMap<>(); boolean refreshingColumnSizes = false; boolean columnsAreVisible = true; @@ -537,12 +519,12 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph /** Set to true when the Tree widget is disposed. */ private boolean disposed = false; - private final CopyOnWriteArrayList focusListeners = new CopyOnWriteArrayList(); - private final CopyOnWriteArrayList mouseListeners = new CopyOnWriteArrayList(); - private final CopyOnWriteArrayList keyListeners = new CopyOnWriteArrayList(); + private final CopyOnWriteArrayList focusListeners = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList mouseListeners = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList keyListeners = new CopyOnWriteArrayList<>(); /** Selection provider */ - private GraphExplorerPostSelectionProvider postSelectionProvider = new GraphExplorerPostSelectionProvider(this); + private GraphExplorerPostSelectionProvider postSelectionProvider = new GraphExplorerPostSelectionProvider(this); protected BasePostSelectionProvider selectionProvider = new BasePostSelectionProvider(); protected SelectionDataResolver selectionDataResolver; protected SelectionFilter selectionFilter; @@ -570,12 +552,12 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph * item was a part of the current selection in which case the selection must * be updated. */ - private final Map selectedItems = new HashMap(); + private final Map selectedItems = new HashMap<>(); /** * TODO: specify what this is for */ - private final Set selectionRefreshContexts = new HashSet(); + private final Set selectionRefreshContexts = new HashSet<>(); /** * If this field is non-null, it means that if {@link #setData(Event)} @@ -649,7 +631,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph * * @see #setPendingImages(IProgressMonitor) */ - Map imageTasks = new THashMap(); + Map imageTasks = new THashMap<>(); /** * A state flag indicating whether the vertical scroll bar was visible for @@ -713,7 +695,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph updateCounter = 0; uiUpdateScheduler.schedule(this, 50, TimeUnit.MILLISECONDS); } else { - tree.getDisplay().asyncExec(new UpdateRunner(GraphExplorerImpl.this, GraphExplorerImpl.this.explorerContext)); + tree.getDisplay().asyncExec(new UpdateRunner(GraphExplorerImpl.this)); } } @@ -788,7 +770,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph * modified. These are used internally to prevent duplicate edits from being * initiated which should always be a sensible thing to do. */ - private Set currentlyModifiedNodes = new THashSet(); + private Set currentlyModifiedNodes = new THashSet<>(); private final TreeEditor editor; private Color invalidModificationColor = null; @@ -1381,17 +1363,14 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph // Keep track of the previous single selection to help // decide whether to start editing a tree node on mouse // downs or not. - tree.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - TreeItem[] selection = tree.getSelection(); - if (selection.length == 1) { - //for (TreeItem item : selection) - // System.out.println("selection: " + item); - previousSingleSelection = selection[0]; - } else { - previousSingleSelection = null; - } + tree.addListener(SWT.Selection, event -> { + TreeItem[] selection = tree.getSelection(); + if (selection.length == 1) { + //for (TreeItem item : selection) + // System.out.println("selection: " + item); + previousSingleSelection = selection[0]; + } else { + previousSingleSelection = null; } }); @@ -1493,39 +1472,33 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph }; tree.addListener(SWT.MouseDown, mouseEditListener); tree.addListener(SWT.DragDetect, mouseEditListener); - tree.addListener(SWT.DragDetect, new Listener() { - @Override - public void handleEvent(Event event) { - Point test = new Point(event.x, event.y); - TreeItem item = tree.getItem(test); - if(item != null) { - for(int i=0;i { + Point test = new Point(event.x, event.y); + TreeItem item = tree.getItem(test); + if(item != null) { + for(int i=0;i { + Point test = new Point(event.x, event.y); + TreeItem item = tree.getItem(test); + if(item != null) { + for(int i=0;i { + //System.out.println("OPENSTRATEGY: post selection changed: " + e); + resetSelection(); + selectionProvider.firePostSelection(selectionProvider.getSelection()); + })); // This listener takes care of updating the set of currently selected // TreeItem instances. This set is needed because we need to know in @@ -1611,108 +1578,14 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph }); } - /** - * Mod count for delaying post selection changed events. - */ - int postSelectionModCount = 0; - - /** - * Last tree selection modification time for implementing a quiet - * time for selection changes. - */ - long lastSelectionModTime = System.currentTimeMillis() - 10000; - - /** - * Current target time for the selection to be set. Calculated - * according to the set quiet time and last selection modification - * time. - */ - long selectionSetTargetTime = 0; - - /** - * true if delayed selection runnable is current scheduled or - * running. - */ - boolean delayedSelectionScheduled = false; - - Runnable SELECTION_DELAY = new Runnable() { - @Override - public void run() { - if (tree.isDisposed()) - return; - long now = System.currentTimeMillis(); - long waitTimeLeft = selectionSetTargetTime - now; - if (waitTimeLeft > 0) { - // Not enough quiet time, reschedule. - delayedSelectionScheduled = true; - tree.getDisplay().timerExec((int) waitTimeLeft, this); - } else { - // Time to perform selection, stop rescheduling. - delayedSelectionScheduled = false; - resetSelection(); - } - } - }; - - private void widgetSelectionChanged(boolean forceSelectionChange) { - long modTime = System.currentTimeMillis(); - long delta = modTime - lastSelectionModTime; - lastSelectionModTime = modTime; - if (!forceSelectionChange && delta < SELECTION_CHANGE_QUIET_TIME) { - long msToWait = SELECTION_CHANGE_QUIET_TIME - delta; - selectionSetTargetTime = modTime + msToWait; - if (!delayedSelectionScheduled) { - delayedSelectionScheduled = true; - tree.getDisplay().timerExec((int) msToWait, SELECTION_DELAY); - } - // Make sure that post selection change events do not fire. - ++postSelectionModCount; - return; - } - - // Immediate selection reconstruction. - resetSelection(); - } - private void resetSelection() { final ISelection selection = getWidgetSelection(); - - //System.out.println("resetSelection(" + postSelectionModCount + ")"); - //System.out.println(" provider selection: " + selectionProvider.getSelection()); - //System.out.println(" widget selection: " + selection); - +// System.out.println("resetSelection()"); +// System.out.println(" provider selection: " + selectionProvider.getSelection()); +// System.out.println(" widget selection: " + selection); selectionProvider.setAndFireNonEqualSelection(selection); - - // Implement deferred firing of post selection events - final int count = ++postSelectionModCount; - //System.out.println("[" + System.currentTimeMillis() + "] scheduling postSelectionChanged " + count + ": " + selection); - ThreadUtils.getNonBlockingWorkExecutor().schedule(new Runnable() { - @Override - public void run() { - int newCount = postSelectionModCount; - // Don't publish selection yet, there's another change incoming. - //System.out.println("[" + System.currentTimeMillis() + "] checking post selection publish: " + count + " vs. " + newCount + ": " + selection); - if (newCount != count) - return; - //System.out.println("[" + System.currentTimeMillis() + "] " + count + " count equals, firing post selection listeners: " + selection); - - if (tree.isDisposed()) - return; - - //System.out.println("scheduling fire post selection changed: " + selection); - tree.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - if (tree.isDisposed() || selectionProvider == null) - return; - //System.out.println("firing post selection changed: " + selection); - selectionProvider.firePostSelection(selection); - } - }); - } - }, POST_SELECTION_DELAY, TimeUnit.MILLISECONDS); } - + protected void setDefaultProcessors() { // Add a simple IMAGER query processor that always returns null. // With this processor no images will ever be shown. @@ -2427,7 +2300,7 @@ class GraphExplorerImpl extends GraphExplorerImplBase implements Listener, Graph // System.out.println("MODCOUNT: " + modCount + " vs. " + count); if (modCount != count) return; - widgetSelectionChanged(true); + resetSelection(); } }); }