def traits_view(self):
     """ Returns the default traits view for the object's class.
     """
     return View(
         VGroup(HGroup(
             VGroup(Label('Content', LabelTheme),
                    Item('content', editor=margin_editor),
                    show_labels=False),
             VGroup(Label('Label', LabelTheme),
                    Item('label', editor=margin_editor),
                    show_labels=False),
             VGroup(Label('Border', LabelTheme),
                    Item('border', editor=margin_editor),
                    show_labels=False)),
                HGroup(spring,
                       Item('editor.mode'),
                       '30',
                       Item('alignment', style='custom'),
                       spring,
                       group_theme=Theme('@std:GL5',
                                         content=(0, 0, -7, -4))),
                Item('editor.items',
                     show_label=False,
                     height=270,
                     editor=ListCanvasEditor(
                         theme='@std:GL5',
                         adapter=ThemeEditorAdapter(editor=self),
                         scrollable=True,
                         operations=['size'])),
                group_theme='@std:XG0'),
         kind='subpanel',
     )
Exemple #2
0
class _MarginEditor(UIEditor):
    """ A custom editor for Margin/Border instances.
    """

    # Mark the editor as being resizable:
    scrollable = True

    #-- Traits View Definitions ------------------------------------------------

    view = View(VGroup(Item('left', editor=slider_editor),
                       Item('right', editor=slider_editor),
                       Item('top', editor=slider_editor),
                       Item('bottom', editor=slider_editor),
                       group_theme='@std:GL5',
                       item_theme=Theme('@std:GreyItemInset',
                                        content=(-6, -6, -7, -2)),
                       label_theme=Theme('@std:BlueLabelInset',
                                         content=(-6, -4, -7, 0),
                                         label=(-3, 8))),
                kind='subpanel')
class ThemedVerticalNotebook(HasPrivateTraits):
    """ Defines a ThemedVerticalNotebook class for displaying a series of pages
        organized vertically, as opposed to horizontally like a standard
        notebook.
    """

    #-- Public Traits ----------------------------------------------------------

    # The theme to use for 'closed' notebook pages:
    closed_theme = ATheme(Theme('@std:notebook_close', content=0))

    # The theme to use for 'open' notebook pages:
    open_theme = ATheme(Theme('@std:notebook_open', content=0))

    # Allow multiple open pages at once?
    multiple_open = Bool(False)

    # Should the notebook be scrollable?
    scrollable = Bool(False)

    # Use double clicks (True) or single clicks (False) to open/close pages:
    double_click = Bool(False)

    # The pages contained in the notebook:
    pages = List(ThemedPage)

    # The traits UI editor this notebook is associated with (if any):
    editor = Instance(Editor)

    #-- Private Traits ---------------------------------------------------------

    # The wxPython control used to represent the notebook:
    control = Instance(wx.Window)

    #-- Public Methods ---------------------------------------------------------

    def create_control(self, parent):
        """ Creates the underlying wxPython window used for the notebook.
        """
        # Create the correct type of window based on whether or not it should
        # be scrollable:
        if self.scrollable:
            self.control = control = TraitsUIScrolledPanel(parent)
            control.SetScrollRate(6, 6)
            control.SetSize(wx.Size(0, 0))
        else:
            self.control = control = TraitsUIPanel(parent, -1)

        control._image_slice = getattr(parent, '_image_slice', None)
        control.SetSizer(ThemedVerticalNotebookSizer(self))

        # Set up the painting event handlers:
        control.Bind(wx.EVT_ERASE_BACKGROUND, self._erase_background)
        control.Bind(wx.EVT_PAINT, self._paint)

        return control

    def create_page(self):
        """ Creates a new **ThemedPage** object representing a notebook page and
            returns it as the result.
        """
        return ThemedPage(notebook=self).set(closed_theme=self.closed_theme,
                                             open_theme=self.open_theme)

    def open(self, page):
        """ Handles opening a specified **ThemedPage** notebook page.
        """
        if (page is not None) and (not page.is_open):
            if not self.multiple_open:
                for a_page in self.pages:
                    a_page.is_open = False

            page.is_open = True

            self._refresh()

    def close(self, page):
        """ Handles closing a specified **ThemedPage** notebook page.
        """
        if (page is not None) and page.is_open:
            page.is_open = False
            self._refresh()

    #-- Trait Event Handlers ---------------------------------------------------

    def _pages_changed(self, old, new):
        """ Handles the notebook's pages being changed.
        """
        for page in old:
            page.close()

        self._refresh()

    def _pages_items_changed(self, event):
        """ Handles some of the notebook's pages being changed.
        """
        for page in event.removed:
            page.close()

        self._refresh()

    def _multiple_open_changed(self, multiple_open):
        """ Handles the 'multiple_open' flag being changed.
        """
        if not multiple_open:
            first = True
            for page in self.pages:
                if first and page.is_open:
                    first = False
                else:
                    page.is_open = False

        self._refresh()

    #-- wx.Python Event Handlers -----------------------------------------------

    def _erase_background(self, event):
        """ Do not erase the background here (do it in the 'on_paint' handler).
        """
        pass

    def _paint(self, event):
        """ Paint the background using the associated ImageSlice object.
        """
        paint_parent(wx.PaintDC(self.control), self.control)

    #-- Private Methods --------------------------------------------------------

    def _refresh(self):
        """ Refresh the layout and contents of the notebook.
        """
        control = self.control
        if control is not None:
            # Set the virtual size of the canvas (so scroll bars work right):
            sizer = control.GetSizer()
            if control.GetSize().Get()[0] == 0:
                control.SetSize(sizer.CalcInit())
            control.SetVirtualSize(sizer.CalcMin())
            control.Layout()
            control.Refresh()
class ScatterPlot2(Template):

    #-- Template Traits --------------------------------------------------------

    # The title of the plot:
    title = TStr('Dual Scatter Plots')

    # The type of marker to use.  This is a mapped trait using strings as the
    # keys:
    marker = marker_trait(template='copy', event='update')

    # The pixel size of the marker (doesn't include the thickness of the
    # outline):
    marker_size = TRange(1, 5, 1, event='update')

    # The thickness, in pixels, of the outline to draw around the marker.  If
    # this is 0, no outline will be drawn.
    line_width = TRange(0.0, 5.0, 1.0)

    # The fill color of the marker:
    color = TColor('red', event='update')

    # The color of the outline to draw around the marker
    outline_color = TColor('black', event='update')

    # The amount of space between plots:
    spacing = TRange(0.0, 20.0, 0.0)

    # The contained scatter plots:
    scatter_plot_1 = TInstance(ScatterPlot, ())
    scatter_plot_2 = TInstance(ScatterPlot, ())

    #-- Derived Traits ---------------------------------------------------------

    plot = TDerived

    #-- Traits UI Views --------------------------------------------------------

    # The scatter plot view:
    template_view = View(VGroup(
        Item('title',
             show_label=False,
             style='readonly',
             editor=ThemedTextEditor(theme=Theme('@GBB', alignment='center'))),
        Item('plot',
             show_label=False,
             resizable=True,
             editor=EnableEditor(),
             item_theme=Theme('@GF5', margins=0))),
                         resizable=True)

    # The scatter plot options view:
    options_view = View(
        VGroup(
            VGroup(Label('Scatter Plot Options',
                         item_theme=Theme('@GBB', alignment='center')),
                   show_labels=False),
            VGroup(Item('title', editor=TextEditor()),
                   Item('marker'),
                   Item('marker_size', editor=ThemedSliderEditor()),
                   Item('line_width',
                        label='Line Width',
                        editor=ThemedSliderEditor()),
                   Item('spacing', editor=ThemedSliderEditor()),
                   Item('color', label='Fill Color'),
                   Item('outline_color', label='Outline Color'),
                   group_theme=Theme('@GF5', margins=(-5, -1)),
                   item_theme=Theme('@G0B', margins=0))))

    #-- ITemplate Interface Implementation -------------------------------------

    def activate_template(self):
        """ Converts all contained 'TDerived' objects to real objects using the
            template traits of the object. This method must be overridden in
            subclasses.

            Returns
            -------
            None
        """
        plots = [
            p for p in [self.scatter_plot_1.plot, self.scatter_plot_2.plot]
            if p is not None
        ]
        if len(plots) == 2:
            self.plot = HPlotContainer(spacing=self.spacing)
            self.plot.add(*plots)
        elif len(plots) == 1:
            self.plot = plots[0]

    #-- Default Values ---------------------------------------------------------

    def _scatter_plot_1_default(self):
        """ Returns the default value for the first scatter plot.
        """
        result = ScatterPlot()
        result.index.description = 'Shared Plot Index'
        result.value.description += ' 1'

        return result

    def _scatter_plot_2_default(self):
        """ Returns the default value for the second scatter plot.
        """
        result = ScatterPlot(index=self.scatter_plot_1.index)
        result.value.description += ' 2'
        result.value.optional = True

        return result

    #-- Trait Event Handlers ---------------------------------------------------

    def _update_changed(self, name, old, new):
        """ Handles a plot option being changed.
        """
        setattr(self.scatter_plot_1, name, new)
        setattr(self.scatter_plot_2, name, new)
        self.plot = Undefined

    def _spacing_changed(self, spacing):
        """ Handles the spacing between plots being changed.
        """
        self.plot = Undefined
Exemple #5
0
class ScatterPlot ( Template ):

    #-- Template Traits --------------------------------------------------------

    # The plot index data source:
    index = TDataSource

    # The plot value data source:
    value = TDataSource

    # The title of the plot:
    title = TStr( 'Scatter Plot' )

    # The type of marker to use.  This is a mapped trait using strings as the
    # keys:
    marker = marker_trait( template = 'copy', event = 'update' )

    # The pixel size of the marker (doesn't include the thickness of the
    # outline):
    marker_size = TRange( 1, 5, 1, event = 'update' )

    # The thickness, in pixels, of the outline to draw around the marker.  If
    # this is 0, no outline will be drawn.
    line_width = TRange( 0.0, 5.0, 1.0 )

    # The fill color of the marker:
    color = TColor( 'red', event = 'update' )

    # The color of the outline to draw around the marker
    outline_color = TColor( 'black', event = 'update' )

    #-- Derived Traits ---------------------------------------------------------

    plot = TDerived # Instance( ScatterPlot )

    #-- Traits UI Views --------------------------------------------------------

    # The scatter plot view:
    template_view = View(
        VGroup(
            Item( 'title',
                  show_label = False,
                  style      = 'readonly',
                  editor     = ThemedTextEditor(
                                 theme = Theme( '@GBB', alignment = 'center' ) )
            ),
            Item( 'plot',
                  show_label = False,
                  resizable  = True,
                  editor     = EnableEditor(),
                  item_theme = Theme( '@GF5', margins = 0 )
            )
        ),
        resizable = True
    )

    # The scatter plot options view:
    options_view = View(
        VGroup(
            VGroup(
                Label( 'Scatter Plot Options',
                       item_theme = Theme( '@GBB', alignment = 'center' ) ),
                show_labels = False
            ),
            VGroup(
                Item( 'title', editor = TextEditor() ),
                Item( 'marker' ),
                Item( 'marker_size', editor = ThemedSliderEditor() ),
                Item( 'line_width',
                      label  = 'Line Width',
                      editor = ThemedSliderEditor() ),
                Item( 'color',         label = 'Fill Color' ),
                Item( 'outline_color', label = 'Outline Color' ),
                group_theme = Theme( '@GF5', margins = ( -5, -1 ) ),
                item_theme  = Theme( '@G0B', margins = 0 )
            )
        )
    )

    #-- Default Values ---------------------------------------------------------

    def _index_default ( self ):
        """ Returns the default value for the 'index' trait.
        """
        return TemplateDataSource(
                   items       = [ ValueDataNameItem( name    = 'index',
                                                      flatten = True ) ],
                   description = 'Scatter Plot Index' )

    def _value_default ( self ):
        """ Returns the default value for the 'value' trait.
        """
        return TemplateDataSource(
                   items       = [ ValueDataNameItem( name    = 'value',
                                                      flatten = True ) ],
                   description = 'Scatter Plot Value' )

    #-- ITemplate Interface Implementation -------------------------------------

    def activate_template ( self ):
        """ Converts all contained 'TDerived' objects to real objects using the
            template traits of the object. This method must be overridden in
            subclasses.

            Returns
            -------
            None
        """
        # If our data sources are still unbound, then just exit; someone must
        # have marked them as optional:
        if ((self.index.context_data is Undefined) or
            (self.value.context_data is Undefined)):
            return

        # Create a plot data object and give it this data:
        pd = ArrayPlotData()
        pd.set_data( 'index', self.index.context_data )
        pd.set_data( 'value', self.value.context_data )

        # Create the plot:
        self.plot = plot = Plot( pd )
        plot.plot(      ( 'index', 'value' ),
                        type           = 'scatter',
                        index_sort     = 'ascending',
                        marker         = self.marker,
                        color          = self.color,
                        outline_color  = self.outline_color,
                        marker_size    = self.marker_size,
                        line_width     = self.line_width,
                        bgcolor        = 'white' )
        plot.trait_set( padding_left   = 50,
                        padding_right  = 0,
                        padding_top    = 0,
                        padding_bottom = 20 )

        # Attach some tools to the plot:
        plot.tools.append( PanTool( plot, constrain_key = 'shift' ) )
        zoom = SimpleZoom( component = plot, tool_mode = 'box',
                           always_on = False )
        plot.overlays.append( zoom )

    #-- Trait Event Handlers ---------------------------------------------------

    def _update_changed ( self ):
        """ Handles a plot option being changed.
        """
        self.plot = Undefined
class TemplateView ( HasPrivateTraits ):
    """ A feature-based Traits UI plug-in for viewing templates.
    """

    #-- Public Traits ----------------------------------------------------------

    # The name of the plugin:
    name = Str( 'Template View' )

    # The data context supplying the data to be viewed:
    context = Instance( ITemplateDataContext,
                        connect = 'to: data context' )

    # The name of the file containing a template view:
    file_name = File( drop_file = DropFile(
                     extensions = [ '.py', '.tv', '.las' ],
                     tooltip = 'Drop a LAS data file, a saved view template '
                               'or a Python source file containing a view '
                               'template here.' ),
                     connect = 'to: template view' )

    # The template to view:
    template = Instance( ITemplate )

    #-- Private Traits ---------------------------------------------------------

    # The name of the file to save the template in:
    save_file_name = File

    # The current data names:
    data_names = Instance( TemplateDataNames )

    # The TemplateDataNames or Message being viewed:
    names_view = Any( no_context )

    # The name of the most recently loaded template file:
    template_file_name = File

    # The template or message being viewed:
    template_view = Any( no_template )

    # The options view for the currently active template:
    options_view = Any( no_options )

    # The event fired when the user wants to save the template:
    save_template = Button( 'Save Template' )

    #-- Traits View Definitions ------------------------------------------------

    view = View(
        VGroup(
            HGroup(
                Item( 'file_name', show_label = False, width = 350 ),
                TButton( 'save_template',
                      label        = 'Save Template',
                      enabled_when = 'template is not None' ),
                group_theme = Theme( '@GFB', margins = ( -7, -5 ) )
            ),
            Tabbed(
                VGroup(
                    '8',
                    Label( 'Data Bindings',
                           item_theme = Theme( '@GBB', alignment = 'center' )
                    ),
                    Item( 'names_view',
                          style      = 'custom',
                          resizable  = True,
                          editor     = InstanceEditor(),
                          export     = 'DockWindowShell',
                          item_theme = Theme( '@GFB', margins = ( -5, -1 ) )
                    ),
                    label       = 'Data Bindings',
                    show_labels = False
                ),
                Item( 'template_view',
                      label     = 'Template View',
                      style     = 'custom',
                      resizable = True,
                      editor    = InstanceEditor( view = 'template_view' ),
                      export    = 'DockWindowShell'
                ),
                Item( 'options_view',
                      label     = 'Template Options',
                      style     = 'custom',
                      resizable = True,
                      editor    = InstanceEditor( view = 'options_view' ),
                      export    = 'DockWindowShell'
                ),
                id          = 'tabbed',
                dock        = 'horizontal',
                show_labels = False
            ),
        ),
        id = 'template.test.template_view.TemplateView'
    )

    #-- Trait Event Handlers ---------------------------------------------------

    def _context_changed ( self, context ):
        """ Handles the 'context' trait being changed.
        """
        if context is None:
            self.names_view = no_context
        elif self.template is None:
            self.names_view = no_template
        else:
            self._create_view()

    def _template_changed ( self, template ):
        """ Handles the 'template' trait being changed.
        """
        if self.context is None:
            self.template_view = no_context
        else:
            self._create_view()

    def _file_name_changed ( self, file_name ):
        """ Handles the 'file_name' trait being changed.
        """
        ext = splitext( file_name )[1]
        if ext == '.py':
            self._load_python_template( file_name )
        elif ext == '.tv':
            self._load_pickled_template( file_name )
        elif ext == '.las':
            self._load_las_file( file_name )
        else:
            # fixme: Display an informational message here...
            pass

    def _save_template_changed ( self ):
        """ Handles the user clicking the 'Save Template' button.
        """
        self._save_pickled_template()

    @on_trait_change( 'data_names.unresolved_data_names' )
    def _on_unresolved_data_names ( self ):
        if len( self.data_names.unresolved_data_names ) == 0:
            self._create_object_view()
        elif not isinstance( self.template_view, Message ):
            self.template_view = no_bindings
            self.options_view  = no_options

    @on_trait_change( 'template.template_mutated?' )
    def _on_template_mutated ( self ):
        """ Handles a mutable template changing.
        """
        if self.context is not None:
            self._create_view()

    #-- Private Methods --------------------------------------------------------

    def _load_python_template ( self, file_name ):
        """ Attempts to load a template from a Python source file.
        """
        path, name    = split( file_name )
        sys.path[0:0] = [ path ]
        try:
            ###values = {}
            module_name, ext = splitext( name )
            module = __import__( module_name )
            values = module.__dict__
            ###execfile( file_name, values )
            template = values.get( 'template' )
            if template is None:
                templates = []
                for value in values.values():
                    try:
                        if (issubclass( value, Template ) and
                            ###(value.__module__ == '__builtin__')):
                            (value.__module__ == module_name)):
                            templates.append( value )
                    except:
                        pass

                for i, template in enumerate( templates ):
                    for t in templates[ i + 1: ]:
                        if issubclass( template, t ):
                            break
                    else:
                        break
                else:
                    self.template_view = no_template_found
                    return

            if not isinstance( template, Template ):
                template = template()

            self.template           = template
            self.template_file_name = file_name

        except Exception as excp:
            self.template_view = Message( str( excp ) )

        # Clean up the Python path:
        del sys.path[0]

    def _load_pickled_template ( self, file_name ):
        """ Attempts to load a template from a pickle.
        """
        # fixme: Implement this...load template from .tv pickle file.
        fh     = None
        delete = False
        try:
            fh            = open( file_name, 'rb' )
            file_name     = load( fh )
            path, name    = split( file_name )
            sys.path[0:0] = [ path ]
            delete        = True
            module_name, ext = splitext( name )
            module = __import__( module_name )
            self.template = load( fh )
            self.template_file_name = file_name
        except Exception as excp:
            import traceback
            traceback.print_exc()
            self.template_view = Message( str( excp ) )

        if fh is not None:
            fh.close()

        if delete:
            del sys.path[0]

    def _load_las_file ( self, file_name ):
        """ Creates a data context from the specified LAS file.
        """
        try:
            self.context = import_log_files( file_name, 'las' )
        except Exception as excp:
            self.names_view = Message( str( excp ) )

    def _save_pickled_template ( self ):
        file_name = self.save_file_name or self.file_name
        fd        = FileDialog(
                        action       = 'save as',
                        default_path = file_name )
                        #wildcard     = 'Template files (*.tv)|*.tv|' )
        if fd.open() == OK:
            self.save_file_name = file_name = fd.path
            fh = None
            try:
                fh = open( file_name, 'wb' )
                dump( self.template_file_name, fh, -1 )
                dump( self.template.template_from_object(), fh, -1 )
            except:
                # fixme: Display an informational message here...
                import traceback
                traceback.print_exc()

            if fh is not None:
                fh.close()

    def _create_view ( self ):
        """ Begins the process of creating a live view from a template and
            data context object.
        """
        self.data_names = self.names_view = nv = TemplateDataNames(
                              context    = self.context,
                              data_names = self.template.names_from_template() )

        if len( nv.unresolved_data_names ) == 0:
            self._create_object_view()
        else:
            self.template_view = no_bindings

    def _create_object_view ( self ):
        """ Create the object view from the current template.
        """
        self.template.object_from_template()
        self.template_view = self.options_view = self.template
class ScatterPlotNM(MutableTemplate):

    #-- Template Traits --------------------------------------------------------

    # The title of the plot:
    title = TStr('NxM Scatter Plots')

    # The type of marker to use.  This is a mapped trait using strings as the
    # keys:
    marker = marker_trait(template='copy', event='update')

    # The pixel size of the marker (doesn't include the thickness of the
    # outline):
    marker_size = TRange(1, 5, 1, event='update')

    # The thickness, in pixels, of the outline to draw around the marker.  If
    # this is 0, no outline will be drawn.
    line_width = TRange(0.0, 5.0, 1.0)

    # The fill color of the marker:
    color = TColor('red', event='update')

    # The color of the outline to draw around the marker
    outline_color = TColor('black', event='update')

    # The number of rows of plots:
    rows = TRange(1, 3, 1, event='grid')

    # The number of columns of plots:
    columns = TRange(1, 5, 1, event='grid')

    # The contained scatter plots:
    scatter_plots = TList(ScatterPlot)

    #-- Derived Traits ---------------------------------------------------------

    plot = TDerived

    #-- Traits UI Views --------------------------------------------------------

    # The scatter plot view:
    template_view = View(
        VGroup(
            Item(
                'title',
                show_label=False,
                style='readonly',
                editor=ThemedTextEditor(theme=Theme(
                    '@GBB', alignment='center'))),
            Item(
                'plot',
                show_label=False,
                resizable=True,
                editor=EnableEditor(),
                item_theme=Theme(
                    '@GF5', margins=0))),
        resizable=True)

    # The scatter plot options view:
    options_view = View(
        VGroup(
            VGroup(
                Label(
                    'Scatter Plot Options',
                    item_theme=Theme(
                        '@GBB', alignment='center')),
                show_labels=False),
            VGroup(
                Item(
                    'title', editor=TextEditor()),
                Item('marker'),
                Item(
                    'marker_size', editor=ThemedSliderEditor()),
                Item(
                    'line_width',
                    label='Line Width',
                    editor=ThemedSliderEditor()),
                Item(
                    'color', label='Fill Color'),
                Item(
                    'outline_color', label='Outline Color'),
                Item(
                    'rows', editor=ThemedSliderEditor()),
                Item(
                    'columns', editor=ThemedSliderEditor()),
                group_theme=Theme(
                    '@GF5', margins=(-5, -1)),
                item_theme=Theme(
                    '@G0B', margins=0))))

    #-- ITemplate Interface Implementation -------------------------------------

    def activate_template(self):
        """ Converts all contained 'TDerived' objects to real objects using the
            template traits of the object. This method must be overridden in
            subclasses.

            Returns
            -------
            None
        """
        plots = []
        i = 0
        for r in range(self.rows):
            row = []
            for c in range(self.columns):
                plot = self.scatter_plots[i].plot
                if plot is None:
                    plot = PlotComponent()
                row.append(plot)
                i += 1
            plots.append(row)

        self.plot = GridPlotContainer(shape=(self.rows, self.columns))
        self.plot.component_grid = plots

    #-- Default Values ---------------------------------------------------------

    def _scatter_plots_default(self):
        """ Returns the default value for the scatter plots list.
        """
        plots = []
        for i in range(self.rows * self.columns):
            plots.append(ScatterPlot())

        self._update_plots(plots)

        return plots

    #-- Trait Event Handlers ---------------------------------------------------

    def _update_changed(self, name, old, new):
        """ Handles a plot option being changed.
        """
        for sp in self.scatter_plots:
            setattr(sp, name, new)

        self.plot = Undefined

    def _grid_changed(self):
        """ Handles the grid size being changed.
        """
        n = self.rows * self.columns
        plots = self.scatter_plots
        if n < len(plots):
            self.scatter_plots = plots[:n]
        else:
            for j in range(len(plots), n):
                plots.append(ScatterPlot())

        self._update_plots(plots)

        self.template_mutated = True

    #-- Private Methods --------------------------------------------------------

    def _update_plots(self, plots):
        """ Update the data sources for all of the current plots.
        """
        index = None
        i = 0
        for r in range(self.rows):
            for c in range(self.columns):
                sp = plots[i]
                i += 1
                desc = sp.value.description
                col = desc.rfind('[')
                if col >= 0:
                    desc = desc[:col]
                sp.value.description = '%s[%d,%d]' % (desc, r, c)
                sp.value.optional = True

                if index is None:
                    index = sp.index
                    index.description = 'Shared Plot Index'
                    index.optional = True
                else:
                    sp.index = index
class LibraryManager(HasPrivateTraits):

    # The list of image volumes currently being managed:
    volumes = List(VolumeManager)

    #-- Traits View Defnitions -------------------------------------------------

    view = View(
        Item('volumes',
             show_label=False,
             editor=ThemedVerticalNotebookEditor(closed_theme=Theme(
                 '@std:GL5', content=(0, 0, -2, 0), alignment='center'),
                                                 open_theme='@std:GL5TB',
                                                 multiple_open=True,
                                                 scrollable=True,
                                                 double_click=False,
                                                 page_name='.name'),
             item_theme='@std:XG1'))

    #-- Public Methods ---------------------------------------------------------

    def add(self, image):
        """ Adds a specified *image* **ImageInfo** object to the library
            manager's collection.
        """
        vm = self._find(image)
        if not isinstance(vm, VolumeManager):
            vm = VolumeManager(volume=vm)
            self.volumes.append(vm)

        vm.add(image)

    def remove(self, image):
        """ Removes a reference to a specified *image* **ImageInfo** object from
            the library manager's collection.
        """
        vm = self._find(image)
        if isinstance(vm, VolumeManager):
            vm.remove(image)

    #-- Traits Event Handlers --------------------------------------------------

    @on_trait_change('volumes:is_empty')
    def _volume_empty(self, volume, name, old, empty):
        """ Handles a VolumeManager becoming empty.
        """
        if empty:
            self.volumes.remove(volume)

    #-- Private Methods --------------------------------------------------------

    def _find(self, image):
        """ Attempts to return the **ImageVolume** object corresponding to a
            specified *image **ImageInfo** object.
        """
        volume = ImageLibrary.find_volume(image.image_name)
        for vm in self.volumes:
            if volume is vm.volume:
                return vm

        return volume
Exemple #9
0
from traitsui.api \
    import Item, Theme, TitleEditor, ButtonEditor

#-------------------------------------------------------------------------------
#  Themes:
#-------------------------------------------------------------------------------

# An item that displays the tool title or information:
class TTitle ( Item ):
    show_label = Constant( False )
    editor     = TitleEditor()

# A standard themed button:
class TButton ( Item ):
    show_label = Constant( False )
    editor     = Instance( ButtonEditor, () )
    image      = Delegate( 'editor', modify = True )

# A label theme:
LabelTheme = Theme( '@std:GL5', label     = ( -3, 10 ),
                                content   = ( 0, -5 ),
                                alignment = 'center' )

# An inset label theme:
InsetTheme = Theme( '@std:inset_grey', content   = -6,
                                       label     = ( 6, 6, 9, 0 ),
                                       alignment = 'center', )