|
3 | 3 | from __future__ import annotations
|
4 | 4 |
|
5 | 5 | import math
|
6 |
| -from typing import TYPE_CHECKING |
| 6 | +from contextlib import contextmanager |
| 7 | +from typing import TYPE_CHECKING, Generator |
7 | 8 |
|
8 | 9 | from guidata.dataset import update_dataset
|
9 | 10 | from guidata.utils.misc import assert_interfaces_valid
|
|
28 | 29 | from plotpy.styles.base import ItemParameters
|
29 | 30 |
|
30 | 31 |
|
| 32 | +@contextmanager |
| 33 | +def no_symbol_context( |
| 34 | + item: QwtPlotMarker, condition: bool |
| 35 | +) -> Generator[None, None, None]: |
| 36 | + """Context manager for temporarily changing a marker's symbol |
| 37 | +
|
| 38 | + Args: |
| 39 | + item: The marker object whose symbol might be changed |
| 40 | + condition: If True, the symbol will be changed to None temporarily |
| 41 | + """ |
| 42 | + old_symbol = None |
| 43 | + if condition: |
| 44 | + old_symbol = item.symbol() |
| 45 | + item.setSymbol(None) |
| 46 | + try: |
| 47 | + yield |
| 48 | + finally: |
| 49 | + if condition and old_symbol is not None: |
| 50 | + item.setSymbol(old_symbol) |
| 51 | + |
| 52 | + |
31 | 53 | class Marker(QwtPlotMarker):
|
32 | 54 | """Marker shape
|
33 | 55 |
|
@@ -137,7 +159,8 @@ def draw(
|
137 | 159 | x, y = self.center_handle(self.xValue(), self.yValue())
|
138 | 160 | self.setValue(x, y)
|
139 | 161 | self.update_label()
|
140 |
| - QwtPlotMarker.draw(self, painter, xMap, yMap, canvasRect) |
| 162 | + with no_symbol_context(self, not self.can_resize()): |
| 163 | + QwtPlotMarker.draw(self, painter, xMap, yMap, canvasRect) |
141 | 164 |
|
142 | 165 | # ------IBasePlotItem API----------------------------------------------------
|
143 | 166 | def get_icon_name(self) -> str:
|
@@ -180,6 +203,14 @@ def set_movable(self, state: bool) -> None:
|
180 | 203 | state: True if item is movable, False otherwise
|
181 | 204 | """
|
182 | 205 | self._can_move = state
|
| 206 | + # For a marker, setting the movable state to False means that, obviously, |
| 207 | + # it cannot be moved. However, due to the way the event system works, |
| 208 | + # the marker can still be moved by the user: it has to be not resizable |
| 209 | + # to prevent the user from moving it by dragging the handles, which is not |
| 210 | + # intuitive for a marker (from a user point of view, a marker is a point |
| 211 | + # or a line, not a shape with handles). |
| 212 | + # So, we set the resizable state to the same value as the movable state: |
| 213 | + self.set_resizable(state) |
183 | 214 |
|
184 | 215 | def set_rotatable(self, state: bool) -> None:
|
185 | 216 | """Set item rotatable state
|
|
0 commit comments