From ee24e2f57176407a3dd0c0f8f69d54ccfee45c12 Mon Sep 17 00:00:00 2001 From: "Pey Lian Lim (Github)" <2090236+pllim@users.noreply.github.com> Date: Fri, 13 May 2022 13:40:28 -0400 Subject: [PATCH 1/2] Imviz click to center in pan/zoom --- CHANGES.rst | 3 +++ docs/imviz/displayimages.rst | 3 +++ jdaviz/configs/imviz/plugins/viewers.py | 14 +++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1015601e0b..bcc2842894 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -19,6 +19,9 @@ Imviz - New curve of growth plot available in Simple Aperture Photometry plugin. [#1287] +- Clicking on image in pan/zoom mode now centers the image to location + under cursor. [#1319] + Mosviz ^^^^^^ diff --git a/docs/imviz/displayimages.rst b/docs/imviz/displayimages.rst index ed7ce9ec7d..23b4a06d9d 100644 --- a/docs/imviz/displayimages.rst +++ b/docs/imviz/displayimages.rst @@ -74,6 +74,9 @@ but you can re-link them via WCS using `~jdaviz.configs.imviz.helper.Imviz.link_ Regular Pan/Zoom is also available and is used in a similar way as other Jdaviz tools. +When in either of these modes, clicking on the image will recenter the image to the +location under cursor. + .. seealso:: :ref:`Pan/Zoom ` diff --git a/jdaviz/configs/imviz/plugins/viewers.py b/jdaviz/configs/imviz/plugins/viewers.py index 2a4657546a..09aa250d11 100644 --- a/jdaviz/configs/imviz/plugins/viewers.py +++ b/jdaviz/configs/imviz/plugins/viewers.py @@ -49,7 +49,8 @@ def __init__(self, *args, **kwargs): self.line_profile_xy = None self.add_event_callback(self.on_mouse_or_key_event, events=['mousemove', 'mouseenter', - 'mouseleave', 'keydown']) + 'mouseleave', 'keydown', + 'click']) self.state.add_callback('x_min', self.on_limits_change) self.state.add_callback('x_max', self.on_limits_change) self.state.add_callback('y_min', self.on_limits_change) @@ -162,6 +163,17 @@ def on_mouse_or_key_event(self, data): self.line_profile_xy.selected_viewer = self.reference_id self.line_profile_xy.vue_draw_plot() + elif (data['event'] == 'click' and + self.toolbar_nested.active_tool_id in ('bqplot:panzoom', 'jdaviz:panzoommatch')): + # Same data as mousemove above. + image = visible_layers[0].layer + x = data['domain']['x'] + y = data['domain']['y'] + if x is None or y is None: # Out of bounds + return + x, y, _ = self._get_real_xy(image, x, y) + self.center_on((x, y)) + def blink_once(self): # Simple blinking of images - this will make it so that only one # layer is visible at a time and cycles through the layers. From d14f59882714cd84ffa9c648815216f9029fd9cc Mon Sep 17 00:00:00 2001 From: "Pey Lian Lim (Github)" <2090236+pllim@users.noreply.github.com> Date: Fri, 13 May 2022 16:26:11 -0400 Subject: [PATCH 2/2] Put logic in proper tool as suggested by Kyle Conroy. --- jdaviz/configs/imviz/plugins/tools.py | 37 +++++++++++++++++++++++-- jdaviz/configs/imviz/plugins/viewers.py | 18 ++---------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/jdaviz/configs/imviz/plugins/tools.py b/jdaviz/configs/imviz/plugins/tools.py index decfa7906e..258782e9c8 100644 --- a/jdaviz/configs/imviz/plugins/tools.py +++ b/jdaviz/configs/imviz/plugins/tools.py @@ -59,6 +59,38 @@ def on_limits_change(self, *args): viewer.state.y_max = self.viewer.state.y_max +@viewer_tool +class JdavizPanZoomMode(BqplotPanZoomMode): + tool_id = 'jdaviz:panzoom' + tool_tip = 'Interactively pan (click-drag), zoom (scroll), and center (click)' + + def activate(self): + super().activate() + self.viewer.add_event_callback(self.on_click, events=['click']) + + def deactivate(self): + self.viewer.remove_event_callback(self.on_click) + super().deactivate() + + def on_click(self, data): + # Find visible layers + visible_layers = [layer for layer in self.viewer.state.layers if layer.visible] + if len(visible_layers) == 0: + return + + # Same data as mousemove event in Imviz viewer. + # Any other config that wants this functionality has to have the following: + # viewer._get_real_xy() + # viewer.center_on() --> inherited from AstrowidgetsImageViewerMixin + image = visible_layers[0].layer + x = data['domain']['x'] + y = data['domain']['y'] + if x is None or y is None: # Out of bounds + return + x, y, _ = self.viewer._get_real_xy(image, x, y) + self.viewer.center_on((x, y)) + + @viewer_tool class BlinkOnce(CheckableTool): icon = os.path.join(ICON_DIR, 'blink.svg') @@ -68,8 +100,7 @@ class BlinkOnce(CheckableTool): 'or you can also press the "b" key anytime') def activate(self): - self.viewer.add_event_callback(self.on_click, - events=['click']) + self.viewer.add_event_callback(self.on_click, events=['click']) def deactivate(self): self.viewer.remove_event_callback(self.on_click) @@ -87,7 +118,7 @@ class MatchBoxZoom(_MatchedZoomMixin, BoxZoom): @viewer_tool -class MatchPanZoom(_MatchedZoomMixin, BqplotPanZoomMode): +class MatchPanZoom(_MatchedZoomMixin, JdavizPanZoomMode): icon = os.path.join(ICON_DIR, 'panzoom_match.svg') tool_id = 'jdaviz:panzoommatch' action_text = 'Pan, matching between viewers' diff --git a/jdaviz/configs/imviz/plugins/viewers.py b/jdaviz/configs/imviz/plugins/viewers.py index 09aa250d11..4a51e3ae9b 100644 --- a/jdaviz/configs/imviz/plugins/viewers.py +++ b/jdaviz/configs/imviz/plugins/viewers.py @@ -23,7 +23,7 @@ class ImvizImageView(BqplotImageView, AstrowidgetsImageViewerMixin, JdavizViewer inherit_tools = False tools = ['bqplot:home', 'jdaviz:boxzoom', 'jdaviz:boxzoommatch', - 'bqplot:panzoom', 'jdaviz:panzoommatch', + 'jdaviz:panzoom', 'jdaviz:panzoommatch', 'jdaviz:contrastbias', 'jdaviz:blinkonce', 'bqplot:rectangle', 'bqplot:circle', 'bqplot:ellipse'] @@ -31,7 +31,7 @@ class ImvizImageView(BqplotImageView, AstrowidgetsImageViewerMixin, JdavizViewer tools_nested = [ ['bqplot:home'], ['jdaviz:boxzoom', 'jdaviz:boxzoommatch'], - ['bqplot:panzoom', 'jdaviz:panzoommatch'], + ['jdaviz:panzoom', 'jdaviz:panzoommatch'], ['bqplot:circle', 'bqplot:rectangle', 'bqplot:ellipse'], ['jdaviz:blinkonce', 'jdaviz:contrastbias'], ['jdaviz:sidebar_plot', 'jdaviz:sidebar_export', 'jdaviz:sidebar_compass'] @@ -49,8 +49,7 @@ def __init__(self, *args, **kwargs): self.line_profile_xy = None self.add_event_callback(self.on_mouse_or_key_event, events=['mousemove', 'mouseenter', - 'mouseleave', 'keydown', - 'click']) + 'mouseleave', 'keydown']) self.state.add_callback('x_min', self.on_limits_change) self.state.add_callback('x_max', self.on_limits_change) self.state.add_callback('y_min', self.on_limits_change) @@ -163,17 +162,6 @@ def on_mouse_or_key_event(self, data): self.line_profile_xy.selected_viewer = self.reference_id self.line_profile_xy.vue_draw_plot() - elif (data['event'] == 'click' and - self.toolbar_nested.active_tool_id in ('bqplot:panzoom', 'jdaviz:panzoommatch')): - # Same data as mousemove above. - image = visible_layers[0].layer - x = data['domain']['x'] - y = data['domain']['y'] - if x is None or y is None: # Out of bounds - return - x, y, _ = self._get_real_xy(image, x, y) - self.center_on((x, y)) - def blink_once(self): # Simple blinking of images - this will make it so that only one # layer is visible at a time and cycles through the layers.