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

Commit

Permalink
Update the splitter implementation to support a stretch factor and a
Browse files Browse the repository at this point in the history
collapse flag.
  • Loading branch information
sccolbert committed Jan 9, 2013
1 parent 14b961d commit c2272cf
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 44 deletions.
99 changes: 84 additions & 15 deletions enaml/qt/qt_split_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@
# Copyright (c) 2012, Enthought, Inc.
# All rights reserved.
#------------------------------------------------------------------------------
from .qt.QtGui import QFrame
from .qt.QtGui import QFrame, QSplitter, QLayout
from .q_single_widget_layout import QSingleWidgetLayout
from .qt_container import QtContainer
from .qt_widget import QtWidget


class QSplitItem(QFrame):
""" A QFrame subclass which acts as an item QSplitter.
""" A QFrame subclass which acts as an item in a QSplitter.
"""
def __init__(self, *args, **kwargs):
def __init__(self, parent=None):
""" Initialize a QSplitItem.
Parameters
----------
*args, **kwargs
The position and keyword arguments required to initialize
a QWidget.
parent : QWidget, optional
The parent widget of the split item, or None if it has no
parent.
"""
super(QSplitItem, self).__init__(*args, **kwargs)
super(QSplitItem, self).__init__(parent)
self._split_widget = None
self.setLayout(QSingleWidgetLayout())
self.layout().setSizeConstraint(QLayout.SetMinAndMaxSize)

def splitWidget(self):
""" Get the split widget for this split item.
Expand All @@ -49,6 +50,62 @@ def setSplitWidget(self, widget):
self._split_widget = widget
self.layout().setWidget(widget)

def stretch(self):
""" Get the stretch factor for this split item.
Returns
-------
result : int
The stretch factor for this split item.
"""
# horizontal and vertical stretch are set to be the same,
# so which one is returned here is irrelevant.
return self.sizePolicy().horizontalStretch()

def setStretch(self, stretch):
""" Set the stretch factor for this split item.
Parameters
----------
stretch : int
The stretch factor to use for this split item.
"""
stretch = max(0, stretch)
policy = self.sizePolicy()
policy.setHorizontalStretch(stretch)
policy.setVerticalStretch(stretch)
self.setSizePolicy(policy)

def collapsible(self):
""" Get whether or not this widget is collapsible.
Returns
-------
result : bool
Whether or not this item can be collapsed to zero size.
"""
parent = self.parentWidget()
if isinstance(parent, QSplitter):
return parent.isCollapsible(parent.indexOf(self))
return False

def setCollapsible(self, collapsible):
""" Set whether or not this widget is collapsible.
Parameters
----------
collapsible : bool
Whether or not this item can be collapsed to zero size.
This holds regardless of the minimum size of the item.
"""
parent = self.parentWidget()
if isinstance(parent, QSplitter):
return parent.setCollapsible(parent.indexOf(self), collapsible)


class QtSplitItem(QtWidget):
""" A Qt implementation of an Enaml SplitItem.
Expand All @@ -68,7 +125,8 @@ def create(self, tree):
"""
super(QtSplitItem, self).create(tree)
self.set_preferred_size(tree['preferred_size'])
self.set_stretch(tree['stretch'])
self.set_collapsible(tree['collapsible'])

def init_layout(self):
""" Initialize the layout for the underyling widget.
Expand Down Expand Up @@ -116,19 +174,30 @@ def child_added(self, child):
#--------------------------------------------------------------------------
# Message Handlers
#--------------------------------------------------------------------------
def on_action_set_preferred_size(self, content):
""" Handle the 'set_preferred_size' action from the Enaml widget.
def on_action_set_stretch(self, content):
""" Handle the 'set_stretch' action from the Enaml widget.
"""
self.set_stretch(content['stretch'])

def on_action_set_collapsible(self, content):
""" Handle the 'set_collapsible' action from the Enaml widget.
"""
self.set_preferred_size(content['preferred_size'])
self.set_collapsible(content['collapsible'])

#--------------------------------------------------------------------------
# Widget Update Methods
#--------------------------------------------------------------------------
def set_preferred_size(self, size):
""" Set the preferred size for this item in the splitter.
def set_stretch(self, stretch):
""" Set the stretch factor for the underlying widget.
"""
self.widget().setStretch(stretch)

def set_collapsible(self, collapsible):
""" Set the collapsible flag for the underlying widget.
"""
# XXX implement me
pass
self.widget().setCollapsible(collapsible)

26 changes: 3 additions & 23 deletions enaml/qt/qt_splitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ class QCustomSplitter(QSplitter):
#: of the splitter is no longer valid.
layoutRequested = Signal()

#--------------------------------------------------------------------------
# Public API
#--------------------------------------------------------------------------
def createHandle(self):
""" A reimplemented virtual method to create splitter handles.
Expand Down Expand Up @@ -145,7 +142,7 @@ def init_layout(self):
# collapsed, the effect of this is to restore the order of event
# processing.
if sys.platform == 'win32':
widget.splitterMoved.connect(self.on_win32_slider_moved)
widget.splitterMoved.connect(self.on_win32_splitter_moved)

#--------------------------------------------------------------------------
# Child Events
Expand Down Expand Up @@ -173,8 +170,8 @@ def on_layout_requested(self):
"""
self.size_hint_updated()

def on_win32_slider_moved(self):
""" Handle the 'sliderMoved' signal from the QSplitter.
def on_win32_splitter_moved(self):
""" Handle the 'splitterMoved' signal from the QSplitter.
This handler is only connected when running on Windows and it
serves to make sure paint events get generated during heavy
Expand Down Expand Up @@ -217,20 +214,3 @@ def set_live_drag(self, live_drag):
"""
self.widget().setOpaqueResize(live_drag)

# def set_preferred_sizes(self, sizes):
# """ Set the preferred sizes for the children.

# For sizes not supplied by the user, either via None values or
# a list which is too short, the current size for that element
# will be used in its place.

# """
# widget = self.widget()
# curr_sizes = widget.sizes()[:]
# max_idx = min(len(curr_sizes), len(sizes))
# for idx in xrange(max_idx):
# size = sizes[idx]
# if size is not None:
# curr_sizes[idx] = size
# widget.setSizes(curr_sizes)

21 changes: 15 additions & 6 deletions enaml/widgets/split_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Copyright (c) 2012, Enthought, Inc.
# All rights reserved.
#------------------------------------------------------------------------------
from traits.api import Either, Int, Property, cached_property
from traits.api import Any, Bool, Range, Property, cached_property

from .container import Container
from .widget import Widget
Expand All @@ -16,13 +16,21 @@ class SplitItem(Widget):
instance of Container.
"""
#: The preferred size for this item in the splitter, or None if
#: there is no preference for the size. The default is None.
preferred_size = Either(None, Int)
#: The stretch factor for this item. The stretch factor determines
#: how much an item is resized relative to its neighbors when the
#: splitter space is allocated.
stretch = Range(low=0, value=1)

#: Whether or not the item can be collapsed to zero width by the
#: user. This holds regardless of the minimum size of the item.
collapsible = Bool(True)

#: A read only property which returns the split widget.
split_widget = Property(depends_on='children')

#: This is a deprecated attribute. It should no longer be used.
preferred_size = Any

#--------------------------------------------------------------------------
# Initialization
#--------------------------------------------------------------------------
Expand All @@ -31,15 +39,16 @@ def snapshot(self):
"""
snap = super(SplitItem, self).snapshot()
snap['preferred_size'] = self.preferred_size
snap['stretch'] = self.stretch
snap['collapsible'] = self.collapsible
return snap

def bind(self):
""" Bind the change handlers for the widget.
"""
super(SplitItem, self).bind()
self.publish_attributes('preferred_size')
self.publish_attributes('stretch', 'collapsible')

#--------------------------------------------------------------------------
# Private API
Expand Down

0 comments on commit c2272cf

Please sign in to comment.