39 ****************************************************************************/ |
39 ****************************************************************************/ |
40 |
40 |
41 #include <QtGui> |
41 #include <QtGui> |
42 |
42 |
43 #include "flowlayout.h" |
43 #include "flowlayout.h" |
44 |
|
45 FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) |
|
46 : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) |
|
47 { |
|
48 setContentsMargins(margin, margin, margin, margin); |
|
49 } |
|
50 |
44 |
51 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) |
45 FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) |
52 : m_hSpace(hSpacing), m_vSpace(vSpacing) |
46 : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) |
53 { |
47 { |
54 setContentsMargins(margin, margin, margin, margin); |
48 setContentsMargins(margin, margin, margin, margin); |
55 } |
49 } |
56 |
50 |
57 FlowLayout::~FlowLayout() |
51 FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) |
58 { |
52 : m_hSpace(hSpacing), m_vSpace(vSpacing) |
59 QLayoutItem *item; |
53 { |
60 while ((item = takeAt(0))) |
54 setContentsMargins(margin, margin, margin, margin); |
61 delete item; |
55 } |
62 } |
|
63 |
56 |
64 void FlowLayout::addItem(QLayoutItem *item) |
57 FlowLayout::~FlowLayout() |
65 { |
58 { |
66 itemList.append(item); |
59 QLayoutItem *item; |
67 } |
60 while ((item = takeAt(0))) |
|
61 delete item; |
|
62 } |
68 |
63 |
69 int FlowLayout::horizontalSpacing() const |
64 void FlowLayout::addItem(QLayoutItem *item) |
70 { |
65 { |
71 if (m_hSpace >= 0) { |
66 itemList.append(item); |
72 return m_hSpace; |
67 } |
73 } else { |
|
74 return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); |
|
75 } |
|
76 } |
|
77 |
68 |
78 int FlowLayout::verticalSpacing() const |
69 int FlowLayout::horizontalSpacing() const |
79 { |
70 { |
80 if (m_vSpace >= 0) { |
71 if (m_hSpace >= 0) { |
81 return m_vSpace; |
72 return m_hSpace; |
82 } else { |
73 } else { |
83 return smartSpacing(QStyle::PM_LayoutVerticalSpacing); |
74 return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); |
84 } |
75 } |
85 } |
76 } |
86 |
77 |
87 int FlowLayout::count() const |
78 int FlowLayout::verticalSpacing() const |
88 { |
79 { |
89 return itemList.size(); |
80 if (m_vSpace >= 0) { |
90 } |
81 return m_vSpace; |
|
82 } else { |
|
83 return smartSpacing(QStyle::PM_LayoutVerticalSpacing); |
|
84 } |
|
85 } |
91 |
86 |
92 QLayoutItem *FlowLayout::itemAt(int index) const |
87 int FlowLayout::count() const |
93 { |
88 { |
94 return itemList.value(index); |
89 return itemList.size(); |
95 } |
90 } |
96 |
91 |
97 QLayoutItem *FlowLayout::takeAt(int index) |
92 QLayoutItem *FlowLayout::itemAt(int index) const |
98 { |
93 { |
99 if (index >= 0 && index < itemList.size()) |
94 return itemList.value(index); |
100 return itemList.takeAt(index); |
95 } |
101 else |
|
102 return 0; |
|
103 } |
|
104 |
96 |
105 Qt::Orientations FlowLayout::expandingDirections() const |
97 QLayoutItem *FlowLayout::takeAt(int index) |
106 { |
98 { |
107 return 0; |
99 if (index >= 0 && index < itemList.size()) |
108 } |
100 return itemList.takeAt(index); |
|
101 else |
|
102 return 0; |
|
103 } |
109 |
104 |
110 bool FlowLayout::hasHeightForWidth() const |
105 Qt::Orientations FlowLayout::expandingDirections() const |
111 { |
106 { |
112 return true; |
107 return 0; |
113 } |
108 } |
114 |
109 |
115 int FlowLayout::heightForWidth(int width) const |
110 bool FlowLayout::hasHeightForWidth() const |
116 { |
111 { |
117 int height = doLayout(QRect(0, 0, width, 0), true); |
112 return true; |
118 return height; |
113 } |
119 } |
|
120 |
114 |
121 void FlowLayout::setGeometry(const QRect &rect) |
115 int FlowLayout::heightForWidth(int width) const |
122 { |
116 { |
123 QLayout::setGeometry(rect); |
117 int height = doLayout(QRect(0, 0, width, 0), true); |
124 doLayout(rect, false); |
118 return height; |
125 } |
119 } |
126 |
120 |
127 QSize FlowLayout::sizeHint() const |
121 void FlowLayout::setGeometry(const QRect &rect) |
128 { |
122 { |
129 return minimumSize(); |
123 QLayout::setGeometry(rect); |
130 } |
124 doLayout(rect, false); |
|
125 } |
131 |
126 |
132 QSize FlowLayout::minimumSize() const |
127 QSize FlowLayout::sizeHint() const |
133 { |
128 { |
134 QSize size; |
129 return minimumSize(); |
135 QLayoutItem *item; |
130 } |
136 foreach (item, itemList) |
|
137 size = size.expandedTo(item->minimumSize()); |
|
138 |
131 |
139 size += QSize(2*margin(), 2*margin()); |
132 QSize FlowLayout::minimumSize() const |
140 return size; |
133 { |
141 } |
134 QSize size; |
|
135 QLayoutItem *item; |
|
136 foreach (item, itemList) |
|
137 size = size.expandedTo(item->minimumSize()); |
142 |
138 |
143 int FlowLayout::doLayout(const QRect &rect, bool testOnly) const |
139 size += QSize(2*margin(), 2*margin()); |
144 { |
140 return size; |
145 int left, top, right, bottom; |
141 } |
146 getContentsMargins(&left, &top, &right, &bottom); |
|
147 QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); |
|
148 int x = effectiveRect.x(); |
|
149 int y = effectiveRect.y(); |
|
150 int lineHeight = 0; |
|
151 |
142 |
152 QLayoutItem *item; |
143 int FlowLayout::doLayout(const QRect &rect, bool testOnly) const |
153 foreach (item, itemList) { |
144 { |
154 QWidget *wid = item->widget(); |
145 int left, top, right, bottom; |
155 int spaceX = horizontalSpacing(); |
146 getContentsMargins(&left, &top, &right, &bottom); |
156 if (spaceX == -1) |
147 QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); |
157 spaceX = wid->style()->layoutSpacing( |
148 int x = effectiveRect.x(); |
158 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); |
149 int y = effectiveRect.y(); |
159 int spaceY = verticalSpacing(); |
150 int lineHeight = 0; |
160 if (spaceY == -1) |
|
161 spaceY = wid->style()->layoutSpacing( |
|
162 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); |
|
163 int nextX = x + item->sizeHint().width() + spaceX; |
|
164 if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { |
|
165 x = effectiveRect.x(); |
|
166 y = y + lineHeight + spaceY; |
|
167 nextX = x + item->sizeHint().width() + spaceX; |
|
168 lineHeight = 0; |
|
169 } |
|
170 |
151 |
171 if (!testOnly) |
152 QLayoutItem *item; |
172 item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); |
153 foreach (item, itemList) { |
|
154 QWidget *wid = item->widget(); |
|
155 int spaceX = horizontalSpacing(); |
|
156 if (spaceX == -1) |
|
157 spaceX = wid->style()->layoutSpacing( |
|
158 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); |
|
159 int spaceY = verticalSpacing(); |
|
160 if (spaceY == -1) |
|
161 spaceY = wid->style()->layoutSpacing( |
|
162 QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); |
|
163 int nextX = x + item->sizeHint().width() + spaceX; |
|
164 if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { |
|
165 x = effectiveRect.x(); |
|
166 y = y + lineHeight + spaceY; |
|
167 nextX = x + item->sizeHint().width() + spaceX; |
|
168 lineHeight = 0; |
|
169 } |
173 |
170 |
174 x = nextX; |
171 if (!testOnly) |
175 lineHeight = qMax(lineHeight, item->sizeHint().height()); |
172 item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); |
176 } |
173 |
177 return y + lineHeight - rect.y() + bottom; |
174 x = nextX; |
178 } |
175 lineHeight = qMax(lineHeight, item->sizeHint().height()); |
179 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const |
176 } |
180 { |
177 return y + lineHeight - rect.y() + bottom; |
181 QObject *parent = this->parent(); |
178 } |
182 if (!parent) { |
179 int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const |
183 return -1; |
180 { |
184 } else if (parent->isWidgetType()) { |
181 QObject *parent = this->parent(); |
185 QWidget *pw = static_cast<QWidget *>(parent); |
182 if (!parent) { |
186 return pw->style()->pixelMetric(pm, 0, pw); |
183 return -1; |
187 } else { |
184 } else if (parent->isWidgetType()) { |
188 return static_cast<QLayout *>(parent)->spacing(); |
185 QWidget *pw = static_cast<QWidget *>(parent); |
189 } |
186 return pw->style()->pixelMetric(pm, 0, pw); |
190 } |
187 } else { |
|
188 return static_cast<QLayout *>(parent)->spacing(); |
|
189 } |
|
190 } |