# ============================================================================
#
# Copyright (C) 2007-2016 Conceptive Engineering bvba.
# www.conceptive.be / info@conceptive.be
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Conceptive Engineering nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ============================================================================
"""
PyQt port of the layouts/flowlayout example from Qt v4.x
The original port was copied from the PyQt layout examples.
"""
from ..core.qt import QtCore, QtGui
[docs]class FlowLayout( QtGui.QLayout ):
"""
Layout that arranges child widgets from left to right and top to bottom.
@todo : this layout returns a height for width that is too high, it seems
as if it takes into account that it should be able to expand
"""
def __init__( self, parent = None ):
"""
:param parent: a `QtWidgets.QWidget`
"""
super(FlowLayout, self).__init__(parent)
if parent is not None:
self.setContentsMargins( 0, 0, 0, 0 )
self.setSpacing( -1 )
self.item_list = []
def addItem( self, item ):
self.item_list.append( item )
def count(self):
return len(self.item_list)
def itemAt( self, index ):
if index >= 0 and index < len(self.item_list):
return self.item_list[index]
return None
def takeAt( self, index ):
if index >= 0 and index < len(self.item_list):
return self.item_list.pop(index)
return None
def expandingDirections( self ):
return QtCore.Qt.Orientations(QtCore.Qt.Orientation(0))
def hasHeightForWidth( self ):
return True
def heightForWidth( self, width ):
height = self.doLayout( QtCore.QRect(0, 0, width, 0), True )
return height
def setGeometry( self, rect ):
super(FlowLayout, self).setGeometry(rect)
self.doLayout( rect, False )
def sizeHint( self ):
return self.minimumSize()
def minimumSize(self):
size = QtCore.QSize()
for item in self.item_list:
size = size.expandedTo(item.minimumSize())
size += QtCore.QSize(2 * self.margin(), 2 * self.margin())
return size
def doLayout( self, rect, testOnly ):
x = rect.x()
y = rect.y()
lineHeight = 0
for item in self.item_list:
wid = item.widget()
spaceX = self.spacing() + wid.style().layoutSpacing(QtGui.QSizePolicy.PushButton, QtGui.QSizePolicy.PushButton, QtCore.Qt.Horizontal)
spaceY = self.spacing() + wid.style().layoutSpacing(QtGui.QSizePolicy.PushButton, QtGui.QSizePolicy.PushButton, QtCore.Qt.Vertical)
nextX = x + item.sizeHint().width() + spaceX
if nextX - spaceX > rect.right() and lineHeight > 0:
x = rect.x()
y = y + lineHeight + spaceY
nextX = x + item.sizeHint().width() + spaceX
lineHeight = 0
if not testOnly:
item.setGeometry(QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint()))
x = nextX
lineHeight = max(lineHeight, item.sizeHint().height())
return y + lineHeight - rect.y()