Repository URL to install this package:
Version:
6.1.1 ▾
|
#------------------------------------------------------------------------------
#
# Copyright (c) 2005, Enthought, Inc.
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in enthought/LICENSE.txt and may be redistributed only
# under the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
#
# Author: David C. Morrill
# Date: 10/21/2004
#
#------------------------------------------------------------------------------
""" Defines the base class for wxPython editors.
"""
#-------------------------------------------------------------------------
# Imports:
#-------------------------------------------------------------------------
from __future__ import absolute_import
import wx
from traits.api \
import HasTraits, Int, Instance, Str, Callable
# CIRCULAR IMPORT FIXME:
# We are importing from the source instead of from the api in order to
# avoid circular imports. The 'toolkit.py' file imports from 'helper' which in
# turns imports from this file. Therefore, trying to import
# 'traitsui.wx' (which imports the toolkit) will lead to importing
# all of the editor factories declared in traitsui.api. In addition,# some of the editor factories have a Color trait defined, and this will lead
# to an import of the wx 'toolkit' causing a circular import problem.
# Another solution could be to move the GroupEditor object from helper to this
# file.
from traitsui.editor \
import Editor as UIEditor
from .constants \
import WindowColor, OKColor, ErrorColor
#-------------------------------------------------------------------------
# 'Editor' class:
#-------------------------------------------------------------------------
class Editor(UIEditor):
""" Base class for wxPython editors for Traits-based UIs.
"""
#-------------------------------------------------------------------------
# Trait definitions:
#-------------------------------------------------------------------------
# Style for embedding control in a sizer:
layout_style = Int(wx.EXPAND)
# The maximum extra padding that should be allowed around the editor:
border_size = Int(4)
#-------------------------------------------------------------------------
# Handles the 'control' trait being set:
#-------------------------------------------------------------------------
def _control_changed(self, control):
""" Handles the **control** trait being set.
"""
if control is not None:
control._editor = self
#-------------------------------------------------------------------------
# Assigns focus to the editor's underlying toolkit widget:
#-------------------------------------------------------------------------
def set_focus(self):
""" Assigns focus to the editor's underlying toolkit widget.
"""
if self.control is not None:
self.control.SetFocus()
#-------------------------------------------------------------------------
# Updates the editor when the object trait changes external to the editor:
#-------------------------------------------------------------------------
def update_editor(self):
""" Updates the editor when the object trait changes externally to the
editor.
"""
new_value = self.str_value
if self.control.GetValue() != new_value:
self.control.SetValue(new_value)
#-------------------------------------------------------------------------
# Handles an error that occurs while setting the object's trait value:
#-------------------------------------------------------------------------
def error(self, excp):
""" Handles an error that occurs while setting the object's trait value.
"""
dlg = wx.MessageDialog(self.control, str(excp),
self.description + ' value error',
wx.OK | wx.ICON_INFORMATION)
dlg.ShowModal()
dlg.Destroy()
#-------------------------------------------------------------------------
# Sets the tooltip for a specified control:
#-------------------------------------------------------------------------
def set_tooltip(self, control=None):
""" Sets the tooltip for a specified control.
"""
desc = self.description
if desc == '':
desc = self.object.base_trait(self.name).tooltip
if desc is None:
desc = self.object.base_trait(self.name).desc
if desc is None:
return False
desc = 'Specifies ' + desc
if control is None:
control = self.control
control.SetToolTipString(desc)
return True
#-------------------------------------------------------------------------
# Handles the 'enabled' state of the editor being changed:
#-------------------------------------------------------------------------
def _enabled_changed(self, enabled):
""" Handles the **enabled** state of the editor being changed.
"""
control = self.control
if control is not None:
control.Enable(enabled)
control.Refresh()
if self.label_control is not None:
self.label_control.Enable(enabled)
self.label_control.Refresh()
#-------------------------------------------------------------------------
# Handles the 'visible' state of the editor being changed:
#-------------------------------------------------------------------------
def _visible_changed(self, visible):
""" Handles the **visible** state of the editor being changed.
"""
control = self.control
parent = control.GetParent()
# Handle the case where the item whose visibility has changed is a
# notebook page:
sizer = parent.GetSizer()
from pyface.dock.api import DockSizer
if isinstance(sizer, DockSizer):
dock_controls = sizer.GetContents().get_controls(False)
for dock_control in dock_controls:
if dock_control.control is control:
dock_control.visible = visible
sizer.Layout()
# Handle a normal item:
else:
if self.label_control is not None:
self.label_control.Show(visible)
control.Show(visible)
# If only control.Layout() is called there are certain cases where
# the newly visible items are sized incorrectly (see ticket 1797)
if parent is None:
control.Layout()
else:
parent.Layout()
#-------------------------------------------------------------------------
# Returns the editor's control for indicating error status:
#-------------------------------------------------------------------------
def get_error_control(self):
""" Returns the editor's control for indicating error status.
"""
return self.control
#-------------------------------------------------------------------------
# Returns whether or not the editor is in an error state:
#-------------------------------------------------------------------------
def in_error_state(self):
""" Returns whether or not the editor is in an error state.
"""
return False
#-------------------------------------------------------------------------
# Sets the editor's current error state:
#-------------------------------------------------------------------------
def set_error_state(self, state=None, control=None):
""" Sets the editor's current error state.
"""
if state is None:
state = self.invalid
state = state or self.in_error_state()
if control is None:
control = self.get_error_control() or []
if not isinstance(control, list):
control = [control]
for item in control:
if state:
color = ErrorColor
if getattr(item, '_ok_color', None) is None:
item._ok_color = item.GetBackgroundColour()
else:
color = getattr(item, '_ok_color', None)
if color is None:
color = OKColor
if isinstance(item, wx.Panel):
color = WindowColor
item.SetBackgroundColour(color)
item.Refresh()
#-------------------------------------------------------------------------
# Handles the editor's invalid state changing:
#-------------------------------------------------------------------------
def _invalid_changed(self, state):
""" Handles the editor's invalid state changing.
"""
self.set_error_state()
#-------------------------------------------------------------------------
# 'EditorWithList' class:
#-------------------------------------------------------------------------
class EditorWithList(Editor):
""" Editor for an object that contains a list.
"""
#-------------------------------------------------------------------------
# Trait definitions:
#-------------------------------------------------------------------------
# Object containing the list being monitored
list_object = Instance(HasTraits)
# Name of the monitored trait
list_name = Str
# Function used to evaluate the current list object value:
list_value = Callable
#-------------------------------------------------------------------------
# Initializes the object:
#-------------------------------------------------------------------------
def init(self, parent):
""" Initializes the object.
"""
factory = self.factory
name = factory.name
if name != '':
self.list_object, self.list_name, self.list_value = \
self.parse_extended_name(name)
else:
self.list_object, self.list_name = factory, 'values'
self.list_value = lambda: factory.values
self.list_object.on_trait_change(
self._list_updated, self.list_name + '[]', dispatch='ui')
self._list_updated()
#-------------------------------------------------------------------------
# Disconnects the listeners set up by the constructor:
#-------------------------------------------------------------------------
def dispose(self):
""" Disconnects the listeners set up by the constructor.
"""
self.list_object.on_trait_change(
self._list_updated, self.list_name + '[]', remove=True)
super(EditorWithList, self).dispose()
#-------------------------------------------------------------------------
# Handles the monitored trait being updated:
#-------------------------------------------------------------------------
def _list_updated(self):
""" Handles the monitored trait being updated.
"""
self.list_updated(self.list_value())
#-------------------------------------------------------------------------
# Handles the monitored list being updated:
#-------------------------------------------------------------------------
def list_updated(self, values):
""" Handles the monitored list being updated.
"""
raise NotImplementedError
#-------------------------------------------------------------------------
# 'EditorFromView' class:
#-------------------------------------------------------------------------
class EditorFromView(Editor):
""" An editor generated from a View object.
"""
#-------------------------------------------------------------------------
# Initializes the object:
#-------------------------------------------------------------------------
def init(self, parent):
""" Initializes the object.
"""
self._ui = ui = self.init_ui(parent)
if ui.history is None:
ui.history = self.ui.history
self.control = ui.control
#-------------------------------------------------------------------------
# Creates and returns the traits UI defined by this editor:
# (Must be overridden by a subclass):
#-------------------------------------------------------------------------
def init_ui(self, parent):
""" Creates and returns the traits UI defined by this editor.
(Must be overridden by a subclass).
"""
raise NotImplementedError
#-------------------------------------------------------------------------
# Updates the editor when the object trait changes external to the editor:
#-------------------------------------------------------------------------
def update_editor(self):
""" Updates the editor when the object trait changes externally to the
editor.
"""
# Normally nothing needs to be done here, since it should all be handled
# by the editor's internally created traits UI:
pass
#-------------------------------------------------------------------------
# Dispose of the editor:
#-------------------------------------------------------------------------
def dispose(self):
""" Disposes of the editor.
"""
self._ui.dispose()
super(EditorFromView, self).dispose()