Search in sources :

Example 1 with PathObjectSelectionModel

use of qupath.lib.objects.hierarchy.events.PathObjectSelectionModel in project qupath by qupath.

the class PathObjectHierarchyView method synchronizeSelectionModelToTree.

/**
 * Ensure that the hierarchy selection model matches the selection within the TreeView.
 * @param change
 */
private void synchronizeSelectionModelToTree(final ListChangeListener.Change<? extends TreeItem<PathObject>> change) {
    if (synchronizingTreeToModel)
        return;
    PathObjectSelectionModel model = getHierarchySelectionModel();
    if (model == null) {
        return;
    }
    boolean wasSynchronizingToTree = synchronizingModelToTree;
    try {
        synchronizingModelToTree = true;
        // Check - was anything removed?
        boolean removed = false;
        if (change != null) {
            while (change.next()) removed = removed | change.wasRemoved();
        }
        MultipleSelectionModel<TreeItem<PathObject>> treeModel = treeView.getSelectionModel();
        List<TreeItem<PathObject>> selectedItems = treeModel.getSelectedItems();
        // If we just have no selected items, and something was removed, then clear the selection
        if (selectedItems.isEmpty() && removed) {
            model.clearSelection();
            return;
        }
        // if (selectedItems.size() == 1 && removed) {
        if (selectedItems.size() == 1) {
            model.setSelectedObject(selectedItems.get(0).getValue(), false);
            return;
        }
        // If we have multiple selected items, we need to ensure that everything in the tree matches with everything in the selection model
        Set<PathObject> toSelect = treeView.getSelectionModel().getSelectedItems().stream().map(t -> t.getValue()).collect(Collectors.toSet());
        TreeItem<PathObject> mainSelection = treeView.getSelectionModel().getSelectedItem();
        PathObject primary = mainSelection == null ? null : mainSelection.getValue();
        model.setSelectedObjects(toSelect, primary);
    } finally {
        synchronizingModelToTree = wasSynchronizingToTree;
    }
}
Also used : EventHandler(javafx.event.EventHandler) java.util(java.util) javafx.scene.control(javafx.scene.control) MouseEvent(javafx.scene.input.MouseEvent) BreadCrumbBar(org.controlsfx.control.BreadCrumbBar) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathRootObject(qupath.lib.objects.PathRootObject) ListChangeListener(javafx.collections.ListChangeListener) PathObjectHierarchyEvent(qupath.lib.objects.hierarchy.events.PathObjectHierarchyEvent) Callback(javafx.util.Callback) QuPathGUI(qupath.lib.gui.QuPathGUI) Pane(javafx.scene.layout.Pane) ImageData(qupath.lib.images.ImageData) ObjectProperty(javafx.beans.property.ObjectProperty) BufferedImage(java.awt.image.BufferedImage) IconFactory(qupath.lib.gui.tools.IconFactory) PathObjectSelectionListener(qupath.lib.objects.hierarchy.events.PathObjectSelectionListener) DefaultPathObjectComparator(qupath.lib.objects.DefaultPathObjectComparator) PathObjectSelectionModel(qupath.lib.objects.hierarchy.events.PathObjectSelectionModel) Collectors(java.util.stream.Collectors) PathObjectTools(qupath.lib.objects.PathObjectTools) PathObject(qupath.lib.objects.PathObject) Platform(javafx.application.Platform) BooleanProperty(javafx.beans.property.BooleanProperty) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) ObservableValue(javafx.beans.value.ObservableValue) PathObjectHierarchyListener(qupath.lib.objects.hierarchy.events.PathObjectHierarchyListener) ObservableList(javafx.collections.ObservableList) BorderPane(javafx.scene.layout.BorderPane) ChangeListener(javafx.beans.value.ChangeListener) PathPrefs(qupath.lib.gui.prefs.PathPrefs) PathObject(qupath.lib.objects.PathObject) PathObjectSelectionModel(qupath.lib.objects.hierarchy.events.PathObjectSelectionModel)

Example 2 with PathObjectSelectionModel

use of qupath.lib.objects.hierarchy.events.PathObjectSelectionModel in project qupath by qupath.

the class SummaryMeasurementTableCommand method synchronizeSelectionModelToTable.

private void synchronizeSelectionModelToTable(final PathObjectHierarchy hierarchy, final ListChangeListener.Change<? extends PathObject> change, final TableView<PathObject> table) {
    if (synchronizingTableToModel || hierarchy == null)
        return;
    PathObjectSelectionModel model = hierarchy.getSelectionModel();
    if (model == null) {
        return;
    }
    boolean wasSynchronizingToTree = synchronizingModelToTable;
    try {
        synchronizingModelToTable = true;
        // Check - was anything removed?
        boolean removed = false;
        if (change != null) {
            while (change.next()) removed = removed | change.wasRemoved();
        }
        MultipleSelectionModel<PathObject> treeModel = table.getSelectionModel();
        List<PathObject> selectedItems = treeModel.getSelectedItems();
        // If we just have no selected items, and something was removed, then clear the selection
        if (selectedItems.isEmpty() && removed) {
            model.clearSelection();
            return;
        }
        // if (selectedItems.size() == 1 && removed) {
        if (selectedItems.size() == 1) {
            model.setSelectedObject(selectedItems.get(0), false);
            return;
        }
        // If we have multiple selected items, we need to ensure that everything in the tree matches with everything in the selection model
        Set<PathObject> toSelect = new HashSet<>(treeModel.getSelectedItems());
        PathObject primary = treeModel.getSelectedItem();
        model.setSelectedObjects(toSelect, primary);
    } finally {
        synchronizingModelToTable = wasSynchronizingToTree;
    }
}
Also used : PathObject(qupath.lib.objects.PathObject) PathObjectSelectionModel(qupath.lib.objects.hierarchy.events.PathObjectSelectionModel) HashSet(java.util.HashSet)

Example 3 with PathObjectSelectionModel

use of qupath.lib.objects.hierarchy.events.PathObjectSelectionModel in project qupath by qupath.

the class CountingPane method setHierarchy.

public void setHierarchy(PathObjectHierarchy hierarchy) {
    if (this.hierarchy == hierarchy)
        return;
    if (this.hierarchy != null) {
        this.hierarchy.getSelectionModel().removePathObjectSelectionListener(this);
        this.hierarchy.removePathObjectListener(this);
    }
    this.hierarchy = hierarchy;
    PathObject objectSelected = null;
    if (this.hierarchy != null) {
        PathObjectSelectionModel model = this.hierarchy.getSelectionModel();
        model.addPathObjectSelectionListener(this);
        objectSelected = model.getSelectedObject();
        this.hierarchy.addPathObjectListener(this);
    }
    // Update selected object in list, if suitable
    if (objectSelected != null && PathObjectTools.hasPointROI(objectSelected))
        listCounts.getSelectionModel().select(objectSelected);
    else
        listCounts.getSelectionModel().clearSelection();
    // Force update
    hierarchyChanged(null);
}
Also used : PathObject(qupath.lib.objects.PathObject) PathObjectSelectionModel(qupath.lib.objects.hierarchy.events.PathObjectSelectionModel)

Example 4 with PathObjectSelectionModel

use of qupath.lib.objects.hierarchy.events.PathObjectSelectionModel in project qupath by qupath.

the class SummaryMeasurementTableCommand method synchronizeTableToSelectionModel.

private void synchronizeTableToSelectionModel(final PathObjectHierarchy hierarchy, final TableView<PathObject> table) {
    if (synchronizingModelToTable || hierarchy == null)
        return;
    boolean ownsChanges = !synchronizingTableToModel;
    try {
        synchronizingTableToModel = true;
        PathObjectSelectionModel model = hierarchy.getSelectionModel();
        TableViewSelectionModel<PathObject> tableModel = table.getSelectionModel();
        if (model == null || model.noSelection()) {
            tableModel.clearSelection();
            return;
        }
        if (model.singleSelection() || tableModel.getSelectionMode() == SelectionMode.SINGLE) {
            int ind = table.getItems().indexOf(model.getSelectedObject());
            if (ind >= 0) {
                tableModel.clearAndSelect(ind);
                table.scrollTo(ind);
            } else
                tableModel.clearSelection();
            return;
        }
        // Loop through all possible selections, and select them if they should be selected (and not if they shouldn't)
        // For performance reasons, we need to do this using arrays - otherwise way too many events may be fired
        int n = table.getItems().size();
        PathObject mainSelectedObject = model.getSelectedObject();
        int mainObjectInd = -1;
        int[] indsToSelect = new int[table.getItems().size()];
        int count = 0;
        for (int i = 0; i < n; i++) {
            PathObject temp = table.getItems().get(i);
            if (temp == mainSelectedObject)
                mainObjectInd = i;
            if (model.isSelected(temp)) {
                indsToSelect[count] = i;
                count++;
            }
        }
        tableModel.clearSelection();
        if (count > 0) {
            int maxCount = 1000;
            if (count > maxCount) {
                logger.warn("Only the first {} items will be selected in the table (out of {} total) - otherwise QuPath can grind to a halt, sorry", maxCount, count);
                count = maxCount;
            }
            tableModel.selectIndices(indsToSelect[0], Arrays.copyOfRange(indsToSelect, 1, count));
        }
        // Ensure that the main object is focussed & its node expanded
        if (mainObjectInd >= 0 && model.singleSelection()) {
            tableModel.select(mainObjectInd);
            table.scrollTo(mainObjectInd);
        }
    } finally {
        if (ownsChanges)
            synchronizingTableToModel = false;
    }
}
Also used : PathObject(qupath.lib.objects.PathObject) PathObjectSelectionModel(qupath.lib.objects.hierarchy.events.PathObjectSelectionModel)

Aggregations

PathObject (qupath.lib.objects.PathObject)4 PathObjectSelectionModel (qupath.lib.objects.hierarchy.events.PathObjectSelectionModel)4 BufferedImage (java.awt.image.BufferedImage)1 java.util (java.util)1 HashSet (java.util.HashSet)1 Collectors (java.util.stream.Collectors)1 Platform (javafx.application.Platform)1 BooleanProperty (javafx.beans.property.BooleanProperty)1 ObjectProperty (javafx.beans.property.ObjectProperty)1 SimpleBooleanProperty (javafx.beans.property.SimpleBooleanProperty)1 ChangeListener (javafx.beans.value.ChangeListener)1 ObservableValue (javafx.beans.value.ObservableValue)1 ListChangeListener (javafx.collections.ListChangeListener)1 ObservableList (javafx.collections.ObservableList)1 EventHandler (javafx.event.EventHandler)1 javafx.scene.control (javafx.scene.control)1 MouseEvent (javafx.scene.input.MouseEvent)1 BorderPane (javafx.scene.layout.BorderPane)1 Pane (javafx.scene.layout.Pane)1 Callback (javafx.util.Callback)1