Search in sources :

Example 1 with PathAnnotationObject

use of qupath.lib.objects.PathAnnotationObject in project qupath by qupath.

the class QuPathGUI method setViewerPopupMenu.

private void setViewerPopupMenu(final QuPathViewerPlus viewer) {
    final ContextMenu popup = new ContextMenu();
    MenuItem miAddRow = new MenuItem("Add row");
    miAddRow.setOnAction(e -> viewerManager.addRow(viewer));
    MenuItem miAddColumn = new MenuItem("Add column");
    miAddColumn.setOnAction(e -> viewerManager.addColumn(viewer));
    MenuItem miRemoveRow = new MenuItem("Remove row");
    miRemoveRow.setOnAction(e -> viewerManager.removeViewerRow(viewer));
    MenuItem miRemoveColumn = new MenuItem("Remove column");
    miRemoveColumn.setOnAction(e -> viewerManager.removeViewerColumn(viewer));
    MenuItem miCloseViewer = new MenuItem("Close viewer");
    miCloseViewer.setOnAction(e -> {
        viewerManager.closeViewer(viewer);
    // viewerManager.removeViewer(viewer);
    });
    MenuItem miResizeGrid = new MenuItem("Reset grid size");
    miResizeGrid.setOnAction(e -> {
        viewerManager.resetGridSize();
    });
    MenuItem miToggleSync = ActionTools.createCheckMenuItem(defaultActions.TOGGLE_SYNCHRONIZE_VIEWERS, null);
    MenuItem miMatchResolutions = ActionTools.createMenuItem(defaultActions.MATCH_VIEWER_RESOLUTIONS);
    Menu menuMultiview = MenuTools.createMenu("Multi-view", miToggleSync, miMatchResolutions, miCloseViewer, null, miResizeGrid, null, // null,
    miAddRow, miAddColumn, null, miRemoveRow, miRemoveColumn);
    Menu menuView = MenuTools.createMenu("Display", ActionTools.createCheckMenuItem(defaultActions.SHOW_ANALYSIS_PANE, null), defaultActions.BRIGHTNESS_CONTRAST, null, ActionTools.createAction(() -> Commands.setViewerDownsample(viewer, 0.25), "400%"), ActionTools.createAction(() -> Commands.setViewerDownsample(viewer, 1), "100%"), ActionTools.createAction(() -> Commands.setViewerDownsample(viewer, 2), "50%"), ActionTools.createAction(() -> Commands.setViewerDownsample(viewer, 10), "10%"), ActionTools.createAction(() -> Commands.setViewerDownsample(viewer, 100), "1%"));
    ToggleGroup groupTools = new ToggleGroup();
    Menu menuTools = MenuTools.createMenu("Set tool", ActionTools.createCheckMenuItem(defaultActions.MOVE_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.RECTANGLE_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.ELLIPSE_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.LINE_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.POLYGON_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.POLYLINE_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.BRUSH_TOOL, groupTools), ActionTools.createCheckMenuItem(defaultActions.POINTS_TOOL, groupTools), null, ActionTools.createCheckMenuItem(defaultActions.SELECTION_MODE));
    // Handle awkward 'TMA core missing' option
    CheckMenuItem miTMAValid = new CheckMenuItem("Set core valid");
    miTMAValid.setOnAction(e -> setTMACoreMissing(viewer.getHierarchy(), false));
    CheckMenuItem miTMAMissing = new CheckMenuItem("Set core missing");
    miTMAMissing.setOnAction(e -> setTMACoreMissing(viewer.getHierarchy(), true));
    Menu menuTMA = new Menu("TMA");
    MenuTools.addMenuItems(menuTMA, miTMAValid, miTMAMissing, null, defaultActions.TMA_ADD_NOTE, null, MenuTools.createMenu("Add", createImageDataAction(imageData -> TMACommands.promptToAddRowBeforeSelected(imageData), "Add TMA row before"), createImageDataAction(imageData -> TMACommands.promptToAddRowAfterSelected(imageData), "Add TMA row after"), createImageDataAction(imageData -> TMACommands.promptToAddColumnBeforeSelected(imageData), "Add TMA column before"), createImageDataAction(imageData -> TMACommands.promptToAddColumnAfterSelected(imageData), "Add TMA column after")), MenuTools.createMenu("Remove", createImageDataAction(imageData -> TMACommands.promptToDeleteTMAGridRow(imageData), "Remove TMA row"), createImageDataAction(imageData -> TMACommands.promptToDeleteTMAGridColumn(imageData), "column")));
    // Create an empty placeholder menu
    Menu menuSetClass = MenuTools.createMenu("Set class");
    // CheckMenuItem miTMAValid = new CheckMenuItem("Set core valid");
    // miTMAValid.setOnAction(e -> setTMACoreMissing(viewer.getHierarchy(), false));
    // CheckMenuItem miTMAMissing = new CheckMenuItem("Set core missing");
    // miTMAMissing.setOnAction(e -> setTMACoreMissing(viewer.getHierarchy(), true));
    Menu menuCells = MenuTools.createMenu("Cells", ActionTools.createCheckMenuItem(defaultActions.SHOW_CELL_BOUNDARIES_AND_NUCLEI, null), ActionTools.createCheckMenuItem(defaultActions.SHOW_CELL_NUCLEI, null), ActionTools.createCheckMenuItem(defaultActions.SHOW_CELL_BOUNDARIES, null), ActionTools.createCheckMenuItem(defaultActions.SHOW_CELL_CENTROIDS, null));
    MenuItem miClearSelectedObjects = new MenuItem("Delete object");
    miClearSelectedObjects.setOnAction(e -> {
        PathObjectHierarchy hierarchy = viewer.getHierarchy();
        if (hierarchy == null)
            return;
        if (hierarchy.getSelectionModel().singleSelection()) {
            GuiTools.promptToRemoveSelectedObject(hierarchy.getSelectionModel().getSelectedObject(), hierarchy);
        } else {
            GuiTools.promptToClearAllSelectedObjects(viewer.getImageData());
        }
    });
    // Create a standard annotations menu
    Menu menuAnnotations = GuiTools.populateAnnotationsMenu(this, new Menu("Annotations"));
    SeparatorMenuItem topSeparator = new SeparatorMenuItem();
    popup.setOnShowing(e -> {
        // Check if we have any cells
        ImageData<?> imageData = viewer.getImageData();
        if (imageData == null)
            menuCells.setVisible(false);
        else
            menuCells.setVisible(!imageData.getHierarchy().getDetectionObjects().isEmpty());
        // Check what to show for TMA cores or annotations
        Collection<PathObject> selectedObjects = viewer.getAllSelectedObjects();
        PathObject pathObject = viewer.getSelectedObject();
        menuTMA.setVisible(false);
        if (pathObject instanceof TMACoreObject) {
            boolean isMissing = ((TMACoreObject) pathObject).isMissing();
            miTMAValid.setSelected(!isMissing);
            miTMAMissing.setSelected(isMissing);
            menuTMA.setVisible(true);
        }
        // Add clear objects option if we have more than one non-TMA object
        if (imageData == null || imageData.getHierarchy().getSelectionModel().noSelection() || imageData.getHierarchy().getSelectionModel().getSelectedObject() instanceof TMACoreObject)
            miClearSelectedObjects.setVisible(false);
        else {
            if (imageData.getHierarchy().getSelectionModel().singleSelection()) {
                miClearSelectedObjects.setText("Delete object");
                miClearSelectedObjects.setVisible(true);
            } else {
                miClearSelectedObjects.setText("Delete objects");
                miClearSelectedObjects.setVisible(true);
            }
        }
        boolean hasAnnotations = pathObject instanceof PathAnnotationObject || (!selectedObjects.isEmpty() && selectedObjects.stream().allMatch(p -> p.isAnnotation()));
        updateSetAnnotationPathClassMenu(menuSetClass, viewer);
        menuAnnotations.setVisible(hasAnnotations);
        topSeparator.setVisible(hasAnnotations || pathObject instanceof TMACoreObject);
        // Occasionally, the newly-visible top part of a popup menu can have the wrong size?
        popup.setWidth(popup.getPrefWidth());
    });
    // popup.add(menuClassify);
    popup.getItems().addAll(miClearSelectedObjects, menuTMA, menuSetClass, menuAnnotations, topSeparator, menuMultiview, menuCells, menuView, menuTools);
    popup.setAutoHide(true);
    // Enable circle pop-up for quick classification on right-click
    CirclePopupMenu circlePopup = new CirclePopupMenu(viewer.getView(), null);
    viewer.getView().addEventHandler(MouseEvent.MOUSE_PRESSED, e -> {
        if ((e.isPopupTrigger() || e.isSecondaryButtonDown()) && e.isShiftDown() && !getAvailablePathClasses().isEmpty()) {
            circlePopup.setAnimationDuration(Duration.millis(200));
            updateSetAnnotationPathClassMenu(circlePopup, viewer);
            circlePopup.show(e.getScreenX(), e.getScreenY());
            e.consume();
            return;
        } else if (circlePopup.isShown())
            circlePopup.hide();
        if (e.isPopupTrigger() || e.isSecondaryButtonDown()) {
            popup.show(viewer.getView().getScene().getWindow(), e.getScreenX(), e.getScreenY());
            e.consume();
        }
    });
// // It's necessary to make the Window the owner, since otherwise the context menu does not disappear when clicking elsewhere on the viewer
// viewer.getView().setOnContextMenuRequested(e -> {
// popup.show(viewer.getView().getScene().getWindow(), e.getScreenX(), e.getScreenY());
// //			popup.show(viewer.getView(), e.getScreenX(), e.getScreenY());
// });
}
Also used : Change(javafx.collections.ListChangeListener.Change) PathObjectHierarchyView(qupath.lib.gui.panes.PathObjectHierarchyView) SelectedMeasurementTableView(qupath.lib.gui.panes.SelectedMeasurementTableView) Version(qupath.lib.common.Version) ProjectBrowser(qupath.lib.gui.panes.ProjectBrowser) ListChangeListener(javafx.collections.ListChangeListener) Map(java.util.Map) Path(java.nio.file.Path) ReleaseVersion(qupath.lib.gui.extensions.UpdateChecker.ReleaseVersion) Rectangle2D(javafx.geometry.Rectangle2D) PathObjects(qupath.lib.objects.PathObjects) Rectangle(javafx.scene.shape.Rectangle) BooleanProperty(javafx.beans.property.BooleanProperty) Project(qupath.lib.projects.Project) ObservableList(javafx.collections.ObservableList) Divider(javafx.scene.control.SplitPane.Divider) QuPathExtension(qupath.lib.gui.extensions.QuPathExtension) ByteArrayOutputStream(java.io.ByteArrayOutputStream) FXCollections(javafx.collections.FXCollections) PathIcons(qupath.lib.gui.tools.IconFactory.PathIcons) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) Bindings(javafx.beans.binding.Bindings) LinkedHashMap(java.util.LinkedHashMap) TreeTableView(javafx.scene.control.TreeTableView) PreferencePane(qupath.lib.gui.panes.PreferencePane) Commands(qupath.lib.gui.commands.Commands) QuPathStyleManager(qupath.lib.gui.prefs.QuPathStyleManager) IOException(java.io.IOException) OverlayOptions(qupath.lib.gui.viewer.OverlayOptions) Preferences(java.util.prefs.Preferences) ROI(qupath.lib.roi.interfaces.ROI) PathTools(qupath.lib.gui.viewer.tools.PathTools) ParameterPanelFX(qupath.lib.gui.dialogs.ParameterPanelFX) DragDropImportListener(qupath.lib.gui.viewer.DragDropImportListener) ImageView(javafx.scene.image.ImageView) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) Image(javafx.scene.image.Image) PathIO(qupath.lib.io.PathIO) EventHandler(javafx.event.EventHandler) ImageServer(qupath.lib.images.servers.ImageServer) BooleanBinding(javafx.beans.binding.BooleanBinding) TextInputControl(javafx.scene.control.TextInputControl) URLDecoder(java.net.URLDecoder) UncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) Date(java.util.Date) URISyntaxException(java.net.URISyntaxException) ObjectInputStream(java.io.ObjectInputStream) KeyCombination(javafx.scene.input.KeyCombination) DefaultImageRegionStore(qupath.lib.gui.images.stores.DefaultImageRegionStore) ByteArrayInputStream(java.io.ByteArrayInputStream) Locale(java.util.Locale) GitHubProject(qupath.lib.gui.extensions.GitHubProject) ImageIO(javax.imageio.ImageIO) RotateEvent(javafx.scene.input.RotateEvent) WindowEvent(javafx.stage.WindowEvent) PathInteractivePlugin(qupath.lib.plugins.PathInteractivePlugin) Orientation(javafx.geometry.Orientation) MenuItem(javafx.scene.control.MenuItem) Ellipse(javafx.scene.shape.Ellipse) ImageServerProvider(qupath.lib.images.servers.ImageServerProvider) Collection(java.util.Collection) Font(javafx.scene.text.Font) ServiceLoader(java.util.ServiceLoader) Collectors(java.util.stream.Collectors) BorderStroke(javafx.scene.layout.BorderStroke) PathObject(qupath.lib.objects.PathObject) Objects(java.util.Objects) ImageTypeSetting(qupath.lib.gui.prefs.PathPrefs.ImageTypeSetting) ProjectIO(qupath.lib.projects.ProjectIO) GuiTools(qupath.lib.gui.tools.GuiTools) ExecutorCompletionService(java.util.concurrent.ExecutorCompletionService) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) ReadOnlyObjectProperty(javafx.beans.property.ReadOnlyObjectProperty) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) Action(org.controlsfx.control.action.Action) PathClassFactory(qupath.lib.objects.classes.PathClassFactory) ScriptEditor(qupath.lib.gui.scripting.ScriptEditor) TableColumn(javafx.scene.control.TableColumn) HashSet(java.util.HashSet) Insets(javafx.geometry.Insets) DetectionDisplayMode(qupath.lib.gui.viewer.OverlayOptions.DetectionDisplayMode) ExecutorService(java.util.concurrent.ExecutorService) KeyCode(javafx.scene.input.KeyCode) ActionAccelerator(qupath.lib.gui.ActionTools.ActionAccelerator) Logger(org.slf4j.Logger) Dialog(javafx.scene.control.Dialog) Label(javafx.scene.control.Label) MenuBar(javafx.scene.control.MenuBar) ActionIcon(qupath.lib.gui.ActionTools.ActionIcon) ServerBuilder(qupath.lib.images.servers.ImageServerBuilder.ServerBuilder) ScrollEvent(javafx.scene.input.ScrollEvent) Consumer(java.util.function.Consumer) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) Stage(javafx.stage.Stage) ViewerPlusDisplayOptions(qupath.lib.gui.viewer.ViewerPlusDisplayOptions) Comparator(java.util.Comparator) PathTool(qupath.lib.gui.viewer.tools.PathTool) Arrays(java.util.Arrays) ServerTools(qupath.lib.images.servers.ServerTools) ActionUtils(org.controlsfx.control.action.ActionUtils) ActionDescription(qupath.lib.gui.ActionTools.ActionDescription) ReadOnlyBooleanProperty(javafx.beans.property.ReadOnlyBooleanProperty) StackPane(javafx.scene.layout.StackPane) AnnotationPane(qupath.lib.gui.panes.AnnotationPane) JFXPanel(javafx.embed.swing.JFXPanel) Category(java.util.Locale.Category) ParameterList(qupath.lib.plugins.parameters.ParameterList) TabPane(javafx.scene.control.TabPane) ScriptException(javax.script.ScriptException) CountingPanelCommand(qupath.lib.gui.commands.CountingPanelCommand) SplitPane(javafx.scene.control.SplitPane) Border(javafx.scene.layout.Border) Event(javafx.event.Event) Set(java.util.Set) KeyEvent(javafx.scene.input.KeyEvent) Screen(javafx.stage.Screen) AffineTransform(java.awt.geom.AffineTransform) QuPathViewerListener(qupath.lib.gui.viewer.QuPathViewerListener) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Platform(javafx.application.Platform) Region(javafx.scene.layout.Region) CommandFinderTools(qupath.lib.gui.tools.CommandFinderTools) InputDisplayCommand(qupath.lib.gui.commands.InputDisplayCommand) ImageRegionStoreFactory(qupath.lib.gui.images.stores.ImageRegionStoreFactory) ThreadTools(qupath.lib.common.ThreadTools) DefaultScriptEditor(qupath.lib.gui.scripting.DefaultScriptEditor) GitHubRepo(qupath.lib.gui.extensions.GitHubProject.GitHubRepo) BorderPane(javafx.scene.layout.BorderPane) ButtonData(javafx.scene.control.ButtonBar.ButtonData) SimpleDateFormat(java.text.SimpleDateFormat) PathPlugin(qupath.lib.plugins.PathPlugin) Projects(qupath.lib.projects.Projects) StandardCopyOption(java.nio.file.StandardCopyOption) ArrayList(java.util.ArrayList) TabClosingPolicy(javafx.scene.control.TabPane.TabClosingPolicy) QuPathViewerPlus(qupath.lib.gui.viewer.QuPathViewerPlus) ObjectOutputStream(java.io.ObjectOutputStream) LinkedHashSet(java.util.LinkedHashSet) Color(javafx.scene.paint.Color) CirclePopupMenu(jfxtras.scene.menu.CirclePopupMenu) TitledPane(javafx.scene.control.TitledPane) Files(java.nio.file.Files) ToolBar(javafx.scene.control.ToolBar) GeneralTools(qupath.lib.common.GeneralTools) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) ProjectCommands(qupath.lib.gui.commands.ProjectCommands) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Menu(javafx.scene.control.Menu) Cursor(javafx.scene.Cursor) KeyCodeCombination(javafx.scene.input.KeyCodeCombination) Paths(java.nio.file.Paths) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) Tab(javafx.scene.control.Tab) PathPrefs(qupath.lib.gui.prefs.PathPrefs) StringBinding(javafx.beans.binding.StringBinding) Pos(javafx.geometry.Pos) Area(java.awt.geom.Area) CheckMenuItem(javafx.scene.control.CheckMenuItem) LoggerFactory(org.slf4j.LoggerFactory) UpdateChecker(qupath.lib.gui.extensions.UpdateChecker) Parent(javafx.scene.Parent) ContextMenu(javafx.scene.control.ContextMenu) URI(java.net.URI) ImageServers(qupath.lib.images.servers.ImageServers) TableView(javafx.scene.control.TableView) ImageType(qupath.lib.images.ImageData.ImageType) Shape(java.awt.Shape) BufferedImage(java.awt.image.BufferedImage) GroovyLanguage(qupath.lib.gui.scripting.languages.GroovyLanguage) ImageServerBuilder(qupath.lib.images.servers.ImageServerBuilder) FileNotFoundException(java.io.FileNotFoundException) TreeView(javafx.scene.control.TreeView) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) List(java.util.List) Duration(javafx.util.Duration) ColorToolsFX(qupath.lib.gui.tools.ColorToolsFX) Optional(java.util.Optional) LogManager(qupath.lib.gui.logging.LogManager) RadioMenuItem(javafx.scene.control.RadioMenuItem) WorkflowCommandLogView(qupath.lib.gui.panes.WorkflowCommandLogView) TextArea(javafx.scene.control.TextArea) ButtonType(javafx.scene.control.ButtonType) MouseEvent(javafx.scene.input.MouseEvent) HashMap(java.util.HashMap) BrightnessContrastCommand(qupath.lib.gui.commands.BrightnessContrastCommand) UriImageSupport(qupath.lib.images.servers.ImageServerBuilder.UriImageSupport) Dialogs(qupath.lib.gui.dialogs.Dialogs) SwingUtilities(javax.swing.SwingUtilities) HostServices(javafx.application.HostServices) ZoomEvent(javafx.scene.input.ZoomEvent) TMACommands(qupath.lib.gui.commands.TMACommands) Tooltip(javafx.scene.control.Tooltip) ImageDetailsPane(qupath.lib.gui.panes.ImageDetailsPane) ImageData(qupath.lib.images.ImageData) Desktop(java.awt.Desktop) RoiTools(qupath.lib.roi.RoiTools) ObjectProperty(javafx.beans.property.ObjectProperty) Iterator(java.util.Iterator) ProjectImageEntry(qupath.lib.projects.ProjectImageEntry) TableRow(javafx.scene.control.TableRow) PathClass(qupath.lib.objects.classes.PathClass) TMACoreObject(qupath.lib.objects.TMACoreObject) DropShadow(javafx.scene.effect.DropShadow) MenuTools(qupath.lib.gui.tools.MenuTools) BorderStrokeStyle(javafx.scene.layout.BorderStrokeStyle) ActionEvent(javafx.event.ActionEvent) ToggleGroup(javafx.scene.control.ToggleGroup) LogViewerCommand(qupath.lib.gui.commands.LogViewerCommand) SwingFXUtils(javafx.embed.swing.SwingFXUtils) Collections(java.util.Collections) InputStream(java.io.InputStream) DialogButton(qupath.lib.gui.dialogs.Dialogs.DialogButton) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) CirclePopupMenu(jfxtras.scene.menu.CirclePopupMenu) TMACoreObject(qupath.lib.objects.TMACoreObject) ContextMenu(javafx.scene.control.ContextMenu) MenuItem(javafx.scene.control.MenuItem) CheckMenuItem(javafx.scene.control.CheckMenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) RadioMenuItem(javafx.scene.control.RadioMenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) CheckMenuItem(javafx.scene.control.CheckMenuItem) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) ToggleGroup(javafx.scene.control.ToggleGroup) CirclePopupMenu(jfxtras.scene.menu.CirclePopupMenu) Menu(javafx.scene.control.Menu) ContextMenu(javafx.scene.control.ContextMenu)

Example 2 with PathAnnotationObject

use of qupath.lib.objects.PathAnnotationObject in project qupath by qupath.

the class GuiTools method promptToSetActiveAnnotationProperties.

/**
 * Prompt the user to set properties for the currently-selected annotation(s).
 *
 * @param hierarchy current hierarchy
 * @return true if changes to annotation properties were made, false otherwise.
 */
public static boolean promptToSetActiveAnnotationProperties(final PathObjectHierarchy hierarchy) {
    PathObject currentObject = hierarchy.getSelectionModel().getSelectedObject();
    if (currentObject == null || !currentObject.isAnnotation())
        return false;
    ROI roi = currentObject.getROI();
    if (roi == null)
        return false;
    Collection<PathAnnotationObject> otherAnnotations = hierarchy.getSelectionModel().getSelectedObjects().stream().filter(p -> p.isAnnotation() && p != currentObject).map(p -> (PathAnnotationObject) p).collect(Collectors.toList());
    if (promptToSetAnnotationProperties((PathAnnotationObject) currentObject, otherAnnotations)) {
        hierarchy.fireObjectsChangedEvent(null, Collections.singleton(currentObject));
        // Ensure the object is still selected
        hierarchy.getSelectionModel().setSelectedObject(currentObject);
        return true;
    }
    return false;
}
Also used : CheckComboBox(org.controlsfx.control.CheckComboBox) UnaryOperator(java.util.function.UnaryOperator) TextFormatter(javafx.scene.control.TextFormatter) PathRootObject(qupath.lib.objects.PathRootObject) ParameterList(qupath.lib.plugins.parameters.ParameterList) PointsROI(qupath.lib.roi.PointsROI) Matcher(java.util.regex.Matcher) Action(java.awt.Desktop.Action) ColorTools(qupath.lib.common.ColorTools) GraphicsContext(javafx.scene.canvas.GraphicsContext) Canvas(javafx.scene.canvas.Canvas) Screen(javafx.stage.Screen) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Platform(javafx.application.Platform) CountDownLatch(java.util.concurrent.CountDownLatch) Transparency(java.awt.Transparency) Clipboard(javafx.scene.input.Clipboard) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) StringProperty(javafx.beans.property.StringProperty) Callable(java.util.concurrent.Callable) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) DefaultColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains.DefaultColorDeconvolutionStains) Bindings(javafx.beans.binding.Bindings) NumberFormat(java.text.NumberFormat) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Slider(javafx.scene.control.Slider) SplitAnnotationsPlugin(qupath.lib.plugins.objects.SplitAnnotationsPlugin) GridPane(javafx.scene.layout.GridPane) Color(javafx.scene.paint.Color) GeneralTools(qupath.lib.common.GeneralTools) Commands(qupath.lib.gui.commands.Commands) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) IOException(java.io.IOException) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Menu(javafx.scene.control.Menu) ROI(qupath.lib.roi.interfaces.ROI) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) ObservableValue(javafx.beans.value.ObservableValue) Image(javafx.scene.image.Image) Button(javafx.scene.control.Button) ImageServer(qupath.lib.images.servers.ImageServer) CombineOp(qupath.lib.roi.RoiTools.CombineOp) DoubleBinding(javafx.beans.binding.DoubleBinding) ListCell(javafx.scene.control.ListCell) CheckMenuItem(javafx.scene.control.CheckMenuItem) LoggerFactory(org.slf4j.LoggerFactory) RenderingHints(java.awt.RenderingHints) Side(javafx.geometry.Side) ContextMenu(javafx.scene.control.ContextMenu) URI(java.net.URI) QuPathGUI(qupath.lib.gui.QuPathGUI) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Spinner(javafx.scene.control.Spinner) Collectors(java.util.stream.Collectors) StainVector(qupath.lib.color.StainVector) PathObject(qupath.lib.objects.PathObject) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) List(java.util.List) Robot(javafx.scene.robot.Robot) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) Pattern(java.util.regex.Pattern) ClipboardContent(javafx.scene.input.ClipboardContent) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) TextArea(javafx.scene.control.TextArea) ParsePosition(java.text.ParsePosition) DoubleProperty(javafx.beans.property.DoubleProperty) ColorDeconvolutionHelper(qupath.lib.color.ColorDeconvolutionHelper) Function(java.util.function.Function) Dialogs(qupath.lib.gui.dialogs.Dialogs) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) SwingUtilities(javax.swing.SwingUtilities) Graphics2D(java.awt.Graphics2D) ActionTools(qupath.lib.gui.ActionTools) Tooltip(javafx.scene.control.Tooltip) ColorPicker(javafx.scene.control.ColorPicker) ImageData(qupath.lib.images.ImageData) Desktop(java.awt.Desktop) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) WritableImage(javafx.scene.image.WritableImage) TMACoreObject(qupath.lib.objects.TMACoreObject) DoubleSpinnerValueFactory(javafx.scene.control.SpinnerValueFactory.DoubleSpinnerValueFactory) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) Stage(javafx.stage.Stage) SpinnerValueFactory(javafx.scene.control.SpinnerValueFactory) SwingFXUtils(javafx.embed.swing.SwingFXUtils) Window(javafx.stage.Window) Collections(java.util.Collections) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) PointsROI(qupath.lib.roi.PointsROI) ROI(qupath.lib.roi.interfaces.ROI)

Example 3 with PathAnnotationObject

use of qupath.lib.objects.PathAnnotationObject in project qupath by qupath.

the class GuiTools method setSelectedAnnotationLock.

/**
 * Set selected TMA cores to have the specified 'locked' status.
 *
 * @param hierarchy
 * @param setToLocked
 */
private static void setSelectedAnnotationLock(final PathObjectHierarchy hierarchy, final boolean setToLocked) {
    if (hierarchy == null)
        return;
    PathObject pathObject = hierarchy.getSelectionModel().getSelectedObject();
    List<PathObject> changed = new ArrayList<>();
    if (pathObject instanceof PathAnnotationObject) {
        PathAnnotationObject annotation = (PathAnnotationObject) pathObject;
        annotation.setLocked(setToLocked);
        changed.add(annotation);
        // Update any other selected cores to have the same status
        for (PathObject pathObject2 : hierarchy.getSelectionModel().getSelectedObjects()) {
            if (pathObject2 instanceof PathAnnotationObject) {
                annotation = (PathAnnotationObject) pathObject2;
                if (annotation.isLocked() != setToLocked) {
                    annotation.setLocked(setToLocked);
                    changed.add(annotation);
                }
            }
        }
    }
    if (!changed.isEmpty())
        hierarchy.fireObjectsChangedEvent(GuiTools.class, changed);
}
Also used : PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList)

Example 4 with PathAnnotationObject

use of qupath.lib.objects.PathAnnotationObject in project qupath by qupath.

the class IJExtension method extractOverlay.

/**
 * Extract an ImageJ overlay for the specified region.
 * @param hierarchy
 * @param request
 * @param options options to control which objects are being displayed
 * @param filter optional additional filter used to determine which objects will be included (may be used in combination with options)
 * @return
 */
public static Overlay extractOverlay(PathObjectHierarchy hierarchy, RegionRequest request, OverlayOptions options, Predicate<PathObject> filter) {
    Overlay overlay = new Overlay();
    double downsample = request.getDownsample();
    double xOrigin = -request.getX() / downsample;
    double yOrigin = -request.getY() / downsample;
    // TODO: Permit filling/unfilling ROIs
    for (PathObject child : hierarchy.getObjectsForRegion(PathObject.class, request, null)) {
        if (filter != null && !filter.test(child))
            continue;
        if (child.hasROI()) {
            // Check if this is displayed - skip it not
            if (options != null && ((child instanceof PathDetectionObject && !options.getShowDetections()) || (child instanceof PathAnnotationObject && !options.getShowAnnotations()) || (child instanceof TMACoreObject && !options.getShowTMAGrid())))
                continue;
            boolean isCell = child instanceof PathCellObject;
            Color color = ColorToolsAwt.getCachedColor(ColorToolsFX.getDisplayedColorARGB(child));
            if (!(isCell && (options == null || !options.getShowCellBoundaries()))) {
                Roi roi = IJTools.convertToIJRoi(child.getROI(), xOrigin, yOrigin, downsample);
                roi.setStrokeColor(color);
                roi.setName(child.getDisplayedName());
                // roi.setStrokeWidth(2);
                overlay.add(roi);
            }
            if (isCell && (options == null || options.getShowCellNuclei())) {
                ROI nucleus = ((PathCellObject) child).getNucleusROI();
                if (nucleus == null)
                    continue;
                Roi roi = IJTools.convertToIJRoi(((PathCellObject) child).getNucleusROI(), xOrigin, yOrigin, downsample);
                roi.setStrokeColor(color);
                roi.setName(child.getDisplayedName() + " - nucleus");
                overlay.add(roi);
            }
        }
    }
    return overlay;
}
Also used : PathDetectionObject(qupath.lib.objects.PathDetectionObject) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) TMACoreObject(qupath.lib.objects.TMACoreObject) Color(java.awt.Color) Overlay(ij.gui.Overlay) Roi(ij.gui.Roi) ROI(qupath.lib.roi.interfaces.ROI) PathCellObject(qupath.lib.objects.PathCellObject)

Example 5 with PathAnnotationObject

use of qupath.lib.objects.PathAnnotationObject in project qupath by qupath.

the class AbstractPathROITool method commitObjectToHierarchy.

/**
 * When drawing an object is complete, add it to the hierarchy - or whatever else is required.
 *
 * @param e
 * @param pathObject
 */
void commitObjectToHierarchy(MouseEvent e, PathObject pathObject) {
    if (pathObject == null)
        return;
    var viewer = getViewer();
    PathObjectHierarchy hierarchy = viewer.getHierarchy();
    var currentROI = pathObject.getROI();
    // If we are in selection mode, try to get objects to select
    if (PathPrefs.selectionModeProperty().get()) {
        var pathClass = PathPrefs.autoSetAnnotationClassProperty().get();
        var toSelect = hierarchy.getObjectsForROI(null, currentROI);
        if (!toSelect.isEmpty() && pathClass != null) {
            boolean retainIntensityClass = !(PathClassTools.isPositiveOrGradedIntensityClass(pathClass) || PathClassTools.isNegativeClass(pathClass));
            var reclassified = toSelect.stream().filter(p -> p.getPathClass() != pathClass).map(p -> new Reclassifier(p, pathClass, retainIntensityClass)).filter(r -> r.apply()).map(r -> r.getPathObject()).collect(Collectors.toList());
            if (!reclassified.isEmpty()) {
                hierarchy.fireObjectClassificationsChangedEvent(this, reclassified);
            }
        }
        if (pathObject.getParent() != null)
            hierarchy.removeObject(pathObject, true);
        // viewer.getHierarchy().fireHierarchyChangedEvent(this);
        if (toSelect.isEmpty())
            viewer.setSelectedObject(null);
        else if (e.isShiftDown()) {
            hierarchy.getSelectionModel().deselectObject(pathObject);
            hierarchy.getSelectionModel().selectObjects(toSelect);
        } else
            hierarchy.getSelectionModel().setSelectedObjects(toSelect, null);
    } else {
        if (!requestParentClipping(e)) {
            if (currentROI.isEmpty()) {
                pathObject = null;
            } else
                // Ensure object is within the hierarchy
                hierarchy.addPathObject(pathObject);
        } else {
            ROI roiNew = refineROIByParent(pathObject.getROI());
            if (roiNew.isEmpty()) {
                hierarchy.removeObject(pathObject, true);
                pathObject = null;
            } else {
                ((PathAnnotationObject) pathObject).setROI(roiNew);
                hierarchy.addPathObjectBelowParent(getCurrentParent(), pathObject, true);
            }
        }
        if (pathObject != null)
            viewer.setSelectedObject(pathObject);
        else
            viewer.getHierarchy().getSelectionModel().clearSelection();
    }
    var editor = viewer.getROIEditor();
    editor.ensureHandlesUpdated();
    editor.resetActiveHandle();
    if (preferReturnToMove()) {
        var qupath = QuPathGUI.getInstance();
        if (qupath != null)
            qupath.setSelectedTool(PathTools.MOVE);
    }
}
Also used : Logger(org.slf4j.Logger) Point2D(java.awt.geom.Point2D) PathClassTools(qupath.lib.objects.classes.PathClassTools) MouseEvent(javafx.scene.input.MouseEvent) PathObjects(qupath.lib.objects.PathObjects) LoggerFactory(org.slf4j.LoggerFactory) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PolylineROI(qupath.lib.roi.PolylineROI) Collectors(java.util.stream.Collectors) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) Cursor(javafx.scene.Cursor) ROI(qupath.lib.roi.interfaces.ROI) RoiEditor(qupath.lib.roi.RoiEditor) ImagePlane(qupath.lib.regions.ImagePlane) Reclassifier(qupath.lib.objects.classes.Reclassifier) PolygonROI(qupath.lib.roi.PolygonROI) Collections(java.util.Collections) PathPrefs(qupath.lib.gui.prefs.PathPrefs) QuPathGUI(qupath.lib.gui.QuPathGUI) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PolylineROI(qupath.lib.roi.PolylineROI) ROI(qupath.lib.roi.interfaces.ROI) PolygonROI(qupath.lib.roi.PolygonROI) Reclassifier(qupath.lib.objects.classes.Reclassifier)

Aggregations

PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)19 PathObject (qupath.lib.objects.PathObject)16 ArrayList (java.util.ArrayList)11 ROI (qupath.lib.roi.interfaces.ROI)11 TMACoreObject (qupath.lib.objects.TMACoreObject)9 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)7 BufferedImage (java.awt.image.BufferedImage)6 List (java.util.List)6 TextArea (javafx.scene.control.TextArea)5 Tooltip (javafx.scene.control.Tooltip)5 IOException (java.io.IOException)4 Collections (java.util.Collections)4 Collectors (java.util.stream.Collectors)4 Point2D (java.awt.geom.Point2D)3 File (java.io.File)3 Collection (java.util.Collection)3 LinkedHashMap (java.util.LinkedHashMap)3 Bindings (javafx.beans.binding.Bindings)3 SimpleBooleanProperty (javafx.beans.property.SimpleBooleanProperty)3 Scene (javafx.scene.Scene)3