#------------------------------------------------------------------------------
# Copyright (c) 2012, Enthought, Inc.
# All rights reserved.
#------------------------------------------------------------------------------
from .qt.QtGui import QScrollArea, QFrame
from .qt_constraints_widget import QtConstraintsWidget
from .qt_flow_item import QtFlowItem
from .q_flow_layout import QFlowLayout
_DIRECTION_MAP = {
'left_to_right': QFlowLayout.LeftToRight,
'right_to_left': QFlowLayout.RightToLeft,
'top_to_bottom': QFlowLayout.TopToBottom,
'bottom_to_top': QFlowLayout.BottomToTop,
}
_ALIGN_MAP = {
'leading': QFlowLayout.AlignLeading,
'trailing': QFlowLayout.AlignTrailing,
'center': QFlowLayout.AlignCenter,
'justify': QFlowLayout.AlignJustify,
}
class QFlowArea(QScrollArea):
""" A custom QScrollArea which implements a flowing layout.
"""
def __init__(self, parent=None):
""" Initialize a QFlowArea.
Parameters
----------
parent : QWidget, optional
The parent widget of this widget.
"""
super(QFlowArea, self).__init__(parent)
self._widget = QFrame(self)
self._layout = QFlowLayout()
self._widget.setLayout(self._layout)
self.setWidgetResizable(True)
self.setWidget(self._widget)
def layout(self):
""" Get the layout for this flow area.
The majority of interaction for a QFlowArea takes place through
its layout, rather than through the widget itself.
Returns
-------
result : QFlowLayout
The flow layout for this flow area.
"""
return self._layout
def setLayout(self, layout):
""" A reimplemented method. Setting the layout on a QFlowArea
is not supported.
"""
raise TypeError("Cannot set layout on a QFlowArea.")
[docs]class QtFlowArea(QtConstraintsWidget):
""" A Qt implementation of an Enaml FlowArea.
"""
#--------------------------------------------------------------------------
# Setup Methods
#--------------------------------------------------------------------------
[docs] def create(self, tree):
""" Create and initialize the underlying control.
"""
super(QtFlowArea, self).create(tree)
self.set_direction(tree['direction'])
self.set_align(tree['align'])
self.set_horizontal_spacing(tree['horizontal_spacing'])
self.set_vertical_spacing(tree['vertical_spacing'])
self.set_margins(tree['margins'])
[docs] def init_layout(self):
""" Initialize the layout for the underlying control.
"""
super(QtFlowArea, self).init_layout()
layout = self.widget().layout()
for child in self.children():
if isinstance(child, QtFlowItem):
layout.addWidget(child.widget())
#--------------------------------------------------------------------------
# Child Events
#--------------------------------------------------------------------------
[docs] def child_removed(self, child):
""" Handle the child removed event for a QtMdiArea.
"""
if isinstance(child, QtFlowItem):
self.widget().layout().removeWidget(child.widget())
[docs] def child_added(self, child):
""" Handle the child added event for a QtMdiArea.
"""
if isinstance(child, QtFlowItem):
index = self.index_of(child)
self.widget().layout().insertWidget(index, child.widget())
#--------------------------------------------------------------------------
# Message Handling
#--------------------------------------------------------------------------
[docs] def on_action_set_direction(self, content):
""" Handle the 'set_direction' action from the Enaml widget.
"""
self.set_direction(content['direction'])
[docs] def on_action_set_align(self, content):
""" Handle the 'set_align' action from the Enaml widget.
"""
self.set_align(content['align'])
[docs] def on_action_set_horizontal_spacing(self, content):
""" Handle the 'set_horizontal_spacing' action from the Enaml
widget.
"""
self.set_horizontal_spacing(content['horizontal_spacing'])
[docs] def on_action_set_vertical_spacing(self, content):
""" Handle the 'set_vertical_spacing' action from the Enaml
widget.
"""
self.set_vertical_spacing(content['vertical_spacing'])
[docs] def on_action_set_margins(self, content):
""" Handle the 'set_margins' action from the Enaml widget.
"""
self.set_margins(content['margins'])
#--------------------------------------------------------------------------
# Widget Update Methods
#--------------------------------------------------------------------------
[docs] def set_direction(self, direction):
""" Set the direction for the underlying control.
"""
self.widget().layout().setDirection(_DIRECTION_MAP[direction])
[docs] def set_align(self, align):
""" Set the alignment for the underlying control.
"""
self.widget().layout().setAlignment(_ALIGN_MAP[align])
[docs] def set_horizontal_spacing(self, spacing):
""" Set the horizontal spacing of the underyling control.
"""
self.widget().layout().setHorizontalSpacing(spacing)
[docs] def set_vertical_spacing(self, spacing):
""" Set the vertical spacing of the underlying control.
"""
self.widget().layout().setVerticalSpacing(spacing)
[docs] def set_margins(self, margins):
""" Set the margins of the underlying control.
"""
top, right, bottom, left = margins
self.widget().layout().setContentsMargins(left, top, right, bottom)
#--------------------------------------------------------------------------
# Overrides
#--------------------------------------------------------------------------
[docs] def replace_constraints(self, old_cns, new_cns):
""" A reimplemented QtConstraintsWidget layout method.
Constraints layout may not cross the boundary of a ScrollArea,
so this method is no-op which stops the layout propagation.
"""
pass