diff --git a/nion/swift/DisplayCanvasItem.py b/nion/swift/DisplayCanvasItem.py index e1d0bc89..18a90640 100644 --- a/nion/swift/DisplayCanvasItem.py +++ b/nion/swift/DisplayCanvasItem.py @@ -87,6 +87,14 @@ def create_lattice(self, u_pos: Geometry.FloatSize) -> Graphics.LatticeGraphic: class DisplayCanvasItem(CanvasItem.CanvasItemComposition): + """Allow display canvas items (tools) to bypass multi-select. + + In cases where only_shift is used in the tool, the tool should bypass multi-select and the result will be as if + the user clicked in the target display panel without modifiers. For instance, if the user shift-clicks using the + crop tool to restrict the crop to a square shape, the crop tool should bypass multi-select and the result will be + as if the user clicked in the target display panel without modifiers, selecting the target panel. + """ + bypass_multi_select = False @property def key_contexts(self) -> typing.Sequence[str]: diff --git a/nion/swift/DisplayPanel.py b/nion/swift/DisplayPanel.py index 3eb9fd47..0ef6c2f6 100644 --- a/nion/swift/DisplayPanel.py +++ b/nion/swift/DisplayPanel.py @@ -1846,7 +1846,11 @@ def drop(mime_data: UserInterface.MimeData, region: str, x: int, y: int) -> str: return "ignore" def adjust_secondary_focus(modifiers: UserInterface.KeyboardModifiers) -> None: - if modifiers.only_shift: + display_canvas_item = self.display_canvas_item + if display_canvas_item and display_canvas_item.bypass_multi_select: + display_canvas_item.bypass_multi_select = False + self.__document_controller.selected_display_panel = self + elif modifiers.only_shift: self.__document_controller.add_secondary_display_panel(self) elif modifiers.only_control: self.__document_controller.toggle_secondary_display_panel(self) diff --git a/nion/swift/ImageCanvasItem.py b/nion/swift/ImageCanvasItem.py index 17ee221f..3312ca5e 100644 --- a/nion/swift/ImageCanvasItem.py +++ b/nion/swift/ImageCanvasItem.py @@ -663,6 +663,10 @@ async def _reactor_loop(self, r: Stream.ValueChangeStreamReactorInterface[MouseP pos = widget_mapping.map_point_widget_to_image_norm(mouse_pos) start_drag_pos = mouse_pos + # bypass multi-select if this tool is started with only the shift key selected. see notes where + # bypass_multi_select is defined. + image_canvas_item.bypass_multi_select = modifiers.only_shift + with delegate.create_create_graphic_task(self.graphic_type, pos) as create_create_graphic_task: # create the graphic and assign a drag part graphic = getattr(create_create_graphic_task, "_graphic")