def test_basics(self): spec = KeySpec("Right", "control", ignore=["shift"]) self.assertEqual(spec.key, "Right") self.assertTrue(spec.control) self.assertSetEqual(spec.ignore, {"shift"}) self.assertFalse(spec.alt) self.assertFalse(spec.shift) event = Event("k", False, True, False) self.assertFalse(spec.match(event)) event = Event("Right", False, True, False) self.assertTrue(spec.match(event))
class InspectorFreezeTool(BaseTool): ''' Provides key for "freezing" line inspector tool so that cursor will remain in place ''' tool_set = Set main_key = Str("c") modifier_keys = List(value=["alt", 'shift']) ignore_keys = List(Str, value=[]) off_key = Instance(KeySpec) def _off_key_default(self): self.reset_off_key() self.on_trait_change(self.reset_off_key, ['main_key', 'modifier_keys', 'ignore_keys']) return self.off_key def reset_off_key(self): self.off_key = KeySpec(self.main_key, *self.modifier_keys, ignore=self.ignore_keys) def normal_key_pressed(self, event): if self.off_key.match(event): for tool in self.tool_set: active = tool.is_interactive if active: tool.is_interactive = False else: tool.is_interactive = True
def _create_plot_component(self): plot_data = TableModelPlotData(model = self.model) self.component = plot = Plot(plot_data, auto_axis = False, padding_left = 75, # FIXME: Can Chaco calcuate this automatically? ) plot.x_axis = DropAxis(component = plot, mapper = plot.x_mapper, plot_name = 'x', orientation = 'bottom') plot.y_axis = DropAxis(component = plot, mapper = plot.y_mapper, plot_name = 'y', orientation = 'left') self.scatter = scatter = plot.plot(('x', 'y'), type = 'scatter', marker = 'circle', )[0] plot.title = self.settings.title # Create selection overlay. inspector_overlay = SafeScatterInspectorOverlay(self.model, scatter, selection_metadata_name = 'selection', selection_color = 'blue', selection_marker_size = 6, ) scatter.overlays.append(inspector_overlay) # Create standard tools (always active). scatter.tools.append(PanTool(scatter, drag_button = 'right')) self._zoom_tool = ZoomTool(scatter, drag_button=None, enter_zoom_key=KeySpec(None), exit_zoom_key=KeySpec(None) ) scatter.tools.append(self._zoom_tool) # Create the active selection and tool. self._set_selection(self.selected) self._set_tool(self.tool) # Register event handlers. scatter.index.on_trait_change(self._update_selection, 'metadata_changed')
def _create_window(self): box = Box(bounds=[100, 100], position=[50, 50], color='red') move_tool = MoveCommandTool(component=box, command_stack=self.command_stack) box.tools.append(move_tool) container = Container(bounds=[600, 600]) container.add(box) undo_tool = UndoTool(component=container, undo_manager=self.undo_manager, undo_keys=[KeySpec('Left')], redo_keys=[KeySpec('Right')]) container.tools.append(undo_tool) window = Window(self.control, -1, component=container) return window
class XYInspector(BaseTool): """ A tool that captures the color and underlying values of an image plot. """ # This event fires whenever the mouse moves over a new image point. # Its value is a dict with a key "color_value", and possibly a key # "data_value" if the plot is a color-mapped image plot. new_value = Event # Indicates whether overlays listening to this tool should be visible. visible = Bool(True) # Stores the last mouse position. This can be used by overlays to # position themselves around the mouse. last_mouse_position = Tuple # This key will show and hide any ImageInspectorOverlays associated # with this tool. inspector_key = KeySpec('p') # Stores the value of self.visible when the mouse leaves the tool, # so that it can be restored when the mouse enters again. _old_visible = Enum(None, True, False) # Trait(None, Bool(True)) def normal_key_pressed(self, event): if self.inspector_key.match(event): self.visible = not self.visible event.handled = True def normal_mouse_leave(self, event): if self._old_visible is None: self._old_visible = self.visible self.visible = False def normal_mouse_enter(self, event): if self._old_visible is not None: self.visible = self._old_visible self._old_visible = None def normal_mouse_move(self, event): """ Handles the mouse being moved. Fires the **new_value** event with the data (if any) from the event's position. """ plot = self.component if plot is not None: # ndx = plot.map_index((event.x, event.y)) # if ndx == (None, None): # self.new_value = None # return pos = plot.map_data((event.x, event.y), all_values=True) # x_index, y_index = ndx self.new_value = dict(pos=pos)
def _add_scatter_inspector_overlay(self, scatter_plot): inspector = ScatterInspector( scatter_plot, threshold=10, multiselect_modifier=KeySpec(None, "shift"), selection_mode="multi", ) overlay = ScatterInspectorOverlay( scatter_plot, hover_color=(0, 0, 1, 1), hover_marker_size=6, selection_marker_size=20, selection_color=(0, 0, 1, 0.5), selection_outline_color=(0, 0, 0, 0.8), selection_line_width=3, ) scatter_plot.tools.append(inspector) scatter_plot.overlays.append(overlay)
def reset_off_key(self): self.off_key = KeySpec(self.main_key, *self.modifier_keys, ignore=self.ignore_keys)
class ImageInspectorTool(BaseTool): """ A tool that captures the color and underlying values of an image plot. """ #: This event fires whenever the mouse moves over a new image point. #: Its value is a dict with a key "color_value", and possibly a key #: "data_value" if the plot is a color-mapped image plot. new_value = Event #: Indicates whether overlays listening to this tool should be visible. visible = Bool(True) #: Stores the last mouse position. This can be used by overlays to #: position themselves around the mouse. last_mouse_position = Tuple #: This key will show and hide any ImageInspectorOverlays associated #: with this tool. inspector_key = KeySpec('p') # Stores the value of self.visible when the mouse leaves the tool, # so that it can be restored when the mouse enters again. _old_visible = Enum(None, True, False) #Trait(None, Bool(True)) def normal_key_pressed(self, event): if self.inspector_key.match(event): self.visible = not self.visible event.handled = True def normal_mouse_leave(self, event): if self._old_visible is None: self._old_visible = self.visible self.visible = False def normal_mouse_enter(self, event): if self._old_visible is not None: self.visible = self._old_visible self._old_visible = None def normal_mouse_move(self, event): """ Handles the mouse being moved. Fires the **new_value** event with the data (if any) from the event's position. """ plot = self.component if plot is not None: if isinstance(plot, ImagePlot): ndx = plot.map_index((event.x, event.y)) if ndx == (None, None): self.new_value = None return x_index, y_index = ndx image_data = plot.value if hasattr(plot, "_cached_mapped_image") and \ plot._cached_mapped_image is not None: self.new_value = \ dict(indices=ndx, data_value=image_data.data[y_index, x_index], color_value=plot._cached_mapped_image[y_index, x_index]) else: self.new_value = \ dict(indices=ndx, color_value=image_data.data[y_index, x_index]) self.last_mouse_position = (event.x, event.y) return
def test_from_string(self): spec = KeySpec.from_string("Shift+Control+z") self.assertSetEqual(spec.ignore, {"alt"}) event = Event("z", False, True, True) self.assertTrue(spec.match(event))
class SimpleInspectorTool(BaseTool): """ Simple inspector tool for plots This is a simple tool that reports the data-space coordinates of the current mouse cursor position in a plot. Interested overlays and other objects can listen for new_value events, which is a dictionary of data about the current location in data space, and can look at the last_mouse_position trait which holds the mouse position in screen space. The tool also provides a visible trait which listeners can use to hide themselves. By default the 'p' key toggles this. Instances can provide a value_generator function that performs computations to generate additional values in the dictionary that is passed to the new_value event. Subclasses can override gather_values() to similar effect. """ # This event fires whenever the mouse moves over a new image point. # Its value is a dict with default keys "x", "y", "index" and "value". new_value = Event # Indicates whether overlays listening to this tool should be visible. visible = Bool(True) # Stores the last mouse position. This can be used by overlays to # position themselves around the mouse. last_mouse_position = Tuple # This key will show and hide any overlays listening to this tool. inspector_key = KeySpec('p') # A callable that computes other values for the new_value event # this takes a dictionary as an argument, and returns a dictionary value_generator = Callable # Private Trails ######################################################## # Stores the value of self.visible when the mouse leaves the tool, # so that it can be restored when the mouse enters again. _old_visible = Enum(None, True, False) #Trait(None, Bool(True)) ######################################################################### # SimpleInspectorTool API ######################################################################### def gather_values(self, event): """ Generate the values for the new_value dictionary. By default this returns a dictionary with keys "x", "y", "index" and "value". If there is a value_generator callable, this will be called to modify the dictionary. Parameters ---------- event The mouse_move event. Returns ------- A dictionary. """ x, y, index, value = self.map_to_data(event.x, event.y) d = {'index': index, 'value': value, 'x': x, 'y': y} if isinstance(self.component, ImagePlot): x_ndx, y_ndx = self.component.map_index((event.x, event.y), outside_returns_none=False) # FIXME: off-by-one error. The size of the index is +1 to the size of # the image array if y_ndx == self.component.value.data.shape[0]: y_ndx -= 1 if x_ndx == self.component.value.data.shape[1]: x_ndx += 1 z = self.component.value.data[y_ndx, x_ndx] d['z'] = z d['color'] = z if self.value_generator is not None: d = self.value_generator(d) return d def map_to_data(self, x, y): """ Returns the data space coordinates of the given x and y. Takes into account orientation of the plot and the axis setting. """ plot = self.component if plot.orientation == "h": index = x = plot.x_mapper.map_data(x) value = y = plot.y_mapper.map_data(y) else: index = y = plot.y_mapper.map_data(y) value = x = plot.x_mapper.map_data(x) return x, y, index, value ######################################################################### # Component API ######################################################################### def normal_key_pressed(self, event): if self.inspector_key.match(event): self.visible = not self.visible def normal_mouse_leave(self, event): if self._old_visible is None: self._old_visible = self.visible self.visible = False def normal_mouse_enter(self, event): if self._old_visible is not None: self.visible = self._old_visible self._old_visible = None def normal_mouse_move(self, event): plot = self.component if plot is not None: self.new_value = self.gather_values(event) self.last_mouse_position = (event.x, event.y)