mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 21:20:31 -05:00 
			
		
		
		
	FlowLayout: Add support for vertically expanding widgets and vertical alignment.
This commit is contained in:
		
							parent
							
								
									880fde3480
								
							
						
					
					
						commit
						19fa10d71d
					
				@ -51,7 +51,7 @@
 | 
				
			|||||||
#include <QtWidgets>
 | 
					#include <QtWidgets>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "flowlayout.h"
 | 
					#include "flowlayout.h"
 | 
				
			||||||
//! [1]
 | 
					
 | 
				
			||||||
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
 | 
					FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
 | 
				
			||||||
    : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
 | 
					    : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -63,25 +63,19 @@ FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    setContentsMargins(margin, margin, margin, margin);
 | 
					    setContentsMargins(margin, margin, margin, margin);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [1]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [2]
 | 
					 | 
				
			||||||
FlowLayout::~FlowLayout()
 | 
					FlowLayout::~FlowLayout()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QLayoutItem *item;
 | 
					    QLayoutItem *item;
 | 
				
			||||||
    while ((item = takeAt(0)))
 | 
					    while ((item = takeAt(0)))
 | 
				
			||||||
        delete item;
 | 
					        delete item;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [2]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [3]
 | 
					 | 
				
			||||||
void FlowLayout::addItem(QLayoutItem *item)
 | 
					void FlowLayout::addItem(QLayoutItem *item)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    itemList.append(item);
 | 
					    itemList.append(item);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [3]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [4]
 | 
					 | 
				
			||||||
int FlowLayout::horizontalSpacing() const
 | 
					int FlowLayout::horizontalSpacing() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (m_hSpace >= 0) {
 | 
					    if (m_hSpace >= 0) {
 | 
				
			||||||
@ -99,9 +93,7 @@ int FlowLayout::verticalSpacing() const
 | 
				
			|||||||
        return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
 | 
					        return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [4]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [5]
 | 
					 | 
				
			||||||
int FlowLayout::count() const
 | 
					int FlowLayout::count() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return itemList.size();
 | 
					    return itemList.size();
 | 
				
			||||||
@ -118,16 +110,12 @@ QLayoutItem *FlowLayout::takeAt(int index)
 | 
				
			|||||||
        return itemList.takeAt(index);
 | 
					        return itemList.takeAt(index);
 | 
				
			||||||
    return nullptr;
 | 
					    return nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [5]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [6]
 | 
					 | 
				
			||||||
Qt::Orientations FlowLayout::expandingDirections() const
 | 
					Qt::Orientations FlowLayout::expandingDirections() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return { };
 | 
					    return { };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [6]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [7]
 | 
					 | 
				
			||||||
bool FlowLayout::hasHeightForWidth() const
 | 
					bool FlowLayout::hasHeightForWidth() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
@ -138,9 +126,7 @@ int FlowLayout::heightForWidth(int width) const
 | 
				
			|||||||
    int height = doLayout(QRect(0, 0, width, 0), true);
 | 
					    int height = doLayout(QRect(0, 0, width, 0), true);
 | 
				
			||||||
    return height;
 | 
					    return height;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [7]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [8]
 | 
					 | 
				
			||||||
void FlowLayout::setGeometry(const QRect &rect)
 | 
					void FlowLayout::setGeometry(const QRect &rect)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QLayout::setGeometry(rect);
 | 
					    QLayout::setGeometry(rect);
 | 
				
			||||||
@ -162,9 +148,7 @@ QSize FlowLayout::minimumSize() const
 | 
				
			|||||||
    size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
 | 
					    size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
 | 
				
			||||||
    return size;
 | 
					    return size;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [8]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [9]
 | 
					 | 
				
			||||||
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
 | 
					int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int left, top, right, bottom;
 | 
					    int left, top, right, bottom;
 | 
				
			||||||
@ -173,39 +157,72 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
 | 
				
			|||||||
    int x = effectiveRect.x();
 | 
					    int x = effectiveRect.x();
 | 
				
			||||||
    int y = effectiveRect.y();
 | 
					    int y = effectiveRect.y();
 | 
				
			||||||
    int lineHeight = 0;
 | 
					    int lineHeight = 0;
 | 
				
			||||||
//! [9]
 | 
					    QList<int> maxLineHeights;
 | 
				
			||||||
 | 
					    int maxLineHeight = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! [10]
 | 
					    // In order to support vertical alignment and expanding widgets, we need to first calculate maxLineHeight
 | 
				
			||||||
 | 
					    // for each row of widgets
 | 
				
			||||||
 | 
					    if (!testOnly) {
 | 
				
			||||||
 | 
					        for (QLayoutItem *item : qAsConst(itemList)) {
 | 
				
			||||||
 | 
					            const QWidget *wid = item->widget();
 | 
				
			||||||
 | 
					            int spaceX = horizontalSpacing();
 | 
				
			||||||
 | 
					            if (spaceX == -1)
 | 
				
			||||||
 | 
					                spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int nextX = x + item->sizeHint().width() + spaceX;
 | 
				
			||||||
 | 
					            if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
 | 
				
			||||||
 | 
					                x = effectiveRect.x();
 | 
				
			||||||
 | 
					                nextX = x + item->sizeHint().width() + spaceX;
 | 
				
			||||||
 | 
					                maxLineHeights.append(lineHeight);
 | 
				
			||||||
 | 
					                lineHeight = 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            x = nextX;
 | 
				
			||||||
 | 
					            lineHeight = qMax(lineHeight, item->sizeHint().height());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        maxLineHeights.append(lineHeight);
 | 
				
			||||||
 | 
					        maxLineHeight = maxLineHeights.takeFirst();
 | 
				
			||||||
 | 
					        x = effectiveRect.x();
 | 
				
			||||||
 | 
					        y = effectiveRect.y();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Now do layout
 | 
				
			||||||
    for (QLayoutItem *item : qAsConst(itemList)) {
 | 
					    for (QLayoutItem *item : qAsConst(itemList)) {
 | 
				
			||||||
        const QWidget *wid = item->widget();
 | 
					        const QWidget *wid = item->widget();
 | 
				
			||||||
        int spaceX = horizontalSpacing();
 | 
					        int spaceX = horizontalSpacing();
 | 
				
			||||||
        if (spaceX == -1)
 | 
					        if (spaceX == -1)
 | 
				
			||||||
            spaceX = wid->style()->layoutSpacing(
 | 
					            spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
 | 
				
			||||||
                QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
 | 
					 | 
				
			||||||
        int spaceY = verticalSpacing();
 | 
					        int spaceY = verticalSpacing();
 | 
				
			||||||
        if (spaceY == -1)
 | 
					        if (spaceY == -1)
 | 
				
			||||||
            spaceY = wid->style()->layoutSpacing(
 | 
					            spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
 | 
				
			||||||
                QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
 | 
					
 | 
				
			||||||
//! [10]
 | 
					 | 
				
			||||||
//! [11]
 | 
					 | 
				
			||||||
        int nextX = x + item->sizeHint().width() + spaceX;
 | 
					        int nextX = x + item->sizeHint().width() + spaceX;
 | 
				
			||||||
        if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
 | 
					        if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
 | 
				
			||||||
            x = effectiveRect.x();
 | 
					            x = effectiveRect.x();
 | 
				
			||||||
            y = y + lineHeight + spaceY;
 | 
					            y = y + lineHeight + spaceY;
 | 
				
			||||||
            nextX = x + item->sizeHint().width() + spaceX;
 | 
					            nextX = x + item->sizeHint().width() + spaceX;
 | 
				
			||||||
 | 
					            if (maxLineHeights.size() > 0) {
 | 
				
			||||||
 | 
					                maxLineHeight = maxLineHeights.takeFirst();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            lineHeight = 0;
 | 
					            lineHeight = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!testOnly)
 | 
					        if (!testOnly)
 | 
				
			||||||
            item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
 | 
					        {
 | 
				
			||||||
 | 
					            QSize size = item->sizeHint();
 | 
				
			||||||
 | 
					            if (wid && (wid->sizePolicy().verticalPolicy() != QSizePolicy::Fixed)) {
 | 
				
			||||||
 | 
					                size.setHeight(maxLineHeight);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            QRect r(QPoint(x, y), size);
 | 
				
			||||||
 | 
					            item->setGeometry(r);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        x = nextX;
 | 
					        x = nextX;
 | 
				
			||||||
        lineHeight = qMax(lineHeight, item->sizeHint().height());
 | 
					        lineHeight = qMax(lineHeight, item->sizeHint().height());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return y + lineHeight - rect.y() + bottom;
 | 
					    return y + lineHeight - rect.y() + bottom;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [11]
 | 
					
 | 
				
			||||||
//! [12]
 | 
					 | 
				
			||||||
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
 | 
					int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QObject *parent = this->parent();
 | 
					    QObject *parent = this->parent();
 | 
				
			||||||
@ -218,4 +235,3 @@ int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
 | 
				
			|||||||
        return static_cast<QLayout *>(parent)->spacing();
 | 
					        return static_cast<QLayout *>(parent)->spacing();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//! [12]
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user