From ea4007203080f50d79f827b29e94296211f796a4 Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 10 Jul 2023 14:04:54 +0200 Subject: [PATCH 1/2] update handling of mouse cursor with marker interaction --- src/silx/gui/plot/PlotInteraction.py | 54 +++++++++++++++++----------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/src/silx/gui/plot/PlotInteraction.py b/src/silx/gui/plot/PlotInteraction.py index 5c4c98c4d6..616625fd13 100644 --- a/src/silx/gui/plot/PlotInteraction.py +++ b/src/silx/gui/plot/PlotInteraction.py @@ -1097,6 +1097,11 @@ def __init__(self, *args, **kw): super(ItemsInteraction.Idle, self).__init__(*args, **kw) self._hoverMarker = None + def enterState(self): + plot = self.machine.plot + position = plot.getWidgetHandle().mapFromGlobal(qt.QCursor.pos()) + self.onMove(position.x(), position.y()) + def onMove(self, x, y): marker = self.machine.plot._getMarkerAt(x, y) @@ -1112,22 +1117,7 @@ def onMove(self, x, y): if marker != self._hoverMarker: self._hoverMarker = marker - - if marker is None: - self.machine.plot.setGraphCursorShape() - - elif marker.isDraggable(): - if isinstance(marker, items.YMarker): - self.machine.plot.setGraphCursorShape(CURSOR_SIZE_VER) - elif isinstance(marker, items.XMarker): - self.machine.plot.setGraphCursorShape(CURSOR_SIZE_HOR) - else: - self.machine.plot.setGraphCursorShape(CURSOR_SIZE_ALL) - - elif marker.isSelectable(): - self.machine.plot.setGraphCursorShape(CURSOR_POINTING) - else: - self.machine.plot.setGraphCursorShape() + self.machine._setCursorForMarker(marker) return True @@ -1139,6 +1129,27 @@ def __init__(self, plot): clickButtons=(LEFT_BTN, RIGHT_BTN), dragButtons=(LEFT_BTN, MIDDLE_BTN)) + def _setCursorForMarker(self, marker: Optional[items.MarkerBase] = None): + """Set mouse cursor for given marker""" + if marker is None: + cursor = None + + elif marker.isDraggable(): + if isinstance(marker, items.YMarker): + cursor = CURSOR_SIZE_VER + elif isinstance(marker, items.XMarker): + cursor = CURSOR_SIZE_HOR + else: + cursor = CURSOR_SIZE_ALL + + elif marker.isSelectable(): + cursor = CURSOR_POINTING + + else: + cursor = None + + self.plot.setGraphCursorShape(cursor) + def click(self, x, y, btn): """Handle mouse click @@ -1253,9 +1264,9 @@ def _signalMarkerMovingEvent(self, eventType, marker, x, y): def __isDraggableItem(item): return isinstance(item, items.DraggableMixIn) and item.isDraggable() - def __terminateDrag(self): + def __terminateDrag(self, x, y): """Finalize a drag operation by reseting to initial state""" - self.plot.setGraphCursorShape() + self._setCursorForMarker(self.plot._getMarkerAt(x, y)) self.draggedItemRef = None def beginDrag(self, x, y, btn): @@ -1276,7 +1287,7 @@ def beginDrag(self, x, y, btn): self.draggedItemRef = None if item is None else weakref.ref(item) if item is None: - self.__terminateDrag() + self.__terminateDrag(x, y) return False if isinstance(item, items.MarkerBase): @@ -1325,13 +1336,14 @@ def endDrag(self, startPos, endPos, btn): self.plot.notify(**eventDict) item._endDrag() - self.__terminateDrag() + self.__terminateDrag(*endPos) elif btn == MIDDLE_BTN: self._pan.endDrag(startPos, endPos, btn) def cancel(self): self._pan.cancel() - self.__terminateDrag() + position = self.plot.getWidgetHandle().mapFromGlobal(qt.QCursor.pos()) + self.__terminateDrag(position.x(), position.y()) class ItemsInteractionForCombo(ItemsInteraction): From 385236d4243ee9500a8a7e0494758e8ed4c06e3c Mon Sep 17 00:00:00 2001 From: Thomas VINCENT Date: Mon, 10 Jul 2023 17:16:02 +0200 Subject: [PATCH 2/2] Make it work without a plot backend --- src/silx/gui/plot/PlotInteraction.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/silx/gui/plot/PlotInteraction.py b/src/silx/gui/plot/PlotInteraction.py index 616625fd13..fe139b48ce 100644 --- a/src/silx/gui/plot/PlotInteraction.py +++ b/src/silx/gui/plot/PlotInteraction.py @@ -1098,8 +1098,10 @@ def __init__(self, *args, **kw): self._hoverMarker = None def enterState(self): - plot = self.machine.plot - position = plot.getWidgetHandle().mapFromGlobal(qt.QCursor.pos()) + widget = self.machine.plot.getWidgetHandle() + if widget is None or not widget.isVisible(): + return + position = widget.mapFromGlobal(qt.QCursor.pos()) self.onMove(position.x(), position.y()) def onMove(self, x, y): @@ -1342,7 +1344,10 @@ def endDrag(self, startPos, endPos, btn): def cancel(self): self._pan.cancel() - position = self.plot.getWidgetHandle().mapFromGlobal(qt.QCursor.pos()) + widget = self.plot.getWidgetHandle() + if widget is None or not widget.isVisible(): + return + position = widget.mapFromGlobal(qt.QCursor.pos()) self.__terminateDrag(position.x(), position.y())