From ab9d502d9897064cb941fcb07fba8cc3180d52c8 Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Fri, 13 Dec 2013 08:43:17 +0000 Subject: [PATCH 01/11] define RectangleSelectionTool and demo --- chaco/tools/api.py | 1 + chaco/tools/rectangle_selection_tool.py | 309 +++++++++++++++++++++ examples/demo/basic/rectangle_selection.py | 77 +++++ 3 files changed, 387 insertions(+) create mode 100644 chaco/tools/rectangle_selection_tool.py create mode 100644 examples/demo/basic/rectangle_selection.py diff --git a/chaco/tools/api.py b/chaco/tools/api.py index d1171da25..fa7ab073a 100644 --- a/chaco/tools/api.py +++ b/chaco/tools/api.py @@ -19,6 +19,7 @@ from range_selection import RangeSelection from range_selection_2d import RangeSelection2D from range_selection_overlay import RangeSelectionOverlay +from rectangle_selection_tool import RectangleSelectionTool from regression_lasso import RegressionLasso, RegressionOverlay from save_tool import SaveTool from scatter_inspector import ScatterInspector diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection_tool.py new file mode 100644 index 000000000..5dc8d7d37 --- /dev/null +++ b/chaco/tools/rectangle_selection_tool.py @@ -0,0 +1,309 @@ +""" Defines the RectangleSelectionTool class. +""" +# Major library imports +import numpy + +# Enthought library imports +from traits.api import Bool, Enum, Trait, Int, Float, Tuple, Array +from enable.api import BaseTool, ColorTrait, KeySpec +from chaco.abstract_overlay import AbstractOverlay + + +class RectangleSelectionTool(AbstractOverlay, BaseTool): + """ Selection tool which allows the user to draw a box which defines a + selected region and draw an overlay for the selected region. + """ + + #: Is the tool always "on"? If True, left-clicking always initiates a + #: selection operation; if False, the user must press a key to enter + #: selection mode. + always_on = Bool(False) + + #: Defines a meta-key, that works with always_on to set the selection mode. + #: This is useful when the selection tool is used in conjunction with the + #: pan tool. + always_on_modifier = Enum('control', 'shift', 'control', 'alt') + + #: The minimum amount of screen space the user must select in order for + #: the tool to actually take effect. + minimum_screen_delta = Int(10) + + #: Bounding box of selected region: (xmin, xmax, ymin, ymax) + #TODO: Rename to `selection`? + selected_box = Tuple() + + #: Key press to clear selected box + clear_selected_key = KeySpec('Esc') + + #------------------------------------------------------------------------- + # Appearance properties (for Box mode) + #------------------------------------------------------------------------- + + #: The pointer to use when drawing a selection box. + pointer = "magnifier" + + #: The color of the selection box. + color = ColorTrait("lightskyblue") + + #: The alpha value to apply to **color** when filling in the selection + #: region. Because it is almost certainly useless to have an opaque + #: selection rectangle, but it's also extremely useful to be able to use + #: the normal named colors from Enable, this attribute allows the + #: specification of a separate alpha value that replaces the alpha value + #: of **color** at draw time. + alpha = Trait(0.4, None, Float) + + #: The color of the outside selection rectangle. + border_color = ColorTrait("dodgerblue") + + #: The thickness of selection rectangle border. + border_size = Int(1) + + #: The possible event states of this selection tool. + event_state = Enum("normal", "selecting", "moving") + + #: The (x,y) screen point where the mouse went down. + _screen_start = Trait(None, None, Tuple) + + #: The (x,,y) screen point of the last seen mouse move event. + _screen_end = Trait(None, None, Tuple) + + #: If **always_on** is False, this attribute indicates whether the tool + #: is currently enabled. + _enabled = Bool(False) + + #------------------------------------------------------------------------ + # Moving (not resizing) state + #------------------------------------------------------------------------ + + #: The position of the initial user click for moving the selection. + _move_start = Array # (x,y) + + #: Move distance during moving state. + _move_offset = Array(value=(0, 0)) # (x,y) + + def __init__(self, component=None, *args, **kw): + # Since this class uses multiple inheritance (eek!), lets be + # explicit about the order of the parent class constructors + AbstractOverlay.__init__(self, component, *args, **kw) + BaseTool.__init__(self, component, *args, **kw) + + def reset(self, event=None): + """ Resets the tool to normal state. + """ + self.event_state = "normal" + + def clear_selected_box(self): + self._screen_start = self._screen_end = None + self.selected_box = () + + #-------------------------------------------------------------------------- + # BaseTool interface + #-------------------------------------------------------------------------- + + def normal_key_pressed(self, event): + """ Handles a key being pressed when the tool is in the 'normal' + state. + """ + if self.clear_selected_key.match(event) and not self._enabled: + self.clear_selected_box() + self.request_redraw() + event.handled = True + + def normal_mouse_move(self, event): + self.position = (event.x, event.y) + + def normal_mouse_enter(self, event): + """ Try to set the focus to the window when the mouse enters, otherwise + the keypress events will not be triggered. + """ + if self.component._window is not None: + self.component._window._set_focus() + + def normal_left_down(self, event): + """ Handles the left mouse button being pressed while the tool is in + the 'normal' state. + + If the tool is enabled or always on, it starts selecting. + """ + if self.component.active_tool in (None, self): + self.component.active_tool = self + else: + self._enabled = False + + if self._within_selected_box(event): + self._start_move(event) + else: + self._start_select(event) + + event.handled = True + + def selecting_mouse_move(self, event): + """ Handles the mouse moving when the tool is in the 'selecting' state. + + The selection is extended to the current mouse position. + """ + self._screen_end = (event.x, event.y) + self.component.request_redraw() + event.handled = True + + def selecting_left_up(self, event): + """ Handles the left mouse button being released when the tool is in + the 'selecting' state. + + Finishes selecting and does the selection. + """ + self._end_select(event) + + def moving_mouse_move(self, event): + """ Handles the mouse moving when the tool is in the 'moving' state. + + Moves the overlayby an amount corresponding to the amount that the + mouse has moved since its button was pressed. If the new selection + range overlaps the endpoints of the data, it is truncated to that + endpoint. + """ + self._move_offset = (event.x, event.y) - self._move_start + self.component.request_redraw() + event.handled = True + + def moving_left_up(self, event): + """ Handles the left mouse button coming up when the tool is in the + 'moving' state. + + Switches the tool to the 'selected' state. + """ + #TODO: Why are _screen_start and _screen_end tuples not arrays? + self._screen_start = tuple(self._screen_start + self._move_offset) + self._screen_end = tuple(self._screen_end + self._move_offset) + + self._update_selected_box() + # Clear move + self._move_offset = (0, 0) + + self.event_state = "normal" + event.handled = True + + #-------------------------------------------------------------------------- + # AbstractOverlay interface + #-------------------------------------------------------------------------- + + def overlay(self, component, gc, view_bounds=None, mode="normal"): + """ Draws this component overlaid on another component. + + Overrides AbstractOverlay. + """ + self._overlay_box(component, gc) + + #-------------------------------------------------------------------------- + # private interface + #-------------------------------------------------------------------------- + + def _start_select(self, event): + """ Starts selecting the selection region + """ + self.event_state = "selecting" + self._screen_start = (event.x, event.y) + self._screen_end = None + event.window.set_pointer(self.pointer) + event.window.set_mouse_owner(self, event.net_transform()) + self.selecting_mouse_move(event) + + def _end_select(self, event): + """ Ends selection of the selection region, adds the new selection + range to the selection stack, and does the selection. + """ + self._screen_end = (event.x, event.y) + self._update_selected_box() + self._end_selecting(event) + event.handled = True + + def _end_selecting(self, event=None): + """ Ends selection of selection region, without selectioning. + """ + self.reset() + self._enabled = False + if self.component.active_tool == self: + self.component.active_tool = None + if event and event.window: + event.window.set_pointer("arrow") + + self.component.request_redraw() + if event and event.window.mouse_owner == self: + event.window.set_mouse_owner(None) + + def _update_selected_box(self): + start = numpy.array(self._screen_start) + end = numpy.array(self._screen_end) + + # If selection is below minimum, clear selected box. + if sum(abs(end - start)) < self.minimum_screen_delta: + self.clear_selected_box() + else: + # Selected box in screen coordinates + self._selected_box_screen = (sorted([start[0], end[0]]) + + sorted([start[1], end[1]])) + # Selected box in data coordinates + low, high = self._map_coordinate_box(self._screen_start, + self._screen_end) + self.selected_box = (low[0], high[0], low[1], high[1]) + + def _start_move(self, event): + self.event_state = "moving" + self._move_start = (event.x, event.y) + self.moving_mouse_move(event) + + def _overlay_box(self, component, gc): + """ Draws the overlay as a box. + """ + if self._screen_start and self._screen_end: + with gc: + gc.set_antialias(0) + gc.set_line_width(self.border_size) + gc.set_stroke_color(self.border_color_) + gc.clip_to_rect(component.x, component.y, + component.width, component.height) + x, y = self._screen_start + self._move_offset + x2, y2 = self._screen_end + self._move_offset + rect = (x, y, x2 - x + 1, y2 - y + 1) + if self.color != "transparent": + if self.alpha: + color = list(self.color_) + if len(color) == 4: + color[3] = self.alpha + else: + color += [self.alpha] + else: + color = self.color_ + gc.set_fill_color(color) + gc.draw_rect(rect) + else: + gc.rect(*rect) + gc.stroke_path() + + def _map_coordinate_box(self, start, end): + """ Given start and end points in screen space, returns corresponding + low and high points in data space. + """ + low = [0, 0] + high = [0, 0] + for axis_index, mapper in [(0, self.component.x_mapper), + (1, self.component.y_mapper)]: + # Ignore missing axis mappers (ColorBar instances only have one). + if not mapper: + continue + low_val, high_val = sorted(mapper.map_data(point[axis_index]) + for point in (start, end)) + low[axis_index] = low_val + high[axis_index] = high_val + return low, high + + def _within_selected_box(self, event): + if not self.selected_box: + return False + + xmin, xmax, ymin, ymax = self._selected_box_screen + if xmin < event.x < xmax and ymin < event.y < ymax: + return True + else: + return False diff --git a/examples/demo/basic/rectangle_selection.py b/examples/demo/basic/rectangle_selection.py new file mode 100644 index 000000000..93b925c07 --- /dev/null +++ b/examples/demo/basic/rectangle_selection.py @@ -0,0 +1,77 @@ +from chaco.api import (ArrayPlotData, HPlotContainer, Plot) +from chaco.tools.api import RectangleSelectionTool +from enable.api import ComponentEditor +from scipy.misc import lena +from traits.api import (Any, Array, cached_property, HasTraits, Instance, + Property) +from traitsui.api import View, Item + + +class RectSelectionDemo(HasTraits): + container = Instance(HPlotContainer) + img = Array() + img_plot = Instance(Plot) + plot_data = Instance(ArrayPlotData()) + selection = Any() + zoom_img = Property(Array, depends_on=['img', 'selection']) + zoom_plot = Instance(Plot) + + def _container_default(self): + img_plot = self.img_plot + zoom_plot = self.zoom_plot + container = HPlotContainer(img_plot, zoom_plot) + return container + + @cached_property + def _get_zoom_img(self): + return self.img + + def _img_default(self): + return lena() + + def _img_plot_default(self): + img_plot = Plot(self.plot_data) + img_plot.img_plot("img", + origin="top left") + rst = RectangleSelectionTool(img_plot) + img_plot.tools.append(rst) + img_plot.overlays.append(rst) + self.selection = rst + rst.on_trait_change(self.update_zoom, 'event_state') + return img_plot + + def _plot_data_default(self): + plot_data = ArrayPlotData(img=self.img, + zoom_img=self.zoom_img) + return plot_data + + def update_zoom(self): + box = self.selection.selected_box + if box is not (): + bottom = max(0, int(box[2])) + top = min(self.img.shape[0], int(box[3])) + left = max(0, int(box[0])) + right = min(self.img.shape[1], int(box[1])) + self.plot_data.set_data("zoom_img", + self.img[bottom:top, left:right]) + self.zoom_plot.plot_components[0].index.set_data((left, right), + (bottom, top)) + + def _zoom_plot_default(self): + zoom_plot = Plot(self.plot_data) + zoom_plot.img_plot("zoom_img", + origin="top left",) + return zoom_plot + + default_traits_view = View( + Item('container', + editor=ComponentEditor(), + show_label=False, + width=800,), + resizable=True, + ) + + +if __name__ == '__main__': + rsd = RectSelectionDemo() + rsd.configure_traits() From 7ae56ea8c7b4b8b7f73501e07305db101443debd Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Fri, 13 Dec 2013 09:01:36 +0000 Subject: [PATCH 02/11] fix 0-axis selection and add comments to the example --- examples/demo/basic/rectangle_selection.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/demo/basic/rectangle_selection.py b/examples/demo/basic/rectangle_selection.py index 93b925c07..a3ca68e7d 100644 --- a/examples/demo/basic/rectangle_selection.py +++ b/examples/demo/basic/rectangle_selection.py @@ -46,12 +46,18 @@ def _plot_data_default(self): return plot_data def update_zoom(self): + # selected box is in data space coordinates + # by default data space is defined in number of array elements box = self.selection.selected_box + height = self.img.shape[0] + width = self.img.shape[1] if box is not (): - bottom = max(0, int(box[2])) - top = min(self.img.shape[0], int(box[3])) + # plot is displayed with the y-axis inverted, so we need to map + # the 0-axis coordinates + bottom = max(0, height - int(box[3])) + top = min(height, height - int(box[2])) left = max(0, int(box[0])) - right = min(self.img.shape[1], int(box[1])) + right = min(width, int(box[1])) self.plot_data.set_data("zoom_img", self.img[bottom:top, left:right]) self.zoom_plot.plot_components[0].index.set_data((left, right), From 0ab273ba2443f60be8bf3a99d79fa45d21a62cb3 Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 18 Feb 2014 14:17:25 +0000 Subject: [PATCH 03/11] typo fix --- chaco/tools/rectangle_selection_tool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection_tool.py index 5dc8d7d37..8dc2f0ed7 100644 --- a/chaco/tools/rectangle_selection_tool.py +++ b/chaco/tools/rectangle_selection_tool.py @@ -158,7 +158,7 @@ def selecting_left_up(self, event): def moving_mouse_move(self, event): """ Handles the mouse moving when the tool is in the 'moving' state. - Moves the overlayby an amount corresponding to the amount that the + Moves the overlay by an amount corresponding to the amount that the mouse has moved since its button was pressed. If the new selection range overlaps the endpoints of the data, it is truncated to that endpoint. From d3a30aae785d1f508980192a4cd1b2e5157daba1 Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 18 Feb 2014 14:21:02 +0000 Subject: [PATCH 04/11] make normal_mouse_move set event.handled = True --- chaco/tools/rectangle_selection_tool.py | 1 + 1 file changed, 1 insertion(+) diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection_tool.py index 8dc2f0ed7..40aa6df98 100644 --- a/chaco/tools/rectangle_selection_tool.py +++ b/chaco/tools/rectangle_selection_tool.py @@ -112,6 +112,7 @@ def normal_key_pressed(self, event): def normal_mouse_move(self, event): self.position = (event.x, event.y) + event.handled = True def normal_mouse_enter(self, event): """ Try to set the focus to the window when the mouse enters, otherwise From 0e3f5e2b610b478a3448354480541eb1e81af854 Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 18 Feb 2014 14:22:13 +0000 Subject: [PATCH 05/11] typos and nits --- chaco/tools/rectangle_selection_tool.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection_tool.py index 40aa6df98..9fae006d5 100644 --- a/chaco/tools/rectangle_selection_tool.py +++ b/chaco/tools/rectangle_selection_tool.py @@ -62,10 +62,10 @@ class RectangleSelectionTool(AbstractOverlay, BaseTool): #: The possible event states of this selection tool. event_state = Enum("normal", "selecting", "moving") - #: The (x,y) screen point where the mouse went down. + #: The (x, y) screen point where the mouse went down. _screen_start = Trait(None, None, Tuple) - #: The (x,,y) screen point of the last seen mouse move event. + #: The (x, y) screen point of the last seen mouse move event. _screen_end = Trait(None, None, Tuple) #: If **always_on** is False, this attribute indicates whether the tool @@ -77,13 +77,13 @@ class RectangleSelectionTool(AbstractOverlay, BaseTool): #------------------------------------------------------------------------ #: The position of the initial user click for moving the selection. - _move_start = Array # (x,y) + _move_start = Array # (x, y) #: Move distance during moving state. - _move_offset = Array(value=(0, 0)) # (x,y) + _move_offset = Array(value=(0, 0)) # (x, ) def __init__(self, component=None, *args, **kw): - # Since this class uses multiple inheritance (eek!), lets be + # Since this class uses multiple inheritance (eek!), let's be # explicit about the order of the parent class constructors AbstractOverlay.__init__(self, component, *args, **kw) BaseTool.__init__(self, component, *args, **kw) From 725b8552f9445a66418329787526733d7fcfa47c Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 18 Feb 2014 14:36:28 +0000 Subject: [PATCH 06/11] add comments describing enumerated states\n\nborrowed from BetterSelectingZoom as was done for the rest of this tool. --- chaco/tools/rectangle_selection_tool.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection_tool.py index 9fae006d5..a01ed5742 100644 --- a/chaco/tools/rectangle_selection_tool.py +++ b/chaco/tools/rectangle_selection_tool.py @@ -60,6 +60,14 @@ class RectangleSelectionTool(AbstractOverlay, BaseTool): border_size = Int(1) #: The possible event states of this selection tool. + # normal: + # Nothing has been selected, and the user is not dragging the mouse. + # selecting: + # The user is dragging the mouse and actively changing the + # selection region; resizing of an existing selection also + # uses this mode. + # moving: + # The user moving (not resizing) the selection range. event_state = Enum("normal", "selecting", "moving") #: The (x, y) screen point where the mouse went down. From 2dfe6d242f886dfc22ff95dff6192a2b91e5a223 Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 18 Feb 2014 15:46:19 +0000 Subject: [PATCH 07/11] remove some tool components from RectangleSelection --- chaco/tools/rectangle_selection_tool.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection_tool.py index a01ed5742..f2ea62d9b 100644 --- a/chaco/tools/rectangle_selection_tool.py +++ b/chaco/tools/rectangle_selection_tool.py @@ -5,11 +5,11 @@ # Enthought library imports from traits.api import Bool, Enum, Trait, Int, Float, Tuple, Array -from enable.api import BaseTool, ColorTrait, KeySpec +from enable.api import ColorTrait, KeySpec from chaco.abstract_overlay import AbstractOverlay -class RectangleSelectionTool(AbstractOverlay, BaseTool): +class RectangleSelection(AbstractOverlay): """ Selection tool which allows the user to draw a box which defines a selected region and draw an overlay for the selected region. """ @@ -90,12 +90,6 @@ class RectangleSelectionTool(AbstractOverlay, BaseTool): #: Move distance during moving state. _move_offset = Array(value=(0, 0)) # (x, ) - def __init__(self, component=None, *args, **kw): - # Since this class uses multiple inheritance (eek!), let's be - # explicit about the order of the parent class constructors - AbstractOverlay.__init__(self, component, *args, **kw) - BaseTool.__init__(self, component, *args, **kw) - def reset(self, event=None): """ Resets the tool to normal state. """ @@ -106,7 +100,7 @@ def clear_selected_box(self): self.selected_box = () #-------------------------------------------------------------------------- - # BaseTool interface + # Interactor interface #-------------------------------------------------------------------------- def normal_key_pressed(self, event): @@ -135,10 +129,6 @@ def normal_left_down(self, event): If the tool is enabled or always on, it starts selecting. """ - if self.component.active_tool in (None, self): - self.component.active_tool = self - else: - self._enabled = False if self._within_selected_box(event): self._start_move(event) From d430f1518f41777943848cc86a264dd89b3c800f Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 18 Feb 2014 15:46:53 +0000 Subject: [PATCH 08/11] rectangle_selection_tool -> rectangle_selection --- chaco/tools/api.py | 2 +- .../{rectangle_selection_tool.py => rectangle_selection.py} | 0 examples/demo/basic/rectangle_selection.py | 5 ++--- 3 files changed, 3 insertions(+), 4 deletions(-) rename chaco/tools/{rectangle_selection_tool.py => rectangle_selection.py} (100%) diff --git a/chaco/tools/api.py b/chaco/tools/api.py index fa7ab073a..927b2a78f 100644 --- a/chaco/tools/api.py +++ b/chaco/tools/api.py @@ -19,7 +19,7 @@ from range_selection import RangeSelection from range_selection_2d import RangeSelection2D from range_selection_overlay import RangeSelectionOverlay -from rectangle_selection_tool import RectangleSelectionTool +from rectangle_selection import RectangleSelection from regression_lasso import RegressionLasso, RegressionOverlay from save_tool import SaveTool from scatter_inspector import ScatterInspector diff --git a/chaco/tools/rectangle_selection_tool.py b/chaco/tools/rectangle_selection.py similarity index 100% rename from chaco/tools/rectangle_selection_tool.py rename to chaco/tools/rectangle_selection.py diff --git a/examples/demo/basic/rectangle_selection.py b/examples/demo/basic/rectangle_selection.py index a3ca68e7d..4193c061e 100644 --- a/examples/demo/basic/rectangle_selection.py +++ b/examples/demo/basic/rectangle_selection.py @@ -1,5 +1,5 @@ from chaco.api import (ArrayPlotData, HPlotContainer, Plot) -from chaco.tools.api import RectangleSelectionTool +from chaco.tools.api import RectangleSelection from enable.api import ComponentEditor from scipy.misc import lena from traits.api import (Any, Array, cached_property, HasTraits, Instance, @@ -33,8 +33,7 @@ def _img_plot_default(self): img_plot = Plot(self.plot_data) img_plot.img_plot("img", origin="top left") - rst = RectangleSelectionTool(img_plot) - img_plot.tools.append(rst) + rst = RectangleSelection(img_plot) img_plot.overlays.append(rst) self.selection = rst rst.on_trait_change(self.update_zoom, 'event_state') From 854d741fe5b939aa5f320f09768c95716f8f2056 Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 10 Jul 2018 16:52:55 -0500 Subject: [PATCH 09/11] convert API imports to explicit relative imports to resolve conflict with master --- chaco/tools/api.py | 64 +++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/chaco/tools/api.py b/chaco/tools/api.py index 927b2a78f..a7d01746f 100644 --- a/chaco/tools/api.py +++ b/chaco/tools/api.py @@ -1,33 +1,33 @@ -from better_zoom import BetterZoom -from better_selecting_zoom import BetterSelectingZoom -from broadcaster import BroadcasterTool -from dataprinter import DataPrinter -from data_label_tool import DataLabelTool -from enable.tools.drag_tool import DragTool -from draw_points_tool import DrawPointsTool -from drag_zoom import DragZoom -from highlight_tool import HighlightTool -from image_inspector_tool import ImageInspectorTool, ImageInspectorOverlay -from lasso_selection import LassoSelection -from legend_tool import LegendTool -from legend_highlighter import LegendHighlighter -from line_inspector import LineInspector -from line_segment_tool import LineSegmentTool -from move_tool import MoveTool -from pan_tool import PanTool -from point_marker import PointMarker -from range_selection import RangeSelection -from range_selection_2d import RangeSelection2D -from range_selection_overlay import RangeSelectionOverlay -from rectangle_selection import RectangleSelection -from regression_lasso import RegressionLasso, RegressionOverlay -from save_tool import SaveTool -from scatter_inspector import ScatterInspector -from select_tool import SelectTool -from simple_inspector import SimpleInspectorTool -from tool_states import ZoomState, PanState, GroupedToolState, SelectedZoomState -from tracking_pan_tool import TrackingPanTool -from tracking_zoom import TrackingZoom -from traits_tool import TraitsTool -from zoom_tool import ZoomTool +from .better_zoom import BetterZoom +from .better_selecting_zoom import BetterSelectingZoom +from .broadcaster import BroadcasterTool +from .dataprinter import DataPrinter +from .data_label_tool import DataLabelTool +from .enable.tools.drag_tool import DragTool +from .draw_points_tool import DrawPointsTool +from .drag_zoom import DragZoom +from .highlight_tool import HighlightTool +from .image_inspector_tool import ImageInspectorTool, ImageInspectorOverlay +from .lasso_selection import LassoSelection +from .legend_tool import LegendTool +from .legend_highlighter import LegendHighlighter +from .line_inspector import LineInspector +from .line_segment_tool import LineSegmentTool +from .move_tool import MoveTool +from .pan_tool import PanTool +from .point_marker import PointMarker +from .range_selection import RangeSelection +from .range_selection_2d import RangeSelection2D +from .range_selection_overlay import RangeSelectionOverlay +from .rectangle_selection import RectangleSelection +from .regression_lasso import RegressionLasso, RegressionOverlay +from .save_tool import SaveTool +from .scatter_inspector import ScatterInspector +from .select_tool import SelectTool +from .simple_inspector import SimpleInspectorTool +from .tool_states import ZoomState, PanState, GroupedToolState, SelectedZoomState +from .tracking_pan_tool import TrackingPanTool +from .tracking_zoom import TrackingZoom +from .traits_tool import TraitsTool +from .zoom_tool import ZoomTool # EOF From 2bb0f79a7192b0fe564704bd788eff9911b90aef Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 10 Jul 2018 16:57:58 -0500 Subject: [PATCH 10/11] fix typo --- chaco/tools/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaco/tools/api.py b/chaco/tools/api.py index a7d01746f..fa6646d27 100644 --- a/chaco/tools/api.py +++ b/chaco/tools/api.py @@ -3,7 +3,7 @@ from .broadcaster import BroadcasterTool from .dataprinter import DataPrinter from .data_label_tool import DataLabelTool -from .enable.tools.drag_tool import DragTool +from enable.tools.drag_tool import DragTool from .draw_points_tool import DrawPointsTool from .drag_zoom import DragZoom from .highlight_tool import HighlightTool From 9950b280feeba38c700f4e702ac947db49c3e1eb Mon Sep 17 00:00:00 2001 From: Tim Diller Date: Tue, 26 May 2020 13:25:08 -0500 Subject: [PATCH 11/11] replace deprecated scipy.misc.lena() with scipy.misc.face() as the default image for the demo --- examples/demo/basic/rectangle_selection.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/demo/basic/rectangle_selection.py b/examples/demo/basic/rectangle_selection.py index 4193c061e..4c49d02bf 100644 --- a/examples/demo/basic/rectangle_selection.py +++ b/examples/demo/basic/rectangle_selection.py @@ -1,7 +1,7 @@ from chaco.api import (ArrayPlotData, HPlotContainer, Plot) from chaco.tools.api import RectangleSelection from enable.api import ComponentEditor -from scipy.misc import lena +from scipy.misc import face from traits.api import (Any, Array, cached_property, HasTraits, Instance, Property) from traitsui.api import View, Item @@ -27,7 +27,7 @@ def _get_zoom_img(self): return self.img def _img_default(self): - return lena() + return face() def _img_plot_default(self): img_plot = Plot(self.plot_data)