Skip to content
This repository has been archived by the owner on May 24, 2021. It is now read-only.

Feature traitsui item #215

Merged
merged 4 commits into from
Dec 8, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions enaml/qt/qt_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ def tool_bar_factory():
return QtToolBar


def traits_item_factory():
from .qt_traits_item import QtTraitsItem
return QtTraitsItem


def web_view_factory():
from .qt_web_view import QtWebView
return QtWebView
Expand Down Expand Up @@ -249,6 +254,7 @@ def register_default():
register('StackItem', stack_item_factory)
register('TimeSelector', time_selector_factory)
register('ToolBar', tool_bar_factory)
register('TraitsItem', traits_item_factory)
register('WebView', web_view_factory)
register('Window', window_factory)

76 changes: 76 additions & 0 deletions enaml/qt/qt_traits_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from .qt.QtCore import Qt, QMargins
from .qt.QtGui import QWidget, QVBoxLayout, QFrame
from .qt_control import QtControl


class QtTraitsItem(QtControl):
""" A Qt implementation of an Enaml TraitsItem.

"""
#--------------------------------------------------------------------------
# Setup Methods
#--------------------------------------------------------------------------
def create_widget(self, parent, tree):
""" Create the underlying label widget.

"""
widget = QFrame(parent)
layout = QVBoxLayout(widget)
layout.setContentsMargins(QMargins(0, 0, 0, 0))
return widget

def create(self, tree):
""" Create and initialize the underlying widget.

"""
super(QtTraitsItem, self).create(tree)
self.model = tree['model']
self.view = tree['view']
self.handler = tree['handler']
self.ui = None

def init_layout(self):
'''Create the Traits UI widget and add to our layout
'''
super(QtTraitsItem, self).init_layout()
# guard against using a named view that is not supported by the model
if isinstance(self.view, (str, unicode)):
if self.model.trait_view(self.view) is None:
self.view = ''
# remove any previous widget before adding a new one
if self.ui:
self.widget().layout().removeWidget(self.ui.control)
self.ui.control.hide()
self.ui = self.model.edit_traits(parent=self.widget(), view=self.view,
handler=self.handler, kind='subpanel')
# on qt, we must set this explicitly
self.ui.control.setParent(self.widget())
self.widget().layout().addWidget(self.ui.control)
# allow the widget to resize when the view is changed
size = self.ui.control.sizeHint()
self.set_minimum_size((size.width(), size.height()))
self.size_hint_updated()

#--------------------------------------------------------------------------
# Message Handlers
#--------------------------------------------------------------------------
def on_action_set_model(self, content):
""" Handle the 'set_model' action from the Enaml widget.

"""
self.model = content['model']
self.init_layout()

def on_action_set_handler(self, content):
""" Handle the 'set_handler' action from the Enaml widget.

"""
self.handler = content['handler']
self.init_layout()

def on_action_set_view(self, content):
""" Handle the 'set_view' action from the Enaml widget.

"""
self.view = content['view']
self.init_layout()
1 change: 1 addition & 0 deletions enaml/widgets/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#from .text_editor import TextEditor
from .time_selector import TimeSelector
from .tool_bar import ToolBar
from .traits_item import TraitsItem
from .web_view import WebView
from .window import Window

48 changes: 48 additions & 0 deletions enaml/widgets/traits_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#------------------------------------------------------------------------------
# Copyright (c) 2011, Enthought, Inc.
# All rights reserved.
#------------------------------------------------------------------------------
from traits.api import HasTraits, Instance, Any, Trait, Str

from .control import Control


class TraitsItem(Control):
""" A control to display a traitsui item

"""
#: The item being displayed
model = Instance(HasTraits)

# optional : the desired handler for the model
handler = Instance('traitsui.api.Handler')

# optional: the desired view for the model
view = Trait('', Str, Instance('traitsui.api.View'))

#: How strongly a component hugs it's contents' width. TraitsItems ignore
#: the width hug by default, so they expand freely in width.
hug_width = 'ignore'
hug_height = 'ignore'

#--------------------------------------------------------------------------
# Initialization
#--------------------------------------------------------------------------
def snapshot(self):
""" Returns the dict of creation attributes for the control.

"""
snap = super(TraitsItem, self).snapshot()
snap['model'] = self.model
snap['handler'] = self.handler
snap['view'] = self.view
return snap

def bind(self):
""" A method called after initialization which allows the widget
to bind any event handlers necessary.

"""
super(TraitsItem, self).bind()
self.publish_attributes('model', 'handler', 'view')

6 changes: 6 additions & 0 deletions enaml/wx/wx_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ def tool_bar_factory():
return WxToolBar


def traits_item_factory():
from .wx_traits_item import WxTraitsItem
return WxTraitsItem


def window_factory():
from .wx_window import WxWindow
return WxWindow
Expand Down Expand Up @@ -188,5 +193,6 @@ def register_default():
register('SplitItem', split_item_factory)
register('Splitter', splitter_factory)
register('ToolBar', tool_bar_factory)
register('TraitsItem', traits_item_factory)
register('Window', window_factory)

75 changes: 75 additions & 0 deletions enaml/wx/wx_traits_item.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import wx

from .wx_control import WxControl


class WxTraitsItem(WxControl):
""" A Wx implementation of an Enaml TraitsUIItem.

"""
#--------------------------------------------------------------------------
# Setup Methods
#--------------------------------------------------------------------------
def create_widget(self, parent, tree):
""" Create the underlying label widget.

"""
widget = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
vbox = wx.BoxSizer(wx.VERTICAL)
widget.SetSizer(vbox)
return widget

def create(self, tree):
""" Create and initialize the underlying widget.

"""
super(WxTraitsItem, self).create(tree)
self.model = tree['model']
self.view = tree['view']
self.handler = tree['handler']
self.ui = None

def init_layout(self):
'''Create the Traits UI widget and add to our layout
'''
super(WxTraitsItem, self).init_layout()
# guard against using a named view that is not supported by the model
if isinstance(self.view, (str, unicode)):
if self.model.trait_view(self.view) is None:
self.view = ''
# remove any previous widget before adding a new one
if self.ui:
self.widget().GetSizer().Remove(self.ui.control)
self.ui.control.Hide()
self.ui = self.model.edit_traits(parent=self.widget(), view=self.view,
handler=self.handler, kind='subpanel')
self.widget().GetSizer().Add(self.ui.control, 1,
wx.LEFT | wx.TOP | wx.GROW)
# allow the widget to resize when the view is changed
size = self.ui.control.GetSize()
self.set_minimum_size((size.width, size.height))
self.size_hint_updated()

#--------------------------------------------------------------------------
# Message Handlers
#--------------------------------------------------------------------------
def on_action_set_model(self, content):
""" Handle the 'set_model' action from the Enaml widget.

"""
self.model = content['model']
self.init_layout()

def on_action_set_handler(self, content):
""" Handle the 'set_handler' action from the Enaml widget.

"""
self.handler = content['handler']
self.init_layout()

def on_action_set_view(self, content):
""" Handle the 'set_view' action from the Enaml widget.

"""
self.view = content['view']
self.init_layout()
29 changes: 29 additions & 0 deletions examples/widgets/traits_item.enaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Note : You may have to set your ETS_TOOLKIT
# environmental value to match the enaml toolkit
# for example, if using QT
# import os
# os.environ['ETS_TOOLKIT'] = 'qt4'
from enaml.widgets.api import MainWindow, TraitsItem, Container, PushButton
from traits.api import HasTraits, Str
from traitsui.api import View


class Test(HasTraits):
a = Str('foo')
b = Str('bar')
traits_view = View('a', 'b')
other_view = View('b', 'a', 'a')


enamldef Main(MainWindow):
Container:
TraitsItem: titem:
model = Test()
view = View('a')
PushButton:
text = 'Change View'
clicked ::
if titem.view == 'other_view':
titem.view = 'traits_view'
else:
titem.view = 'other_view'
35 changes: 35 additions & 0 deletions examples/widgets/traits_mayavi.enaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# NOTE: If using PySide, upgrade to mayavi 4.2.0 for this to work
# You may have to set your ETS_TOOLKIT
# environmental value to match the enaml toolkit
# for example, if using QT
# import os
# os.environ['ETS_TOOLKIT'] = 'qt4'

from enaml.widgets.api import MainWindow, Container, TraitsItem

from traits.api import HasTraits, Instance, on_trait_change
from traitsui.api import View, Item
from mayavi.core.ui.api import MayaviScene, MlabSceneModel, SceneEditor


class Visualization(HasTraits):
scene = Instance(MlabSceneModel, ())

@on_trait_change('scene.activated')
def update_plot(self):
# This function is called when the view is opened. We don't
# populate the scene when the view is not yet open, as some
# VTK features require a GLContext.

# We can do normal mlab calls on the embedded scene.
self.scene.mlab.test_points3d()


enamldef Main(MainWindow):
Container:
TraitsItem:
model = Visualization()
view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
height=250, width=300, show_label=False),
resizable=True # We need this to resize with the parent widget
)