• 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
NodeLayout.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 "NodeLayout.h"
21 #include "Global.h"
22 
23 #include <QMap>
24 #include <QPair>
25 
26 #include <lancelot/lancelot.h>
27 
28 #include <limits>
29 
30 namespace Lancelot
31 {
32 
33 NodeLayout::NodeCoordinate::NodeCoordinate(qreal xRelative, qreal yRelative, qreal xAbsolute, qreal yAbsolute)
34  : xr(xRelative), xa(xAbsolute), yr(yRelative), ya(yAbsolute) {}
35 
36 NodeLayout::NodeCoordinate NodeLayout::NodeCoordinate::simple(qreal x, qreal y,
37  CoordinateType xType, CoordinateType yType)
38 {
39  NodeLayout::NodeCoordinate coo;
40  switch (xType) {
41  case Relative:
42  coo.xr = x;
43  coo.xa = 0;
44  break;
45  case Absolute:
46  coo.xr = 0;
47  coo.xa = x;
48  break;
49  case InnerRelative:
50  coo.xr = x;
51  coo.xa = QREAL_INFINITY;
52  break;
53  }
54 
55  switch (yType) {
56  case Relative:
57  coo.yr = y;
58  coo.ya = 0;
59  break;
60  case Absolute:
61  coo.yr = 0;
62  coo.ya = y;
63  break;
64  case InnerRelative:
65  coo.yr = y;
66  coo.ya = QREAL_INFINITY;
67  break;
68  }
69  return coo;
70 }
71 
72 class NodeLayout::Private {
73 public:
74  QMap <QGraphicsLayoutItem * , QPair < NodeCoordinate, NodeCoordinate > > items;
75  NodeLayout * parent;
76  QMap < Qt::SizeHint, QSizeF > sizeHintCache;
77 
78  Private(NodeLayout * parentLayout) {
79  parent = parentLayout;
80  }
81 
82  void relayout()
83  {
84  foreach (QGraphicsLayoutItem * item, items.keys()) // krazy:exclude=foreach
85  {
86  if (item) {
87  item->setGeometry(calculateRectangle(item));
88  }
89  }
90  }
91 
92  qreal calculateXPosition(const NodeCoordinate & coo, const QRectF & parentGeometry) const
93  {
94  return parentGeometry.left() + (coo.xr * parentGeometry.width()) + coo.xa;
95  }
96 
97  qreal calculateYPosition(const NodeCoordinate & coo, const QRectF & parentGeometry) const
98  {
99  return parentGeometry.top() + (coo.yr * parentGeometry.height()) + coo.ya;
100  }
101 
102  QPointF calculatePosition(const NodeCoordinate & coo, const QRectF & parentGeometry) const
103  {
104  Q_UNUSED( parentGeometry );
105 
106  return QPointF(
107  calculateXPosition(coo, parent->geometry()),
108  calculateYPosition(coo, parent->geometry())
109  );
110  }
111 
112  QRectF calculateRectangle(QGraphicsLayoutItem * item, QRectF geometry = QRectF()) const
113  {
114  if (geometry == QRectF()) {
115  geometry = parent->geometry();
116  }
117 
118  QRectF result;
119  if (!item || !items.contains(item)) {
120  return QRectF();
121  }
122 
123  result.setTopLeft(calculatePosition(items[item].first, geometry));
124 
125  if (items[item].second.xa != QREAL_INFINITY) {
126  result.setRight(calculateXPosition(items[item].second, geometry));
127  } else {
128  result.setWidth(item->preferredSize().width());
129  result.moveLeft(result.left() - items[item].second.xr * result.width());
130  }
131 
132  if (items[item].second.ya != QREAL_INFINITY) {
133  result.setBottom(calculateYPosition(items[item].second, geometry));
134  } else {
135  result.setHeight(item->preferredSize().height());
136  result.moveTop(result.top() - items[item].second.yr * result.height());
137  }
138  return result;
139  }
140 
141  void calculateSizeHint(QGraphicsLayoutItem * item = NULL) {
142  if (item == NULL) {
143  // Recalculate the sizeHint using all items
144  sizeHintCache[Qt::MinimumSize] = QSizeF();
145  sizeHintCache[Qt::MaximumSize] = QSizeF();
146  sizeHintCache[Qt::PreferredSize] = QSizeF();
147  foreach (QGraphicsLayoutItem * item, items.keys()) // krazy:exclude=foreach
148  {
149  if (item) {
150  calculateSizeHint(item);
151  }
152  }
153  } else {
154  // Calculate size hint for current item
155  const QRectF scaled = calculateRectangle(item, QRectF(0, 0, 1, 1));
156 
157  // qMin(..., 1.0) so that for autosized elements we don't get smaller
158  // size than the item's size itself. The sizeHint for NodeLayout can
159  // not do anything smarter concerning the sizeHint when there are
160  // autosized elements.
161 
162  QSizeF size;
163 
164  foreach (const Qt::SizeHint &which, sizeHintCache.keys()) // krazy:exclude=foreach
165  {
166  size = item->effectiveSizeHint(which);
167  size.scale(
168  1 / qMin(scaled.width(), qreal(1.0)),
169  1 / qMin(scaled.height(), qreal(1.0)),
170  Qt::IgnoreAspectRatio
171  );
172  sizeHintCache[which] = sizeHintCache[which].expandedTo(size);
173  }
174  }
175  }
176 
177 };
178 
179 NodeLayout::NodeLayout(QGraphicsLayoutItem * parent)
180  : QGraphicsLayout(parent), d(new Private(this))
181 {
182 }
183 
184 NodeLayout::~NodeLayout()
185 {
186  delete d;
187 }
188 
189 QSizeF NodeLayout::sizeHint(Qt::SizeHint which,
190  const QSizeF & constraint) const
191 {
192  Q_UNUSED(which);
193  Q_UNUSED(constraint);
194  QSizeF result;
195 
196  switch (which) {
197  case Qt::MaximumSize:
198  result = MAX_WIDGET_SIZE;
199  break;
200  default:
201  result = d->sizeHintCache[which];
202  }
203  if (constraint.isValid()) {
204  result = result.boundedTo(constraint);
205  }
206  return result;
207 }
208 
209 void NodeLayout::addItem(QGraphicsLayoutItem * item)
210 {
211  NodeLayout::addItem(item, NodeCoordinate());
212 }
213 
214 void NodeLayout::addItem(QGraphicsLayoutItem * item, NodeCoordinate topLeft, NodeCoordinate bottomRight)
215 {
216  if (!item) {
217  return;
218  }
219 
220  d->items[item] = QPair<NodeCoordinate, NodeCoordinate>(topLeft, bottomRight);
221  d->calculateSizeHint(item);
222  updateGeometry();
223 }
224 
225 void NodeLayout::addItem(QGraphicsLayoutItem * item, NodeCoordinate node, qreal xr, qreal yr)
226 {
227  if (!item) {
228  return;
229  }
230 
231  d->items[item] = QPair<NodeCoordinate, NodeCoordinate>(node,
232  NodeCoordinate::simple(xr, yr, NodeCoordinate::InnerRelative, NodeCoordinate::InnerRelative));
233  d->calculateSizeHint(item);
234  updateGeometry();
235 }
236 
237 int NodeLayout::count() const
238 {
239  return d->items.count();
240 }
241 
242 QGraphicsLayoutItem * NodeLayout::itemAt(int i) const
243 {
244  if (i >= d->items.count()) {
245  return 0;
246  }
247 
248  return d->items.keys()[i];
249 }
250 
251 void NodeLayout::removeAt(int i)
252 {
253  if (i >= d->items.count()) {
254  return;
255  }
256 
257  d->items.remove(itemAt(i));
258 }
259 
260 void NodeLayout::setGeometry(const QRectF & rect)
261 {
262  QGraphicsLayout::setGeometry(rect);
263  d->relayout();
264 }
265 
266 } // namespace Lancelot
267 
Lancelot::NodeLayout::sizeHint
L_Override QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Definition: NodeLayout.cpp:189
QSizeF::scale
void scale(qreal width, qreal height, Qt::AspectRatioMode mode)
Lancelot::NodeLayout::NodeCoordinate::ya
qreal ya
Definition: NodeLayout.h:70
Lancelot::NodeLayout::NodeCoordinate::xa
qreal xa
Definition: NodeLayout.h:69
Lancelot::NodeLayout::addItem
void addItem(QGraphicsLayoutItem *item)
Adds item at top-left corner, with automatic sizing (using sizeHint of the item)
Definition: NodeLayout.cpp:209
QGraphicsLayoutItem::geometry
QRectF geometry() const
QRectF::setRight
void setRight(qreal x)
QMap
Lancelot::NodeLayout::NodeLayout
NodeLayout(QGraphicsLayoutItem *parent=0)
Creates a new Lancelot::NodeLayout.
Definition: NodeLayout.cpp:179
QSizeF::isValid
bool isValid() const
Lancelot::NodeLayout::NodeCoordinate::yr
qreal yr
Definition: NodeLayout.h:70
QRectF::top
qreal top() const
MAX_WIDGET_SIZE
#define MAX_WIDGET_SIZE
Definition: lancelot.h:45
QRectF::left
qreal left() const
QRectF::setHeight
void setHeight(qreal height)
QPointF
Lancelot::NodeLayout::NodeCoordinate::CoordinateType
CoordinateType
Definition: NodeLayout.h:62
Lancelot::NodeLayout::NodeCoordinate::simple
static NodeCoordinate simple(qreal x, qreal y, CoordinateType xType=Relative, CoordinateType yType=Relative)
Definition: NodeLayout.cpp:36
QGraphicsLayoutItem::preferredSize
QSizeF preferredSize() const
Lancelot::NodeLayout::setGeometry
L_Override void setGeometry(const QRectF &rect)
Definition: NodeLayout.cpp:260
QGraphicsLayoutItem::effectiveSizeHint
QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint) const
NodeLayout.h
QRectF::moveLeft
void moveLeft(qreal x)
Global.h
QSizeF::boundedTo
QSizeF boundedTo(const QSizeF &otherSize) const
QGraphicsLayout::updateGeometry
virtual void updateGeometry()
QPair
Lancelot::NodeLayout::~NodeLayout
virtual ~NodeLayout()
Destroys this Lancelot::NodeLayout.
Definition: NodeLayout.cpp:184
Lancelot::NodeLayout::itemAt
L_Override QGraphicsLayoutItem * itemAt(int i) const
Definition: NodeLayout.cpp:242
Lancelot::NodeLayout::NodeCoordinate
Definition: NodeLayout.h:53
QRectF::setTopLeft
void setTopLeft(const QPointF &position)
Lancelot::NodeLayout::NodeCoordinate::xr
qreal xr
Definition: NodeLayout.h:69
QRectF::width
qreal width() const
Lancelot::NodeLayout::removeAt
L_Override void removeAt(int index)
Definition: NodeLayout.cpp:251
QSizeF
QRectF::setBottom
void setBottom(qreal y)
Lancelot::NodeLayout
Node layout has an advanced layouting mechanism.
Definition: NodeLayout.h:51
QRectF
QRectF::setWidth
void setWidth(qreal width)
lancelot.h
QGraphicsLayout
QRectF::height
qreal height() const
Lancelot::NodeLayout::NodeCoordinate::InnerRelative
Definition: NodeLayout.h:65
Lancelot::NodeLayout::NodeCoordinate::NodeCoordinate
NodeCoordinate(qreal xRelative=0, qreal yRelative=0, qreal xAbsolute=0, qreal yAbsolute=0)
Position is calculated: x = parentLeft + (xRelative * parentWidth) + xAbsolute y = parentTop + (yRela...
Definition: NodeLayout.cpp:33
QSizeF::height
qreal height() const
QRectF::moveTop
void moveTop(qreal y)
QREAL_INFINITY
#define QREAL_INFINITY
Definition: lancelot.h:47
QSizeF::width
qreal width() const
QGraphicsLayoutItem
QGraphicsLayoutItem::setGeometry
virtual void setGeometry(const QRectF &rect)
Lancelot::NodeLayout::count
L_Override int count() const
Definition: NodeLayout.cpp:237
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