diff --git a/docs/crop.ipynb b/docs/crop.ipynb index ddbefb4..2083743 100644 --- a/docs/crop.ipynb +++ b/docs/crop.ipynb @@ -37,7 +37,8 @@ "id": "deec8f67-28d2-4823-9f0e-f98feb8c8f3c", "metadata": {}, "source": [ - "The widget contains 2 or 3 sliders, for 2D and 3D images respectively. It also supports `stackview`'s typical parameters such as `continuous_update`, `zoom_factor`, etc." + "The widget contains 2 or 3 sliders, for 2D and 3D images respectively. It also supports `stackview`'s typical parameters such as `continuous_update`, `zoom_factor`, etc.\n", + "The crop can either be selected via the sliders or with two mouse clicks (left click for top left corner, right lick for bottom right corner of the cropped rectangle)." ] }, { diff --git a/stackview/_crop.py b/stackview/_crop.py index a01121d..ce7128a 100644 --- a/stackview/_crop.py +++ b/stackview/_crop.py @@ -131,6 +131,48 @@ def __init__(self, if len(image.shape) > 2: widgets.append(slice_slider) + from ipyevents import Event + + event_handler_top_left = Event(source=view, watched_events=["click"]) + event_handler_bottom_right = Event(source=view, watched_events=["auxclick"]) + + def update_rec_top_left(event=None): + relative_position_x = event["relativeX"] / zoom_factor + relative_position_y = event["relativeY"] / zoom_factor + positions = [int(relative_position_y), int(relative_position_x)] + + for i in [-1, -2]: + cmin, cmax = self._range_sliders[i].value + cvalue = positions[i] + cmin # Adjust position for current crop + self._range_sliders[i].value = (cvalue, cmax) + + if len(self._image.shape) > 2: + cmin, cmax = self._range_sliders[0].value + cvalue = slice_slider.value + cmin + self._range_sliders[0].value = (cvalue, cmax) + slice_slider.value = 0 + self.update() + + def update_rec_bottom_right(event=None): + relative_position_x = event["relativeX"] / zoom_factor + relative_position_y = event["relativeY"] / zoom_factor + positions = [int(relative_position_y), int(relative_position_x)] + + for i in [-1, -2]: + cmin, cmax = self._range_sliders[i].value + cvalue = positions[i] + cmin # Adjust position for current crop + self._range_sliders[i].value = (cmin, cvalue) + + if len(self._image.shape) > 2: + cmin, cmax = self._range_sliders[0].value + cvalue = slice_slider.value + cmin + 1 + self._range_sliders[0].value = (cmin, cvalue) + slice_slider.value = cvalue - cmin + 1 + self.update() + + event_handler_top_left.on_dom_event(update_rec_top_left) + event_handler_bottom_right.on_dom_event(update_rec_bottom_right) + super(_Cropper, self).__init__(widgets) def update(self, event=None):