Pencil2D Animation
Download Community News Docs Contribute
  • Overview
  • Articles
  • Code
  •  
  • Class List
  • Class Index
  • Class Hierarchy
  • Class Members
  • File List
Loading...
Searching...
No Matches
  • core_lib
  • src
  • interface
flowlayout.cpp
1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the examples of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:BSD$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** BSD License Usage
18** Alternatively, you may use this file under the terms of the BSD license
19** as follows:
20**
21** "Redistribution and use in source and binary forms, with or without
22** modification, are permitted provided that the following conditions are
23** met:
24** * Redistributions of source code must retain the above copyright
25** notice, this list of conditions and the following disclaimer.
26** * Redistributions in binary form must reproduce the above copyright
27** notice, this list of conditions and the following disclaimer in
28** the documentation and/or other materials provided with the
29** distribution.
30** * Neither the name of The Qt Company Ltd nor the names of its
31** contributors may be used to endorse or promote products derived
32** from this software without specific prior written permission.
33**
34**
35** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46**
47** $QT_END_LICENSE$
48**
49****************************************************************************/
50
51#include <QWidget>
52#include <QLayout>
53#include <QtMath>
54
55#include "flowlayout.h"
56
57FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
58 : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
59{
60 setContentsMargins(margin, margin, margin, margin);
61}
62
63FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
64 : m_hSpace(hSpacing), m_vSpace(vSpacing)
65{
66 setContentsMargins(margin, margin, margin, margin);
67}
68
69FlowLayout::~FlowLayout()
70{
71 QLayoutItem *item;
72 while ((item = takeAt(0)))
73 delete item;
74}
75
76void FlowLayout::addItem(QLayoutItem *item)
77{
78 itemList.append(item);
79}
80
81int FlowLayout::horizontalSpacing() const
82{
83 if (m_hSpace >= 0) {
84 return m_hSpace;
85 } else {
86 return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
87 }
88}
89
90int FlowLayout::verticalSpacing() const
91{
92 if (m_vSpace >= 0) {
93 return m_vSpace;
94 } else {
95 return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
96 }
97}
98
99int FlowLayout::count() const
100{
101 return itemList.size();
102}
103
104QLayoutItem *FlowLayout::itemAt(int index) const
105{
106 return itemList.value(index);
107}
108
109QLayoutItem *FlowLayout::takeAt(int index)
110{
111 if (index >= 0 && index < itemList.size())
112 return itemList.takeAt(index);
113 else
114 return nullptr;
115}
116
117Qt::Orientations FlowLayout::expandingDirections() const
118{
119 return {};
120}
121
122bool FlowLayout::hasHeightForWidth() const
123{
124 return true;
125}
126
127int FlowLayout::heightForWidth(int width) const
128{
129 int height = doLayout(QRect(0, 0, width, 0), true);
130 return height;
131}
132
133void FlowLayout::setGeometry(const QRect &rect)
134{
135 QLayout::setGeometry(rect);
136 doLayout(rect, false);
137}
138
139QSize FlowLayout::sizeHint() const
140{
141 return minimumSize();
142}
143
144QSize FlowLayout::minimumSize() const
145{
146 QSize size;
147 QLayoutItem *item;
148 foreach (item, itemList)
149 size = size.expandedTo(item->minimumSize());
150 int left, top, right, bottom;
151 getContentsMargins(&left, &top, &right, &bottom);
152 size += QSize(left + right, top + bottom);
153 return size;
154}
155
156int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
157{
158 int left, top, right, bottom;
159 getContentsMargins(&left, &top, &right, &bottom);
160 QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
161 int x = effectiveRect.x();
162 int y = effectiveRect.y();
163 int lineHeight = 0;
164 int rowCount = 0;
165
166 QLayoutItem *item;
167 int spaceX = 0;
168 for (int i = 0; i < itemList.length(); i++) {
169 item = itemList.at(i);
170 QWidget *wid = item->widget();
171 spaceX = horizontalSpacing();
172 if (spaceX == -1)
173 spaceX = wid->style()->layoutSpacing(
174 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
175 int spaceY = verticalSpacing();
176 if (spaceY == -1)
177 spaceY = wid->style()->layoutSpacing(
178 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
179
180 int nextX = x + item->sizeHint().width() + spaceX;
181 if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
182 if(!testOnly && alignment() & Qt::AlignHCenter) {
183 int offset = qFloor((effectiveRect.right() + spaceX - x) / 2);
184 for(int j = i-1; j > i-1-rowCount; j--) {
185 auto rowItem = itemList.at(j);
186 rowItem->setGeometry(rowItem->geometry().adjusted(offset, 0, offset, 0));
187 }
188 }
189
190 x = effectiveRect.x();
191 y = y + lineHeight + spaceY;
192 nextX = x + item->sizeHint().width() + spaceX;
193 lineHeight = 0;
194 rowCount = 0;
195 }
196 rowCount++;
197
198 if (!testOnly) {
199 item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
200 }
201
202 x = nextX;
203 lineHeight = qMax(lineHeight, item->sizeHint().height());
204 }
205
206 if (!testOnly && alignment() & Qt::AlignHCenter) {
207 int offset = qFloor((effectiveRect.right() + spaceX - x) / 2);
208 for (int j = itemList.length()-1; j > itemList.length()-1-rowCount; j--) {
209 auto rowItem = itemList.at(j);
210 rowItem->setGeometry(rowItem->geometry().adjusted(offset, 0, offset, 0));
211 }
212 }
213
214 return y + lineHeight - rect.y() + bottom;
215}
216
217int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
218{
219 QObject* parent = this->parent();
220 if (!parent) {
221 return -1;
222 } else if (parent->isWidgetType()) {
223 QWidget *pw = static_cast<QWidget *>(parent);
224 return pw->style()->pixelMetric(pm, nullptr, pw);
225 } else {
226 return static_cast<QLayout *>(parent)->spacing();
227 }
228}
QLayout
QLayout::getContentsMargins
void getContentsMargins(int *left, int *top, int *right, int *bottom) const const
QLayout::setGeometry
virtual void setGeometry(const QRect &r) override
QLayout::spacing
spacing
QLayoutItem
QLayoutItem::alignment
Qt::Alignment alignment() const const
QLayoutItem::minimumSize
virtual QSize minimumSize() const const=0
QLayoutItem::setGeometry
virtual void setGeometry(const QRect &r)=0
QLayoutItem::sizeHint
virtual QSize sizeHint() const const=0
QLayoutItem::widget
virtual QWidget * widget()
QList::append
void append(const T &value)
QList::at
const T & at(int i) const const
QList::length
int length() const const
QList::size
int size() const const
QList::takeAt
T takeAt(int i)
QList::value
T value(int i) const const
QObject
QObject::isWidgetType
bool isWidgetType() const const
QObject::parent
QObject * parent() const const
QPoint
QRect
QRect::adjusted
QRect adjusted(int dx1, int dy1, int dx2, int dy2) const const
QRect::right
int right() const const
QRect::x
int x() const const
QRect::y
int y() const const
QSize
QSize::expandedTo
QSize expandedTo(const QSize &otherSize) const const
QSize::height
int height() const const
QSize::width
int width() const const
QSizePolicy::PushButton
PushButton
QStyle::PM_LayoutHorizontalSpacing
PM_LayoutHorizontalSpacing
QStyle::layoutSpacing
virtual int layoutSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation, const QStyleOption *option, const QWidget *widget) const const=0
QStyle::pixelMetric
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
Qt::AlignHCenter
AlignHCenter
Qt::Orientations
typedef Orientations
Qt::left
QTextStream & left(QTextStream &stream)
Qt::right
QTextStream & right(QTextStream &stream)
QWidget
QWidget::style
QStyle * style() const const
Generated on Thu May 8 2025 04:47:53 for Pencil2D by doxygen 1.9.6 based on revision 4513250b1d5b1a3676ec0e67b06b7a885ceaae39