RazorAutostartEntry => LxQt::AutostartEntry
[lxde/liblxqt.git] / razorgridlayout.cpp
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
34 class RazorGridLayoutPrivate
35 {
36 public:
37 RazorGridLayoutPrivate();
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;
54 QSize mPrefCellMinSize;
55 QSize mPrefCellMaxSize;
56 };
57
58
59 /************************************************
60
61 ************************************************/
62 RazorGridLayoutPrivate::RazorGridLayoutPrivate()
63 {
64 mColumnCount = 0;
65 mRowCount = 0;
66 mDirection = RazorGridLayout::LeftToRight;
67 mIsValid = false;
68 mVisibleCount = 0;
69 mStretch = RazorGridLayout::StretchHorizontal | RazorGridLayout::StretchVertical;
70 mPrefCellMinSize = QSize(0,0);
71 mPrefCellMaxSize = QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
72 }
73
74
75 /************************************************
76
77 ************************************************/
78 void RazorGridLayoutPrivate::updateCache()
79 {
80 mCellSizeHint = QSize(0, 0);
81 mCellMaxSize = QSize(0, 0);
82 mVisibleCount = 0;
83
84 for (int i=0; i<mItems.count(); ++i)
85 {
86 QLayoutItem *item = mItems.at(i);
87 if (!item->widget() || item->widget()->isHidden())
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
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++;
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
117 }
118 mCellSizeHint.rwidth() = qBound(mPrefCellMinSize.width(), mCellSizeHint.width(), mPrefCellMaxSize.width());
119 mCellSizeHint.rheight()= qBound(mPrefCellMinSize.height(), mCellSizeHint.height(), mPrefCellMaxSize.height());
120 mIsValid = !mCellSizeHint.isEmpty();
121 }
122
123
124 /************************************************
125
126 ************************************************/
127 int 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 ************************************************/
142 int 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 ************************************************/
159 RazorGridLayout::RazorGridLayout(QWidget *parent):
160 QLayout(parent),
161 d_ptr(new RazorGridLayoutPrivate())
162 {
163 }
164
165
166 /************************************************
167
168 ************************************************/
169 RazorGridLayout::~RazorGridLayout()
170 {
171 delete d_ptr;
172 }
173
174
175 /************************************************
176
177 ************************************************/
178 void RazorGridLayout::addItem(QLayoutItem *item)
179 {
180 d_ptr->mItems.append(item);
181 }
182
183
184 /************************************************
185
186 ************************************************/
187 QLayoutItem *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 ************************************************/
200 QLayoutItem *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 ************************************************/
214 int RazorGridLayout::count() const
215 {
216 Q_D(const RazorGridLayout);
217 return d->mItems.count();
218 }
219
220
221 /************************************************
222
223 ************************************************/
224 void RazorGridLayout::invalidate()
225 {
226 Q_D(RazorGridLayout);
227 d->mIsValid = false;
228 QLayout::invalidate();
229 }
230
231
232 /************************************************
233
234 ************************************************/
235 int RazorGridLayout::rowCount() const
236 {
237 Q_D(const RazorGridLayout);
238 return d->mRowCount;
239 }
240
241
242 /************************************************
243
244 ************************************************/
245 void 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 ************************************************/
259 int RazorGridLayout::columnCount() const
260 {
261 Q_D(const RazorGridLayout);
262 return d->mColumnCount;
263 }
264
265
266 /************************************************
267
268 ************************************************/
269 void 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 ************************************************/
283 RazorGridLayout::Direction RazorGridLayout::direction() const
284 {
285 Q_D(const RazorGridLayout);
286 return d->mDirection;
287 }
288
289
290 /************************************************
291
292 ************************************************/
293 void 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 ************************************************/
306 RazorGridLayout::Stretch RazorGridLayout::stretch() const
307 {
308 Q_D(const RazorGridLayout);
309 return d->mStretch;
310 }
311
312 /************************************************
313
314 ************************************************/
315 void 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 /************************************************
327
328 ************************************************/
329 void RazorGridLayout::moveItem(int from, int to)
330 {
331 Q_D(RazorGridLayout);
332 d->mItems.move(from, to);
333 invalidate();
334 }
335
336
337 /************************************************
338
339 ************************************************/
340 QSize RazorGridLayout::cellMinimumSize() const
341 {
342 Q_D(const RazorGridLayout);
343 return d->mPrefCellMinSize;
344 }
345
346
347 /************************************************
348
349 ************************************************/
350 void 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 ************************************************/
364 void 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 ************************************************/
378 void 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 ************************************************/
392 QSize RazorGridLayout::cellMaximumSize() const
393 {
394 Q_D(const RazorGridLayout);
395 return d->mPrefCellMaxSize;
396 }
397
398
399 /************************************************
400
401 ************************************************/
402 void 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 ************************************************/
416 void 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 ************************************************/
430 void 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 ************************************************/
444 void 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 ************************************************/
460 void 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 ************************************************/
476 void 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 ************************************************/
492 QSize 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 ************************************************/
507 void 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
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
526 int itemWidth;
527 if (d->mStretch.testFlag(StretchHorizontal))
528 {
529 itemWidth = geometry.width() * 1.0 / d->cols();
530 itemWidth = qMin(itemWidth, d->mCellMaxSize.width());
531 }
532 else
533 {
534 itemWidth = d->mCellSizeHint.width();
535 }
536
537 itemWidth = qBound(d->mPrefCellMinSize.width(), itemWidth, d->mPrefCellMaxSize.width());
538
539 int itemHeight;
540 if (d->mStretch.testFlag(StretchVertical))
541 {
542 itemHeight = geometry.height() * 1.0 / d->rows();
543 itemHeight = qMin(itemHeight, d->mCellMaxSize.height());
544 }
545 else
546 {
547 itemHeight = d->mCellSizeHint.height();
548 }
549
550 itemHeight = qBound(d->mPrefCellMinSize.height(), itemHeight, d->mPrefCellMaxSize.height());
551
552
553 #if 0
554 qDebug() << "** RazorGridLayout::setGeometry *******************************";
555 qDebug() << "Geometry:" << geometry;
556 qDebug() << "CellSize:" << d->mCellSizeHint;
557 qDebug() << "Constraints:" << "min" << d->mPrefCellMinSize << "max" << d->mPrefCellMaxSize;
558 qDebug() << "Count" << count();
559 qDebug() << "Cols:" << d->cols() << "(" << d->mColumnCount << ")";
560 qDebug() << "Rows:" << d->rows() << "(" << d->mRowCount << ")";
561 qDebug() << "Stretch:" << "h:" << (d->mStretch.testFlag(StretchHorizontal)) << " v:" << (d->mStretch.testFlag(StretchVertical));
562 qDebug() << "Item:" << "h:" << itemHeight << " w:" << itemWidth;
563 #endif
564
565 if (d->mDirection == LeftToRight)
566 {
567 foreach(QLayoutItem *item, d->mItems)
568 {
569 if (!item->widget() || item->widget()->isHidden())
570 continue;
571
572 if (x + itemWidth > maxX)
573 {
574 x = geometry.left();
575 if (d->mStretch.testFlag(StretchVertical))
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 {
590 if (!item->widget() || item->widget()->isHidden())
591 continue;
592
593 if (y + itemHeight > maxY)
594 {
595 y = geometry.top();
596 if (d->mStretch.testFlag(StretchHorizontal))
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