RazorAutostartEntry => LxQt::AutostartEntry
[lxde/liblxqt.git] / razorgridlayout.cpp
CommitLineData
ca1b12f4
AS
1/* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
4 * Razor - a lightweight, Qt based, desktop toolset
5 * http://razor-qt.org
6 *
7 * Copyright: 2012 Razor team
8 * Authors:
9 * Alexander Sokoloff <sokoloff.a@gmail.com>
10 *
11 * This program or library is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20
21 * You should have received a copy of the GNU Lesser General
22 * Public License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
25 *
26 * END_COMMON_COPYRIGHT_HEADER */
27
28
29#include "razorgridlayout.h"
30#include <QtGui/QWidget>
31#include <QtCore/QDebug>
32#include <math.h>
33
34class RazorGridLayoutPrivate
35{
36public:
a654e583 37 RazorGridLayoutPrivate();
ca1b12f4
AS
38
39 QList<QLayoutItem*> mItems;
40 int mRowCount;
41 int mColumnCount;
42 RazorGridLayout::Direction mDirection;
43
44 bool mIsValid;
45 QSize mCellSizeHint;
46 QSize mCellMaxSize;
47 int mVisibleCount;
48 RazorGridLayout::Stretch mStretch;
49
50
51 void updateCache();
52 int rows() const;
53 int cols() const;
a654e583
AS
54 QSize mPrefCellMinSize;
55 QSize mPrefCellMaxSize;
ca1b12f4
AS
56};
57
58
59/************************************************
60
61 ************************************************/
a654e583
AS
62RazorGridLayoutPrivate::RazorGridLayoutPrivate()
63{
64 mColumnCount = 0;
65 mRowCount = 0;
66 mDirection = RazorGridLayout::LeftToRight;
67 mIsValid = false;
68 mVisibleCount = 0;
39b2c497 69 mStretch = RazorGridLayout::StretchHorizontal | RazorGridLayout::StretchVertical;
a654e583
AS
70 mPrefCellMinSize = QSize(0,0);
71 mPrefCellMaxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
72}
73
74
75/************************************************
76
77 ************************************************/
ca1b12f4
AS
78void RazorGridLayoutPrivate::updateCache()
79{
40e2257e
AS
80 mCellSizeHint = QSize(0, 0);
81 mCellMaxSize = QSize(0, 0);
ca1b12f4
AS
82 mVisibleCount = 0;
83
84 for (int i=0; i<mItems.count(); ++i)
85 {
86 QLayoutItem *item = mItems.at(i);
d32e88ab 87 if (!item->widget() || item->widget()->isHidden())
ca1b12f4
AS
88 continue;
89
90 int h = qBound(item->minimumSize().height(),
91 item->sizeHint().height(),
92 item->maximumSize().height());
93
94 int w = qBound(item->minimumSize().width(),
95 item->sizeHint().width(),
96 item->maximumSize().width());
97
ca1b12f4
AS
98 mCellSizeHint.rheight() = qMax(mCellSizeHint.height(), h);
99 mCellSizeHint.rwidth() = qMax(mCellSizeHint.width(), w);
100
101 mCellMaxSize.rheight() = qMax(mCellMaxSize.height(), item->maximumSize().height());
102 mCellMaxSize.rwidth() = qMax(mCellMaxSize.width(), item->maximumSize().width());
103 mVisibleCount++;
40e2257e
AS
104
105#if 0
106 qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
107 qDebug() << "item.min" << item->minimumSize().width();
108 qDebug() << "item.sz " << item->sizeHint().width();
109 qDebug() << "item.max" << item->maximumSize().width();
110 qDebug() << "w h" << w << h;
111 qDebug() << "wid.sizeHint" << item->widget()->sizeHint();
112 qDebug() << "mCellSizeHint:" << mCellSizeHint;
113 qDebug() << "mCellMaxSize: " << mCellMaxSize;
114 qDebug() << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-";
115#endif
116
ca1b12f4 117 }
a654e583
AS
118 mCellSizeHint.rwidth() = qBound(mPrefCellMinSize.width(), mCellSizeHint.width(), mPrefCellMaxSize.width());
119 mCellSizeHint.rheight()= qBound(mPrefCellMinSize.height(), mCellSizeHint.height(), mPrefCellMaxSize.height());
40e2257e 120 mIsValid = !mCellSizeHint.isEmpty();
ca1b12f4
AS
121}
122
123
124/************************************************
125
126 ************************************************/
127int RazorGridLayoutPrivate::rows() const
128{
129 if (mRowCount)
130 return mRowCount;
131
132 if (!mColumnCount)
133 return 1;
134
135 return ceil(mVisibleCount * 1.0 / mColumnCount);
136}
137
138
139/************************************************
140
141 ************************************************/
142int RazorGridLayoutPrivate::cols() const
143{
144 if (mColumnCount)
145 return mColumnCount;
146
147 int rows = mRowCount;
148 if (!rows)
149 rows = 1;
150
151 return ceil(mVisibleCount * 1.0 / rows);
152}
153
154
155
156/************************************************
157
158 ************************************************/
159RazorGridLayout::RazorGridLayout(QWidget *parent):
160 QLayout(parent),
161 d_ptr(new RazorGridLayoutPrivate())
162{
ca1b12f4
AS
163}
164
165
166/************************************************
167
168 ************************************************/
169RazorGridLayout::~RazorGridLayout()
170{
171 delete d_ptr;
172}
173
174
175/************************************************
176
177 ************************************************/
178void RazorGridLayout::addItem(QLayoutItem *item)
179{
180 d_ptr->mItems.append(item);
181}
182
183
184/************************************************
185
186 ************************************************/
187QLayoutItem *RazorGridLayout::itemAt(int index) const
188{
189 Q_D(const RazorGridLayout);
190 if (index < 0 || index >= d->mItems.count())
191 return 0;
192
193 return d->mItems.at(index);
194}
195
196
197/************************************************
198
199 ************************************************/
200QLayoutItem *RazorGridLayout::takeAt(int index)
201{
202 Q_D(RazorGridLayout);
203 if (index < 0 || index >= d->mItems.count())
204 return 0;
205
206 QLayoutItem *item = d->mItems.takeAt(index);
207 return item;
208}
209
210
211/************************************************
212
213 ************************************************/
214int RazorGridLayout::count() const
215{
216 Q_D(const RazorGridLayout);
217 return d->mItems.count();
218}
219
220
221/************************************************
222
223 ************************************************/
224void RazorGridLayout::invalidate()
225{
226 Q_D(RazorGridLayout);
227 d->mIsValid = false;
228 QLayout::invalidate();
229}
230
231
232/************************************************
233
234 ************************************************/
235int RazorGridLayout::rowCount() const
236{
237 Q_D(const RazorGridLayout);
238 return d->mRowCount;
239}
240
241
242/************************************************
243
244 ************************************************/
245void RazorGridLayout::setRowCount(int value)
246{
247 Q_D(RazorGridLayout);
248 if (d->mRowCount != value)
249 {
250 d->mRowCount = value;
251 invalidate();
252 }
253}
254
255
256/************************************************
257
258 ************************************************/
259int RazorGridLayout::columnCount() const
260{
261 Q_D(const RazorGridLayout);
262 return d->mColumnCount;
263}
264
265
266/************************************************
267
268 ************************************************/
269void RazorGridLayout::setColumnCount(int value)
270{
271 Q_D(RazorGridLayout);
272 if (d->mColumnCount != value)
273 {
274 d->mColumnCount = value;
275 invalidate();
276 }
277}
278
279
280/************************************************
281
282 ************************************************/
283RazorGridLayout::Direction RazorGridLayout::direction() const
284{
285 Q_D(const RazorGridLayout);
286 return d->mDirection;
287}
288
289
290/************************************************
291
292 ************************************************/
293void RazorGridLayout::setDirection(RazorGridLayout::Direction value)
294{
295 Q_D(RazorGridLayout);
296 if (d->mDirection != value)
297 {
298 d->mDirection = value;
299 invalidate();
300 }
301}
302
303/************************************************
304
305 ************************************************/
306RazorGridLayout::Stretch RazorGridLayout::stretch() const
307{
308 Q_D(const RazorGridLayout);
309 return d->mStretch;
310}
311
312/************************************************
313
314 ************************************************/
315void RazorGridLayout::setStretch(Stretch value)
316{
317 Q_D(RazorGridLayout);
318 if (d->mStretch != value)
319 {
320 d->mStretch = value;
321 invalidate();
322 }
323}
324
325
326/************************************************
5a1ce682
AS
327
328 ************************************************/
329void RazorGridLayout::moveItem(int from, int to)
330{
331 Q_D(RazorGridLayout);
332 d->mItems.move(from, to);
333 invalidate();
334}
335
336
337/************************************************
ca1b12f4
AS
338
339 ************************************************/
a654e583
AS
340QSize RazorGridLayout::cellMinimumSize() const
341{
342 Q_D(const RazorGridLayout);
343 return d->mPrefCellMinSize;
344}
345
346
347/************************************************
348
349 ************************************************/
350void RazorGridLayout::setCellMinimumSize(QSize minSize)
351{
352 Q_D(RazorGridLayout);
353 if (d->mPrefCellMinSize != minSize)
354 {
355 d->mPrefCellMinSize = minSize;
356 invalidate();
357 }
358}
359
360
361/************************************************
362
363 ************************************************/
05a1e105
AS
364void RazorGridLayout::setCellMinimumHeight(int value)
365{
366 Q_D(RazorGridLayout);
367 if (d->mPrefCellMinSize.height() != value)
368 {
369 d->mPrefCellMinSize.setHeight(value);
370 invalidate();
371 }
372}
373
374
375/************************************************
376
377 ************************************************/
378void RazorGridLayout::setCellMinimumWidth(int value)
379{
380 Q_D(RazorGridLayout);
381 if (d->mPrefCellMinSize.width() != value)
382 {
383 d->mPrefCellMinSize.setWidth(value);
384 invalidate();
385 }
386}
387
388
389/************************************************
390
391 ************************************************/
a654e583
AS
392QSize RazorGridLayout::cellMaximumSize() const
393{
394 Q_D(const RazorGridLayout);
395 return d->mPrefCellMaxSize;
396}
397
398
399/************************************************
400
401 ************************************************/
402void RazorGridLayout::setCellMaximumSize(QSize maxSize)
403{
404 Q_D(RazorGridLayout);
405 if (d->mPrefCellMaxSize != maxSize)
406 {
407 d->mPrefCellMaxSize = maxSize;
408 invalidate();
409 }
410}
411
412
413/************************************************
414
415 ************************************************/
05a1e105
AS
416void RazorGridLayout::setCellMaximumHeight(int value)
417{
418 Q_D(RazorGridLayout);
419 if (d->mPrefCellMaxSize.height() != value)
420 {
421 d->mPrefCellMaxSize.setHeight(value);
422 invalidate();
423 }
424}
425
426
427/************************************************
428
429 ************************************************/
430void RazorGridLayout::setCellMaximumWidth(int value)
431{
432 Q_D(RazorGridLayout);
433 if (d->mPrefCellMaxSize.width() != value)
434 {
435 d->mPrefCellMaxSize.setWidth(value);
436 invalidate();
437 }
438}
439
440
441/************************************************
442
443 ************************************************/
444void RazorGridLayout::setCellFixedSize(QSize size)
445{
446 Q_D(RazorGridLayout);
447 if (d->mPrefCellMinSize != size ||
448 d->mPrefCellMaxSize != size)
449 {
450 d->mPrefCellMinSize = size;
451 d->mPrefCellMaxSize = size;
452 invalidate();
453 }
454}
455
456
457/************************************************
458
459 ************************************************/
460void RazorGridLayout::setCellFixedHeight(int value)
461{
462 Q_D(RazorGridLayout);
463 if (d->mPrefCellMinSize.height() != value ||
464 d->mPrefCellMaxSize.height() != value)
465 {
466 d->mPrefCellMinSize.setHeight(value);
467 d->mPrefCellMaxSize.setHeight(value);
468 invalidate();
469 }
470}
471
472
473/************************************************
474
475 ************************************************/
476void RazorGridLayout::setCellFixedWidth(int value)
477{
478 Q_D(RazorGridLayout);
479 if (d->mPrefCellMinSize.width() != value ||
480 d->mPrefCellMaxSize.width() != value)
481 {
482 d->mPrefCellMinSize.setWidth(value);
483 d->mPrefCellMaxSize.setWidth(value);
484 invalidate();
485 }
486}
487
488
489/************************************************
490
491 ************************************************/
ca1b12f4
AS
492QSize RazorGridLayout::sizeHint() const
493{
494 Q_D(const RazorGridLayout);
495
496 if (!d->mIsValid)
497 const_cast<RazorGridLayoutPrivate*>(d)->updateCache();
498
499 return QSize(d->cols() * d->mCellSizeHint.width(),
500 d->rows() * d->mCellSizeHint.height());
501}
502
503
504/************************************************
505
506 ************************************************/
507void RazorGridLayout::setGeometry(const QRect &geometry)
508{
509 Q_D(RazorGridLayout);
510
511 if (!d->mIsValid)
512 d->updateCache();
513
514 int y = geometry.top();
515 int x = geometry.left();
516
a654e583
AS
517 // For historical reasons QRect::right returns left() + width() - 1
518 // and QRect::bottom() returns top() + height() - 1;
519 // So we use left() + height() and top() + height()
520 //
521 // http://qt-project.org/doc/qt-4.8/qrect.html
522
523 int maxX = geometry.left() + geometry.width();
524 int maxY = geometry.top() + geometry.height();
525
ca1b12f4 526 int itemWidth;
39b2c497 527 if (d->mStretch.testFlag(StretchHorizontal))
ca1b12f4 528 {
a654e583 529 itemWidth = geometry.width() * 1.0 / d->cols();
ca1b12f4
AS
530 itemWidth = qMin(itemWidth, d->mCellMaxSize.width());
531 }
532 else
533 {
534 itemWidth = d->mCellSizeHint.width();
535 }
536
a654e583
AS
537 itemWidth = qBound(d->mPrefCellMinSize.width(), itemWidth, d->mPrefCellMaxSize.width());
538
ca1b12f4 539 int itemHeight;
39b2c497 540 if (d->mStretch.testFlag(StretchVertical))
ca1b12f4 541 {
a654e583 542 itemHeight = geometry.height() * 1.0 / d->rows();
ca1b12f4
AS
543 itemHeight = qMin(itemHeight, d->mCellMaxSize.height());
544 }
545 else
546 {
547 itemHeight = d->mCellSizeHint.height();
548 }
549
a654e583
AS
550 itemHeight = qBound(d->mPrefCellMinSize.height(), itemHeight, d->mPrefCellMaxSize.height());
551
552
ca1b12f4
AS
553#if 0
554 qDebug() << "** RazorGridLayout::setGeometry *******************************";
a654e583
AS
555 qDebug() << "Geometry:" << geometry;
556 qDebug() << "CellSize:" << d->mCellSizeHint;
557 qDebug() << "Constraints:" << "min" << d->mPrefCellMinSize << "max" << d->mPrefCellMaxSize;
40e2257e 558 qDebug() << "Count" << count();
ca1b12f4
AS
559 qDebug() << "Cols:" << d->cols() << "(" << d->mColumnCount << ")";
560 qDebug() << "Rows:" << d->rows() << "(" << d->mRowCount << ")";
9604060d 561 qDebug() << "Stretch:" << "h:" << (d->mStretch.testFlag(StretchHorizontal)) << " v:" << (d->mStretch.testFlag(StretchVertical));
ca1b12f4
AS
562 qDebug() << "Item:" << "h:" << itemHeight << " w:" << itemWidth;
563#endif
564
565 if (d->mDirection == LeftToRight)
566 {
567 foreach(QLayoutItem *item, d->mItems)
568 {
d32e88ab 569 if (!item->widget() || item->widget()->isHidden())
ca1b12f4 570 continue;
a654e583
AS
571
572 if (x + itemWidth > maxX)
ca1b12f4
AS
573 {
574 x = geometry.left();
39b2c497 575 if (d->mStretch.testFlag(StretchVertical))
ca1b12f4
AS
576 y += geometry.height() / d->rows();
577 else
578 y += itemHeight;
579
580 }
581
582 item->setGeometry(QRect(x, y, itemWidth, itemHeight));
583 x += itemWidth;
584 }
585 }
586 else
587 {
588 foreach(QLayoutItem *item, d->mItems)
589 {
d32e88ab 590 if (!item->widget() || item->widget()->isHidden())
ca1b12f4
AS
591 continue;
592
a654e583 593 if (y + itemHeight > maxY)
ca1b12f4
AS
594 {
595 y = geometry.top();
39b2c497 596 if (d->mStretch.testFlag(StretchHorizontal))
ca1b12f4
AS
597 x += geometry.width() / d->rows();
598 else
599 x += itemWidth;
600
601 }
602 item->setGeometry(QRect(x, y, itemWidth, itemHeight));
603 y += itemHeight;
604 }
605 }
606}
607