class WorkflowDockPane(TraitsDockPane): id = 'edu.mit.synbio.cytoflowgui.workflow_pane' name = "Workflow" # the application instance from which to get plugin instances plugins = List(IOperationPlugin) # controller handler = Instance(WorkflowController) # the size of the plugin toolbar images IN INCHES image_size = Tuple((0.33, 0.33)) def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ dpi = self.control.physicalDpiX() image_size = (int(self.image_size[0] * dpi), int(self.image_size[1] * dpi)) self.toolbar = ToolBarManager(orientation='vertical', show_tool_names=False, image_size=image_size) for plugin in self.plugins: # don't include the import plugin if plugin.id == 'edu.mit.synbio.cytoflowgui.op_plugins.import': continue task_action = TaskAction( name=plugin.short_name, on_perform=lambda plugin_id=plugin.operation_id: self.handler. add_operation(plugin_id), image=plugin.get_icon()) self.toolbar.append(task_action) # see the comment in cytoflowgui.view_pane for an explanation of this # HintedMainWindow business. window = HintedMainWindow() window.addToolBar( QtCore.Qt.LeftToolBarArea, # @UndefinedVariable self.toolbar.create_tool_bar(window)) # construct the view self.ui = self.handler.edit_traits(view='workflow_traits_view', context=self.model, kind='subpanel', parent=window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) return window
class WorkflowDockPane(TraitsDockPane): id = 'edu.mit.synbio.cytoflowgui.workflow_pane' name = "Workflow" # the application instance from which to get plugin instances plugins = List(IOperationPlugin) # the task serving as the dock pane's controller task = Instance(Task) def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ self.toolbar = ToolBarManager(orientation='vertical', show_tool_names=False, image_size=(32, 32)) for plugin in self.plugins: # don't include the import plugin if plugin.id == 'edu.mit.synbio.cytoflowgui.op_plugins.import': continue task_action = TaskAction( name=plugin.short_name, on_perform=lambda pid=plugin.id: self.task.add_operation(pid), image=plugin.get_icon()) self.toolbar.append(task_action) window = QtGui.QMainWindow() # @UndefinedVariable window.addToolBar( QtCore.Qt.LeftToolBarArea, # @UndefinedVariable self.toolbar.create_tool_bar(window)) self.ui = self.model.edit_traits(view='operations_traits', kind='subpanel', parent=window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) return window
class WorkflowDockPane(TraitsDockPane): id = 'edu.mit.synbio.workflow_pane' name = "Workflow" # the application instance from which to get plugin instances plugins = List(IOperationPlugin) # the task serving as the dock pane's controller task = Instance(Task) def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ self.toolbar = ToolBarManager(orientation='vertical', show_tool_names = False, image_size = (32, 32)) for plugin in self.plugins: task_action = TaskAction(name=plugin.short_name, on_perform = lambda pid=plugin.id: self.task.add_operation(pid), image = plugin.get_icon()) self.toolbar.append(task_action) window = QtGui.QMainWindow() window.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolbar.create_tool_bar(window)) self.ui = self.model.edit_traits(view = 'operations_traits', kind = 'subpanel', parent = window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) return window
class ViewDockPane(DockPane): """ A DockPane to manipulate the traits of the currently selected view. """ #### TaskPane interface ############################################### id = 'edu.mit.synbio.view_traits_pane' name = 'View Properties' # the Task that serves as the controller task = Instance('flow_task.FlowTask') # the IViewPlugins that the user can possibly choose. set by the controller # as we're instantiated view_plugins = List(IViewPlugin) # changed depending on whether the selected wi in the model is valid. # would use a direct listener, but valid gets changed outside # the UI thread and we can't change UI things from other threads. enabled = Bool # the UI object associated with the object we're editing. # NOTE: we don't maintain a reference to the IView itself... _ui = Instance(UI) _current_view_id = Str # the layout that manages the pane _layout = Instance(QtGui.QVBoxLayout) # the main panel control _control = Instance(QtGui.QWidget) # the entire window (plus toolbar) _window = Instance(QtGui.QMainWindow) # actions associated with views _actions = Dict(Str, TaskAction) # the default action _default_action = Instance(TaskAction) ########################################################################### # 'ITaskPane' interface. ########################################################################### def create(self, *args, **kwargs): super(ViewDockPane, self).create(*args, **kwargs) self.on_trait_change(self._set_enabled, 'enabled', dispatch = 'ui') def destroy(self): """ Destroy the toolkit-specific control that represents the pane. """ # Destroy the Traits-generated control inside the dock control. if self._ui is not None: self._ui.dispose() self._ui = None # Destroy the dock control. super(ViewDockPane, self).destroy() ########################################################################### # 'IDockPane' interface. ########################################################################### def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ self.toolbar = ToolBarManager(orientation = 'vertical', show_tool_names = False, image_size = (32, 32)) self._default_action = TaskAction(name = "Default\nView", on_perform = lambda: self.task.set_current_view("default"), style = 'toggle', visible = False) self._actions["default"] = self._default_action self.toolbar.append(self._default_action) for plugin in self.plugins: task_action = TaskAction(name = plugin.short_name, on_perform = lambda id=plugin.view_id: self.task.set_current_view(id), image = plugin.get_icon(), style = 'toggle') self._actions[plugin.view_id] = task_action self.toolbar.append(task_action) self._window = QtGui.QMainWindow() tb = self.toolbar.create_tool_bar(self._window) self._window.addToolBar(QtCore.Qt.RightToolBarArea, tb) # the top-level control scroll_area = QtGui.QScrollArea() scroll_area.setFrameShape(QtGui.QFrame.NoFrame) scroll_area.setWidgetResizable(True) # the panel that we can scroll around self._control = QtGui.QWidget() # the panel's layout manager self._layout = QtGui.QVBoxLayout() self._control.setLayout(self._layout) scroll_area.setWidget(self._control) self._window.setCentralWidget(scroll_area) self._window.setParent(parent) parent.setWidget(self._window) self._window.setEnabled(False) return self._window # @on_trait_change('_current_view_id') # def _picker_current_view_changed(self, obj, name, old, new): # if new: # self.task.set_current_view(new) def _set_enabled(self, obj, name, old, new): self._window.setEnabled(new) @on_trait_change('task:model:selected.valid') def _on_model_valid_changed(self, obj, name, old, new): # print "valid changed: {0}".format(threading.current_thread()) if not new: return if name == 'selected': new = new.valid # redirect to the UI thread self.enabled = True if new == "valid" else False @on_trait_change('task:model:selected.current_view') def _model_current_view_changed(self, obj, name, old, new): # at the moment, this only gets called from the UI thread, so we can # do UI things. we get notified if *either* the currently selected # workflowitem *or* the current view changes. # untoggle everything on the toolbar for action in self._actions.itervalues(): action.checked = False if name == 'selected': old = old.current_view if old else None new = new.current_view if new else None if old: # remove the view's widget from the layout self._layout.takeAt(self._layout.indexOf(self._ui.control)) # and the spacer self._layout.takeAt(self._layout.count() - 1) self._ui.control.setParent(None) self._ui.dispose() if new: if new == self.task.model.selected.default_view: self._default_action.checked = True else: self._actions[new.id].checked = True self._ui = new.handler.edit_traits(kind='subpanel', parent=self._control) self._layout.addWidget(self._ui.control) self._layout.addStretch(stretch = 1) self._current_view_id = new.id else: self._current_view_id = "" @on_trait_change('task:model:selected.default_view') def _default_view_changed(self, obj, name, old, new): old_view = (old.default_view if isinstance(obj, Workflow) and isinstance(old, WorkflowItem) else old) new_view = (new.default_view if isinstance(obj, Workflow) and isinstance(new, WorkflowItem) else new) if new_view is None: self._default_action.visible = False else: plugins = [x for x in self.task.op_plugins if x.operation_id == self.task.model.selected.operation.id] plugin = plugins[0] self._default_action.image = plugin.get_icon() self._default_action.visible = True # if old_view is not None: # old_id = old_view.id # del self._plugins_dict[old_id] # # if new_view is not None: # new_id = new_view.id # new_name = "{0} (Default)".format(new_view.friendly_id) # self._plugins_dict[new_id] = new_name
class ViewDockPane(TraitsDockPane): """ A DockPane to manipulate the traits of the currently selected view. """ #### TaskPane interface ############################################### id = 'edu.mit.synbio.view_traits_pane' name = 'View Properties' # the Task that serves as the controller task = Instance(Task) # the IViewPlugins that the user can possibly choose. set by the controller # as we're instantiated view_plugins = List(IViewPlugin) # changed depending on whether the selected wi in the model is valid. # would use a direct listener, but valid gets changed outside # the UI thread and we can't change UI things from other threads. enabled = Bool # the view's model. i would rather put these in Workflow, but traitsui # isn't smart about intermediate objects that could be None default_scale = util.ScaleEnum current_view_handler = Instance(Handler) # actions associated with views _actions = Dict(Str, TaskAction) # the default action _default_action = Instance(TaskAction) def default_traits_view(self): return View( Item('pane.current_view_handler', style='custom', show_label=False), Spring(), Label("Default scale"), Item('pane.default_scale', show_label=False)) def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ self.toolbar = ToolBarManager(orientation='vertical', show_tool_names=False, image_size=(32, 32)) self._default_action = TaskAction( name="Setup View", on_perform=lambda: self.task.set_current_view("default"), image=ImageResource('setup'), style='toggle', visible=False) self._actions["default"] = self._default_action self.toolbar.append(self._default_action) for plugin in self.plugins: task_action = TaskAction(name=plugin.short_name, on_perform=lambda id=plugin.view_id: self. task.set_current_view(id), image=plugin.get_icon(), style='toggle') self._actions[plugin.view_id] = task_action self.toolbar.append(task_action) window = QtGui.QMainWindow() window.addToolBar(QtCore.Qt.RightToolBarArea, self.toolbar.create_tool_bar(window)) self.ui = self.edit_traits(kind='subpanel', parent=window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) return window # @on_trait_change('_current_view_id') # def _picker_current_view_changed(self, obj, name, old, new): # if new: # self.task.set_current_view(new) # MAGIC: called when enabled is changed def _enabled_changed(self, name, old, new): self.ui.control.setEnabled(new) @on_trait_change('task:model:selected.status') def _on_model_status_changed(self, obj, name, old, new): if not new: return if name == 'selected': new = new.status # redirect to the UI thread self.enabled = True if new == "valid" else False # MAGIC: called when default_scale is changed def _default_scale_changed(self, new_scale): cytoflow.set_default_scale(new_scale) @on_trait_change('task:model:selected.current_view') def _model_current_view_changed(self, obj, name, old, new): # at the moment, this only gets called from the UI thread, so we can # do UI things. we get notified if *either* the currently selected # workflowitem *or* the current view changes. # untoggle everything on the toolbar for action in self._actions.itervalues(): action.checked = False if name == 'selected': old = old.current_view if old else None new = new.current_view if new else None try: self.current_view_handler = new.handler if new == self.task.model.selected.default_view: self._default_action.checked = True else: self._actions[new.id].checked = True except AttributeError: self.current_view_handler = None @on_trait_change('task:model:selected.default_view') def _default_view_changed(self, obj, name, old, new): new_view = (new.default_view if isinstance(obj, Workflow) and isinstance(new, WorkflowItem) else new) if new_view is None: self._default_action.visible = False else: self._default_action.visible = True
class ViewDockPane(TraitsDockPane): """ A DockPane to manipulate the traits of the currently selected view. """ #### TaskPane interface ############################################### id = 'edu.mit.synbio.cytoflowgui.view_traits_pane' name = 'View Properties' # the Task that serves as the controller task = Instance(Task) # the IViewPlugins that the user can possibly choose. set by the controller # as we're instantiated view_plugins = List(IViewPlugin) # changed depending on whether the selected wi in the model is valid. enabled = Bool(False) # the currently selected view id selected_view = Str # if there is a default view for the currently selected operation, this # is its view id default_view = Str # IN INCHES image_size = Tuple((0.33, 0.33)) # task actions associated with views _actions = Dict(Str, TaskAction) # the default task action _default_action = Instance(TaskAction) _window = Instance(QtGui.QMainWindow) def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ dpi = self.control.physicalDpiX() image_size = (int(self.image_size[0] * dpi), int(self.image_size[1] * dpi)) self.toolbar = ToolBarManager(orientation = 'vertical', show_tool_names = False, image_size = image_size) self._default_action = TaskAction(name = "Setup View", on_perform = lambda s=self: self.trait_set(selected_view = s.default_view), image = ImageResource('setup'), style = 'toggle', visible = False) self.toolbar.append(self._default_action) for plugin in self.plugins: task_action = TaskAction(name = plugin.short_name, on_perform = lambda view_id=plugin.view_id: self.trait_set(selected_view = view_id), image = plugin.get_icon(), style = 'toggle') self._actions[plugin.view_id] = task_action self.toolbar.append(task_action) self._window = window = HintedMainWindow() window.addToolBar(QtCore.Qt.RightToolBarArea, self.toolbar.create_tool_bar(window)) self.ui = self.model.edit_traits(view = 'selected_view_traits', kind = 'subpanel', parent = window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) window.setEnabled(False) return window @on_trait_change('enabled', enabled) def _enabled_changed(self, enabled): self._window.setEnabled(enabled) self.ui.control.setEnabled(enabled) @on_trait_change('default_view') def set_default_view(self, obj, name, old_view_id, new_view_id): if old_view_id: del self._actions[old_view_id] if new_view_id: self._actions[new_view_id] = self._default_action self._default_action.visible = (new_view_id != "") @on_trait_change('selected_view') def _selected_view_changed(self, view_id): # untoggle everything on the toolbar for action in self._actions.values(): action.checked = False # toggle the right button if view_id: self._actions[view_id].checked = True
class ViewDockPane(TraitsDockPane): """ A DockPane to manipulate the traits of the currently selected view. """ #### TaskPane interface ############################################### id = 'edu.mit.synbio.view_traits_pane' name = 'View Properties' # the Task that serves as the controller task = Instance(Task) # the IViewPlugins that the user can possibly choose. set by the controller # as we're instantiated view_plugins = List(IViewPlugin) # changed depending on whether the selected wi in the model is valid. # would use a direct listener, but valid gets changed outside # the UI thread and we can't change UI things from other threads. enabled = Bool(True) # actions associated with views _actions = Dict(Str, TaskAction) # the default action _default_action = Instance(TaskAction) def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ self.toolbar = ToolBarManager(orientation = 'vertical', show_tool_names = False, image_size = (32, 32)) self._default_action = TaskAction(name = "Setup View", on_perform = lambda: self.task.set_current_view("default"), image = ImageResource('setup'), style = 'toggle', visible = False) self._actions["default"] = self._default_action self.toolbar.append(self._default_action) for plugin in self.plugins: task_action = TaskAction(name = plugin.short_name, on_perform = lambda view_id=plugin.view_id: self.task.set_current_view(view_id), image = plugin.get_icon(), style = 'toggle') self._actions[plugin.view_id] = task_action self.toolbar.append(task_action) window = QtGui.QMainWindow() window.addToolBar(QtCore.Qt.RightToolBarArea, self.toolbar.create_tool_bar(window)) self.ui = self.model.edit_traits(view = 'selected_view_traits', kind = 'subpanel', parent = window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) return window # MAGIC: called when enabled is changed def _enabled_changed(self, name, old, new): self.ui.control.setEnabled(new) @on_trait_change('task:model:selected.current_view') def _model_current_view_changed(self, obj, name, old, new): # at the moment, this only gets called from the UI thread, so we can # do UI things. we get notified if *either* the currently selected # workflowitem *or* the current view changes. # untoggle everything on the toolbar for action in self._actions.itervalues(): action.checked = False if name == 'selected': old = old.current_view if old else None new = new.current_view if new else None # toggle the right button try: self.current_view_handler = new.handler if new == self.task.model.selected.default_view: self._default_action.checked = True else: self._actions[new.id].checked = True except AttributeError: self.current_view_handler = None @on_trait_change('task:model:selected.default_view') def _default_view_changed(self, obj, name, old, new): # TODO - this is ugly. fixme. new_view = (new.default_view if isinstance(obj, LocalWorkflow) and isinstance(new, WorkflowItem) else new) if new_view is None: self._default_action.visible = False else: self._default_action.visible = True
class WorkflowDockPane(DockPane): id = 'edu.mit.synbio.workflow_pane' name = "Workflow" # the workflow this pane is displaying model = Instance(Workflow) # the UI object associated with the TraitsUI view ui = Instance(UI) # the application instance from which to get plugin instances plugins = List(IOperationPlugin) # the task serving as the dock pane's controller task = Instance(Task) # an empty, unitialized view empty_view = View() ########################################################################### # 'ITaskPane' interface. ########################################################################### def destroy(self): """ Destroy the toolkit-specific control that represents the pane. """ # Destroy the Traits-generated control inside the dock control. if self.ui is not None: self.ui.dispose() self.ui = None # Destroy the dock control. super(WorkflowDockPane, self).destroy() ########################################################################### # 'IDockPane' interface. ########################################################################### def create_contents(self, parent): """ Create and return the toolkit-specific contents of the dock pane. """ self.toolbar = ToolBarManager(orientation='vertical', show_tool_names = False, image_size = (32, 32)) for plugin in self.plugins: task_action = TaskAction(name=plugin.short_name, on_perform = lambda id=plugin.id: self.task.add_operation(id), image = plugin.get_icon()) self.toolbar.append(task_action) window = QtGui.QMainWindow() window.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolbar.create_tool_bar(window)) self.ui = self.model.edit_traits(kind='subpanel', parent=window) window.setCentralWidget(self.ui.control) window.setParent(parent) parent.setWidget(window) return window