From cf84b65120531ea6c461e4056c26bba7ea8c4b96 Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Sun, 21 May 2023 09:14:38 -0400 Subject: [PATCH] fix sync bug, arrow key movements are toggleable --- fastplotlib/graphics/selectors/_base_selector.py | 9 ++++++++- fastplotlib/graphics/selectors/_linear.py | 3 ++- fastplotlib/graphics/selectors/_linear_region.py | 4 ++++ fastplotlib/graphics/selectors/_sync.py | 11 ++++++++--- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/fastplotlib/graphics/selectors/_base_selector.py b/fastplotlib/graphics/selectors/_base_selector.py index 84c72283d..682e1855b 100644 --- a/fastplotlib/graphics/selectors/_base_selector.py +++ b/fastplotlib/graphics/selectors/_base_selector.py @@ -71,6 +71,7 @@ def __init__( # if not False, moves the slider on every render cycle self._key_move_value = False self.step: float = 1.0 #: step size for moving selector using the arrow keys + self.arrow_key_events_enabled = False self._move_info: MoveInfo = None @@ -106,6 +107,9 @@ def _add_plot_area_hook(self, plot_area): pfunc_down = partial(self._move_start, wo) wo.add_event_handler(pfunc_down, "pointer_down") + # double-click to enable arrow-key moveable mode + wo.add_event_handler(self._toggle_arrow_key_moveable, "double_click") + # when the pointer moves self._plot_area.renderer.add_event_handler(self._move, "pointer_move") @@ -237,8 +241,11 @@ def _pointer_leave(self, ev): for wo in self._hover_responsive: wo.material.color = self._original_colors[wo] + def _toggle_arrow_key_moveable(self, ev): + self.arrow_key_events_enabled = not self.arrow_key_events_enabled + def _key_hold(self): - if self._key_move_value: + if self._key_move_value and self.arrow_key_events_enabled: # direction vector * step delta = key_bind_direction[self._key_move_value].clone().multiply_scalar(self.step) diff --git a/fastplotlib/graphics/selectors/_linear.py b/fastplotlib/graphics/selectors/_linear.py index b02233135..ec18061d6 100644 --- a/fastplotlib/graphics/selectors/_linear.py +++ b/fastplotlib/graphics/selectors/_linear.py @@ -120,7 +120,8 @@ def __init__( arrow_keys_modifier: str modifier key that must be pressed to initiate movement using arrow keys, must be one of: - "Control", "Shift", "Alt" or ``None`` + "Control", "Shift", "Alt" or ``None``. Double click on the selector first to enable the + arrow key movements, or set the attribute ``arrow_key_events_enabled = True`` ipywidget_slider: IntSlider, optional ipywidget slider to associate with this graphic diff --git a/fastplotlib/graphics/selectors/_linear_region.py b/fastplotlib/graphics/selectors/_linear_region.py index 8cd0313a1..d41c47de8 100644 --- a/fastplotlib/graphics/selectors/_linear_region.py +++ b/fastplotlib/graphics/selectors/_linear_region.py @@ -178,6 +178,10 @@ def __init__( edge_color: str, array, or tuple edge color for the selector, passed to pygfx.Color + arrow_keys_modifier: str + modifier key that must be pressed to initiate movement using arrow keys, must be one of: + "Control", "Shift", "Alt" or ``None`` + name: str name for this selector graphic """ diff --git a/fastplotlib/graphics/selectors/_sync.py b/fastplotlib/graphics/selectors/_sync.py index 72d25b542..d697b9d07 100644 --- a/fastplotlib/graphics/selectors/_sync.py +++ b/fastplotlib/graphics/selectors/_sync.py @@ -26,6 +26,8 @@ def __init__(self, *selectors: LinearSelector, key_bind: str = "Shift"): self.block_event = False + self.enabled: bool = True + @property def selectors(self): """Selectors managed by the Synchronizer""" @@ -46,6 +48,9 @@ def _handle_event(self, ev): # because infinite recursion return + if not self.enabled: + return + self.block_event = True source = ev.pick_info["graphic"] @@ -63,18 +68,18 @@ def _handle_event(self, ev): return if delta is not None: - self._move_selectors(source, delta) + self._move_selectors(source, delta, ev) self.block_event = False - def _move_selectors(self, source, delta): + def _move_selectors(self, source, delta, ev): for s in self.selectors: # must use == and not is to compare Graphics because they are weakref proxies! if s == source: # if it's the source, since it has already movied continue - s._move_graphic(delta) + s._move_graphic(delta, ev) def __del__(self): for s in self.selectors: