class ButtonEditorDemo(HasTraits): my_button = Button() my_button_label = Str("Initial Label") my_button_image = Image() my_button_image_options = List(Image(), value=[ ImageResource("run", [traitsui.extras]), ImageResource("previous", [traitsui.extras]), ImageResource("next", [traitsui.extras]), ImageResource("parent", [traitsui.extras]), ImageResource("reload", [traitsui.extras]) ]) def _my_button_image_default(self): return self.my_button_image_options[0] traits_view = View( Item("my_button", style="custom", editor=ButtonEditor(label_value="my_button_label", image_value="my_button_image", orientation="horizontal")), Item("my_button_label"), Item("my_button_image", editor=InstanceEditor(name="my_button_image_options", adapter=ImageChoice), style="custom"))
class IView(IWorkbenchPart, IPerspectiveItem): """ The interface for workbench views. """ # Is the view busy? (i.e., should the busy cursor (often an hourglass) be # displayed?). busy = Bool(False) # The category that the view belongs to (this can used to group views when # they are displayed to the user). category = Str("General") # An image used to represent the view to the user (shown in the view tab # and in the view chooser etc). image = Image() # Whether the view is visible or not. visible = Bool(False) # ------------------------------------------------------------------------ # 'IView' interface. # ------------------------------------------------------------------------ def activate(self): """ Activate the view. """ def hide(self): """ Hide the view. """ def show(self): """ Show the view.
class CustomEditor(SimpleEditor): """ Custom style editor for a button, which can contain an image. """ #: The button image image = Image() #: The mapping of button styles to Qt classes. _STYLE_MAP = { "checkbox": QtGui.QCheckBox, "radio": QtGui.QRadioButton, "toolbar": QtGui.QToolButton, } def init(self, parent): """ Finishes initializing the editor by creating the underlying toolkit widget. """ # FIXME: We ignore orientation, width_padding and height_padding. factory = self.factory if factory.label: label = factory.label else: label = self.item.get_label(self.ui) btype = self._STYLE_MAP.get(factory.style, QtGui.QPushButton) self.control = btype() self.control.setText(self.string_value(label)) if factory.image is not None: self.control.setIcon(factory.image.create_icon()) self.sync_value(self.factory.label_value, "label", "from") self.sync_value(self.factory.image_value, "image", "from") self.control.clicked.connect(self.update_object) self.set_tooltip() @observe("image") def _image_updated(self, event): image = event.new self.control.setIcon(image.create_icon()) def dispose(self): """ Disposes of the contents of an editor. """ if self.control is not None: self.control.clicked.disconnect(self.update_object) # FIXME: Maybe better to let this class subclass Editor directly # enthought/traitsui#884 Editor.dispose(self)
class ImageDisplay(HasTraits): image = Image()
class NodeType(HasPrivateTraits): """ The base class for all node types. """ # The default image used to represent nodes that DO NOT allow children. DOCUMENT = ImageResource("document") # The default image used to represent nodes that allow children and are NOT # expanded. CLOSED_FOLDER = ImageResource("closed_folder") # The default image used to represent nodes that allow children and ARE # expanded. OPEN_FOLDER = ImageResource("open_folder") # 'NodeType' interface ------------------------------------------------- # The node manager that the type belongs to. node_manager = Instance("pyface.tree.node_manager.NodeManager") # The image used to represent nodes that DO NOT allow children. image = Image(DOCUMENT) # The image used to represent nodes that allow children and are NOT # expanded. closed_image = Image(CLOSED_FOLDER) # The image used to represent nodes that allow children and ARE expanded. open_image = Image(OPEN_FOLDER) # The default actions/groups/menus available on nodes of this type (shown # on the context menu). actions = Any # List # The default action for nodes of this type. The default action is # performed when a node is activated (i.e., double-clicked). default_action = Instance(Action) # The default actions/groups/menus for creating new children within nodes # of this type (shown in the 'New' menu of the context menu). new_actions = Any # List # ------------------------------------------------------------------------ # 'NodeType' interface. # ------------------------------------------------------------------------ # These methods are specific to the 'NodeType' interface --------------- def is_type_for(self, node): """ Returns True if a node is deemed to be of this type. """ raise NotImplementedError() def allows_children(self, node): """ Does the node allow children (ie. a folder vs a file). """ return False def get_actions(self, node): """ Returns the node-specific actions for a node. """ return self.actions def get_context_menu(self, node): """ Returns the context menu for a node. """ sat = Group(id="SystemActionsTop") nsa = Group(id="NodeSpecificActions") sab = Group(id="SystemActionsBottom") # The 'New' menu. new_actions = self.get_new_actions(node) if new_actions is not None and len(new_actions) > 0: sat.append(MenuManager(name="New", *new_actions)) # Node-specific actions. actions = self.get_actions(node) if actions is not None and len(actions) > 0: for item in actions: nsa.append(item) # System actions (actions available on ALL nodes). system_actions = self.node_manager.system_actions if len(system_actions) > 0: for item in system_actions: sab.append(item) context_menu = MenuManager(sat, nsa, sab) context_menu.dump() return context_menu def get_copy_value(self, node): """ Get the value that is copied for a node. By default, returns the node itself. """ return node def get_default_action(self, node): """ Returns the default action for a node. """ return self.default_action def get_new_actions(self, node): """ Returns the new actions for a node. """ return self.new_actions def get_paste_value(self, node): """ Get the value that is pasted for a node. By default, returns the node itself. """ return node def get_monitor(self, node): """ Returns a monitor that detects changes to a node. Returns None by default, which indicates that the node is not monitored. """ return None # These methods are exactly the same as the 'TreeModel' interface -----# def has_children(self, node): """ Returns True if a node has children, otherwise False. You only need to implement this method if children are allowed for the node (ie. 'allows_children' returns True). """ return False def get_children(self, node): """ Returns the children of a node. You only need to implement this method if children are allowed for the node. """ raise NotImplementedError() def get_drag_value(self, node): """ Get the value that is dragged for a node. By default, returns the node itself. """ return node def can_drop(self, node, data): """ Returns True if a node allows an object to be dropped onto it. """ return False def drop(self, obj, data): """ Drops an object onto a node. """ raise NotImplementedError() def get_image(self, node, selected, expanded): """ Returns the label image for a node. """ if self.allows_children(node): if expanded: order = ["open_image", "closed_image", "image"] default = self.OPEN_FOLDER else: order = ["closed_image", "open_image", "image"] default = self.CLOSED_FOLDER else: order = ["image", "open_image", "closed_image"] default = self.DOCUMENT # Use the search order to look for a trait that is NOT None. for name in order: image = getattr(self, name) if image is not None: break # If no such trait is found then use the default image. else: image = default return image def get_selection_value(self, node): """ Get the value that is used when a node is selected. By default the selection value is the node itself. """ return node def get_text(self, node): """ Returns the label text for a node. """ return str(node) def can_set_text(self, node, text): """ Returns True if the node's label can be set. """ return len(text.strip()) > 0 def set_text(self, node, text): """ Sets the label text for a node. """ pass def is_collapsible(self, node): """ Returns True if the node is collapsible, otherwise False. """ return True def is_draggable(self, node): """ Returns True if the node is draggablee, otherwise False. """ return True def can_rename(self, node): """ Returns True if the node can be renamed, otherwise False. """ return False def is_editable(self, node): """ Returns True if the node is editable, otherwise False. If the node is editable, its text can be set via the UI. DEPRECATED: Use 'can_rename'. """ return self.can_rename(node) def is_expandable(self, node): """ Returns True if the node is expandanble, otherwise False. """ return True
class MView(MWorkbenchPart, PerspectiveItem): """ Mixin containing common code for toolkit-specific implementations. """ # 'IView' interface ---------------------------------------------------- # Is the view busy? (i.e., should the busy cursor (often an hourglass) be # displayed?). busy = Bool(False) # The category that the view belongs to (this can be used to group views # when they are displayed to the user). category = Str("General") # An image used to represent the view to the user (shown in the view tab # and in the view chooser etc). image = Image() # Whether the view is visible or not. visible = Bool(False) # ------------------------------------------------------------------------ # 'IWorkbenchPart' interface. # ------------------------------------------------------------------------ def _id_default(self): """ Trait initializer. """ id = "%s.%s" % (type(self).__module__, type(self).__name__) logger.warning("view %s has no Id - using <%s>" % (self, id)) # If no Id is specified then use the name. return id def _name_default(self): """ Trait initializer. """ name = camel_case_to_words(type(self).__name__) logger.warning("view %s has no name - using <%s>" % (self, name)) return name # ------------------------------------------------------------------------ # 'IView' interface. # ------------------------------------------------------------------------ def activate(self): """ Activate the view. """ self.window.activate_view(self) def hide(self): """ Hide the view. """ self.window.hide_view(self) def show(self): """ Show the view. """ self.window.show_view(self) return
class ImageView(ModelView): """A model view of an image with actions. """ #: The image model being viewed. model = Instance(ImageModel, (), allow_none=False) #: The image to display. image = Image() def rotate_left(self): """Rotate the image anticlockwise.""" self.model.rotate("anticlockwise") def rotate_right(self): """Rotate the image clockwise.""" self.model.rotate("clockwise") def flip_horizontal(self): """Flip the image horizontally.""" self.model.flip("horizontal") def flip_vertical(self): """Flip the image vertically.""" self.model.flip("vertical") def reload(self): """Reload the image from disk.""" self.model.load_image() @observe('model.data') def _update_image(self, event): self.image = ArrayImage(data=self.model.data) def _image_default(self): return ArrayImage(data=self.model.data) view = View( HSplit( Item( 'model.image_path', editor=FileEditor( dialog_style='open', filter=["*.png", "*.jpg", "*.jpeg"] ), style='custom', ), Item( 'image', editor=ImageEditor( scale=True, preserve_aspect_ratio=True, allow_upscaling=True, ), springy=True, resizable=True, ), show_labels=False, # NOTE: this id means the position of the sash will be saved id='viewer_split' ), resizable=True, toolbar=ToolBar( ActionGroup( Action( name="Rotate Left", tooltip="Rotate Left", action='rotate_left', image='rotate_left', ), Action( name="Rotate Right", tooltip="Rotate Right", action='rotate_right', image='rotate_right', ), Action( name="Flip Horizontally", tooltip="Flip Horizontally", action='flip_horizontal', image='flip_horizontal', ), Action( name="Flip Vertically", tooltip="Flip Vertically", action='flip_vertical', image='flip_vertical', ), name="Transpose Group", id="transpose_group", ), ActionGroup( Action( name="Denoise", tooltip="Denoise", action='denoise', image='denoise', ), name="Filter Group", id="filter_group", ), image_size=(24, 24), show_tool_names=False, ), menubar=MenuBar( Menu( Action(name="Revert Image", action="revert"), name="File", id="file_menu", ), Menu( ActionGroup( Action(name="Rotate Left", action='rotate_left'), Action(name="Rotate Right", action='rotate_right'), Action(name="Flip Horizontally", action='flip_horizontal'), Action(name="Flip Vertically", action='flip_vertical'), name="Transpose Group", id="transpose_group", ), ActionGroup( Action(name="Denoise", action='denoise'), name="Filter Group", id="filter_group", ), name="Edit", id="edit_menu", ), ), # NOTE: this id means the size of the window will be saved id='image_preview', )