• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • workspace API Reference
  • KDE Home
  • Contact Us
 

liblancelot

  • sources
  • kde-4.14
  • workspace
  • kdeplasma-addons
  • libs
  • lancelot
  • layouts
ColumnLayout.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010 Ivan Cukic <ivan.cukic(at)kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser/Library General Public License version 2,
6  * or (at your option) any later version, as published by the Free
7  * Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser/Library General Public License for more details
13  *
14  * You should have received a copy of the GNU Lesser/Library General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include "ColumnLayout.h"
21 
22 #include <QGraphicsScene>
23 #include <QGraphicsWidget>
24 #include <QPropertyAnimation>
25 #include <QList>
26 #include <QDebug>
27 #include <QPointer>
28 
29 #include <Global.h>
30 #include <KConfig>
31 #include <KConfigGroup>
32 
33 #define GOLDEN_SIZE 0.381966011250105 // 1 / (1 + phi); phi = (sqrt(5) + 1) / 2
34 
35 namespace Lancelot
36 {
37 
38 class GoldenColumnSizer: public ColumnLayout::ColumnSizer {
39 public:
40  void init(int count) {
41  m_position = 0;
42  qreal size = 1.0;
43  m_sizes.clear();
44  while (count) {
45  if (count == 1) {
46  m_sizes.prepend(size);
47  } else if (count == 2) {
48  m_sizes.prepend((1 - GOLDEN_SIZE) * size);
49  size *= GOLDEN_SIZE;
50  } else {
51  m_sizes.prepend(size * GOLDEN_SIZE);
52  size -= size * GOLDEN_SIZE;
53  }
54  --count;
55  }
56  }
57 
58  qreal size() {
59  if (m_position < 0 || m_position > m_sizes.size()) return 0;
60  return m_sizes.at(m_position++);
61  }
62 private:
63  QList < qreal > m_sizes;
64  int m_position;
65 };
66 
67 class EqualColumnSizer: public ColumnLayout::ColumnSizer {
68 public:
69  void init(int count) {
70  m_count = count;
71  }
72 
73  qreal size() {
74  return 1.0 / m_count;
75  }
76 private:
77  int m_count;
78 };
79 
80 ColumnLayout::ColumnSizer::~ColumnSizer()
81 {
82 }
83 
84 ColumnLayout::ColumnSizer * ColumnLayout::ColumnSizer::create(SizerType type)
85 {
86  switch (type) {
87  case EqualSizer:
88  return new EqualColumnSizer();
89  case GoldenSizer:
90  return new GoldenColumnSizer();
91  }
92  return NULL;
93 }
94 
95 class ColumnLayout::Private {
96 public:
97  ColumnLayout * q;
98  QList < QGraphicsWidget * > items;
99  QHash < QGraphicsWidget *, QPointer < QPropertyAnimation > > animators;
100 
101  QGraphicsItem * parentItem;
102  ColumnLayout::ColumnSizer * sizer;
103 
104  int count;
105  bool animate;
106 
107  enum RelayoutType { Clean, Push, Pop, Resize };
108 
109  Private(ColumnLayout * parent)
110  : q(parent), parentItem(NULL),
111  sizer(new GoldenColumnSizer()), count(2)
112  {
113  animate = !Global::self()->config("Animation", "disableAnimations", false)
114  && Global::self()->config("Animation", "columnLayoutAnimaiton", true);
115  }
116  ~Private()
117  {
118  delete sizer;
119  }
120 
121  QPropertyAnimation * animator(QGraphicsWidget * item, const QByteArray & property)
122  {
123  QPropertyAnimation * result;
124 
125  if (animators.contains(item) && animators[item]) {
126  result = animators[item];
127  result->stop();
128  result->setPropertyName(property);
129 
130  } else {
131  animators[item] = new QPropertyAnimation(item, property);
132  result = animators[item];
133  }
134 
135  return result;
136  }
137 
138  void moveItemTo(QGraphicsWidget * item, QRectF newGeometry)
139  {
140  if (!animate) {
141  item->setGeometry(newGeometry);
142  item->show();
143  item->setOpacity(1);
144  return;
145  }
146 
147  if (newGeometry.width() < 1) {
148  hideItem(item);
149  }
150 
151  if (item->isVisible()) {
152  // Moving the item
153 
154  if (item->geometry().height() == newGeometry.height()) {
155  QPropertyAnimation * animation = animator(item, "geometry");
156  animation->setDuration(300);
157  animation->setStartValue(item->geometry());
158  animation->setEndValue(newGeometry);
159  animation->start();
160 
161  } else {
162  item->setGeometry(newGeometry);
163 
164  }
165 
166  } else {
167  // Showing the item
168 
169  item->setGeometry(newGeometry);
170  item->setOpacity(0);
171  item->show();
172 
173  QPropertyAnimation * animation = animator(item, "opacity");
174  animation->setDuration(300);
175  animation->setStartValue(0);
176  animation->setEndValue(1);
177  animation->start();
178 
179  }
180  }
181 
182  void hideItem(QGraphicsWidget * item)
183  {
184  if (!animate) {
185  item->hide();
186  return;
187  }
188 
189  if (!item->isVisible()) {
190  return;
191  }
192 
193  item->setOpacity(1);
194 
195  QPropertyAnimation * animation = animator(item, "opacity");
196  animation->setDuration(300);
197  animation->setStartValue(1);
198  animation->setEndValue(0);
199  animation->start();
200 
201  //item->connect(animation, SIGNAL(finished()), SLOT(hide()));
202  }
203 
204  void relayout(RelayoutType type = Clean)
205  {
206  Q_UNUSED(type);
207  if (items.size() == 0) return;
208 
209  int showItems = qMin(items.size(), count + 1);
210  sizer->init(showItems);
211 
212  qreal left, top, right, bottom;
213  q->getContentsMargins(&left, &top, &right, &bottom);
214 
215  QRectF newGeometry = q->geometry().adjusted(left, top, right, bottom);
216  qreal width = newGeometry.width();
217 
218 
219  int i = 0;
220 
221  foreach (QGraphicsWidget * item, items) {
222  if (items.size() - showItems > i++) {
223  hideItem(item);
224 
225  } else {
226  int itemWidth = sizer->size() * width;
227 
228  newGeometry.setWidth(itemWidth);
229 
230  moveItemTo(item, newGeometry);
231 
232  newGeometry.moveLeft(newGeometry.left() + itemWidth);
233  }
234  }
235  }
236 
237  void push(QGraphicsWidget * widget)
238  {
239  if (!widget || items.contains(widget)) {
240  return;
241  }
242 
243  //TODO: Uncomment : widget->hide();
244  items.append(widget);
245 
246  q->updateGeometry();
247  }
248 
249  QGraphicsWidget * pop()
250  {
251  QGraphicsWidget * widget = items.takeLast();
252 
253  animators.remove(widget);
254 
255  relayout(Pop);
256  return widget;
257  }
258 };
259 
260 void ColumnLayout::setSizer(ColumnLayout::ColumnSizer * sizer)
261 {
262  delete d->sizer;
263  d->sizer = sizer;
264  d->relayout(Private::Resize);
265 }
266 
267 ColumnLayout::ColumnSizer * ColumnLayout::sizer() const
268 {
269  return d->sizer;
270 }
271 
272 QSizeF ColumnLayout::sizeHint(Qt::SizeHint which,
273  const QSizeF & constraint) const
274 {
275  Q_UNUSED(which);
276  Q_UNUSED(constraint);
277  return QSizeF();
278 }
279 
280 void ColumnLayout::push(QGraphicsWidget * widget)
281 {
282  d->push(widget);
283 }
284 
285 QGraphicsWidget * ColumnLayout::pop()
286 {
287  return d->pop();
288 }
289 
290 void ColumnLayout::setColumnCount(int count)
291 {
292  if (count < 1) return;
293  d->count = count;
294  d->relayout(Private::Clean);
295 }
296 
297 int ColumnLayout::columnCount() const
298 {
299  return d->count;
300 }
301 
302 ColumnLayout::ColumnLayout(QGraphicsLayoutItem * parent)
303  : QGraphicsLayout(parent), d(new Private(this))
304 {
305 
306 }
307 
308 ColumnLayout::~ColumnLayout()
309 {
310  delete d;
311 }
312 
313 void ColumnLayout::removeAt(int index)
314 {
315  Q_UNUSED(index);
316 }
317 
318 QGraphicsLayoutItem * ColumnLayout::itemAt(int i) const
319 {
320  return d->items.at(i);
321 }
322 
323 int ColumnLayout::count() const
324 {
325  return d->items.size();
326 }
327 
328 void ColumnLayout::setGeometry(const QRectF & rect)
329 {
330  QGraphicsLayout::setGeometry(rect);
331  d->relayout();
332 }
333 
334 } // namespace Lancelot
335 
ColumnLayout.h
Lancelot::ColumnLayout::ColumnSizer::SizerType
SizerType
Definition: ColumnLayout.h:84
Lancelot::ColumnLayout::sizeHint
L_Override QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Definition: ColumnLayout.cpp:272
Lancelot::ColumnLayout::~ColumnLayout
~ColumnLayout()
Destroys Lancelot::ColumnLayout.
Definition: ColumnLayout.cpp:308
QByteArray
Lancelot::ColumnLayout
This layout is not a general purpose layout, and should not be used as such.
Definition: ColumnLayout.h:49
Lancelot::ColumnLayout::columnCount
int columnCount() const
Definition: ColumnLayout.cpp:297
Lancelot::Global::self
static Global * self()
Definition: Global.cpp:307
Lancelot::ColumnLayout::ColumnSizer::init
virtual void init(int count)=0
Initializes the ColumnSizer.
Lancelot::ColumnLayout::setGeometry
L_Override void setGeometry(const QRectF &rect)
Definition: ColumnLayout.cpp:328
GOLDEN_SIZE
#define GOLDEN_SIZE
Definition: ColumnLayout.cpp:33
QPropertyAnimation::setPropertyName
void setPropertyName(const QByteArray &propertyName)
QGraphicsItem
QGraphicsItem::hide
void hide()
QRectF::left
qreal left() const
QVariantAnimation::setStartValue
void setStartValue(const QVariant &value)
Lancelot::ColumnLayout::ColumnSizer::size
virtual qreal size()=0
QAbstractAnimation::stop
void stop()
QPropertyAnimation
QHash
Lancelot::Global::config
KConfig * config()
Definition: Global.cpp:425
QRectF::moveLeft
void moveLeft(qreal x)
QGraphicsWidget
Global.h
QList< qreal >
QGraphicsItem::setOpacity
void setOpacity(qreal opacity)
Lancelot::ColumnLayout::push
void push(QGraphicsWidget *widget)
Pushes the specified widget to the end of stack.
Definition: ColumnLayout.cpp:280
Lancelot::ColumnLayout::setSizer
void setSizer(ColumnSizer *sizer)
Sets the ColumnSizer object.
Definition: ColumnLayout.cpp:260
Lancelot::ColumnLayout::ColumnSizer
Abstract interface for implementing column size calculation depending on the column count...
Definition: ColumnLayout.h:59
Lancelot::ColumnLayout::removeAt
L_Override void removeAt(int index)
Not implemented.
Definition: ColumnLayout.cpp:313
Lancelot::ColumnLayout::itemAt
L_Override QGraphicsLayoutItem * itemAt(int i) const
Definition: ColumnLayout.cpp:318
QGraphicsItem::isVisible
bool isVisible() const
QRectF::width
qreal width() const
QSizeF
Lancelot::ColumnLayout::count
L_Override int count() const
Definition: ColumnLayout.cpp:323
QRectF
QRectF::setWidth
void setWidth(qreal width)
Lancelot::ColumnLayout::ColumnSizer::create
static ColumnSizer * create(SizerType type)
Definition: ColumnLayout.cpp:84
Lancelot::ColumnLayout::sizer
ColumnSizer * sizer() const
Definition: ColumnLayout.cpp:267
Lancelot::ColumnLayout::pop
QGraphicsWidget * pop()
Removes the last widget from the stack and returns it.
Definition: ColumnLayout.cpp:285
Lancelot::ColumnLayout::ColumnSizer::~ColumnSizer
virtual ~ColumnSizer()
Destroys the ColumnLayout::ColumnSizer.
Definition: ColumnLayout.cpp:80
QVariantAnimation::setEndValue
void setEndValue(const QVariant &value)
QVariantAnimation::setDuration
void setDuration(int msecs)
QGraphicsLayout
QRectF::adjusted
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const
QRectF::height
qreal height() const
QAbstractAnimation::start
void start(QAbstractAnimation::DeletionPolicy policy)
QGraphicsItem::show
void show()
Lancelot::ColumnLayout::ColumnLayout
ColumnLayout(QGraphicsLayoutItem *parent=0)
Creates a new Lancelot::ColumnLayout.
Definition: ColumnLayout.cpp:302
QGraphicsItem::contains
virtual bool contains(const QPointF &point) const
Lancelot::ColumnLayout::setColumnCount
void setColumnCount(int count)
Sets the maximum number of visible columns.
Definition: ColumnLayout.cpp:290
QGraphicsWidget::setGeometry
virtual void setGeometry(const QRectF &rect)
QGraphicsLayoutItem
QGraphicsLayoutItem::setGeometry
virtual void setGeometry(const QRectF &rect)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:43:01 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

liblancelot

Skip menu "liblancelot"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

workspace API Reference

Skip menu "workspace API Reference"
  • kdeplasma-addons
  •       GroupingDesktop
  •     liblancelot

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal