1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtDeclarative module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "private/qdeclarativeanchors_p_p.h" |
43 | |
44 | #include "qdeclarativeitem.h" |
45 | #include "private/qdeclarativeitem_p.h" |
46 | |
47 | #include <qdeclarativeinfo.h> |
48 | |
49 | #include <QDebug> |
50 | |
51 | QT_BEGIN_NAMESPACE |
52 | |
53 | //TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)? |
54 | //TODO: support non-parent, non-sibling (need to find lowest common ancestor) |
55 | |
56 | static qreal hcenter(QGraphicsItem *i) |
57 | { |
58 | QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i); |
59 | |
60 | qreal width = item->width(); |
61 | int iw = width; |
62 | if (iw % 2) |
63 | return (width + 1) / 2; |
64 | else |
65 | return width / 2; |
66 | } |
67 | |
68 | static qreal vcenter(QGraphicsItem *i) |
69 | { |
70 | QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i); |
71 | |
72 | qreal height = item->height(); |
73 | int ih = height; |
74 | if (ih % 2) |
75 | return (height + 1) / 2; |
76 | else |
77 | return height / 2; |
78 | } |
79 | |
80 | //### const item? |
81 | //local position |
82 | static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine) |
83 | { |
84 | qreal ret = 0.0; |
85 | QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item); |
86 | switch(anchorLine) { |
87 | case QDeclarativeAnchorLine::Left: |
88 | ret = item->x(); |
89 | break; |
90 | case QDeclarativeAnchorLine::Right: |
91 | ret = item->x() + d->width(); |
92 | break; |
93 | case QDeclarativeAnchorLine::Top: |
94 | ret = item->y(); |
95 | break; |
96 | case QDeclarativeAnchorLine::Bottom: |
97 | ret = item->y() + d->height(); |
98 | break; |
99 | case QDeclarativeAnchorLine::HCenter: |
100 | ret = item->x() + hcenter(item); |
101 | break; |
102 | case QDeclarativeAnchorLine::VCenter: |
103 | ret = item->y() + vcenter(item); |
104 | break; |
105 | case QDeclarativeAnchorLine::Baseline: |
106 | if (d->isDeclarativeItem) |
107 | ret = item->y() + static_cast<QDeclarativeItem*>(item)->baselineOffset(); |
108 | break; |
109 | default: |
110 | break; |
111 | } |
112 | |
113 | return ret; |
114 | } |
115 | |
116 | //position when origin is 0,0 |
117 | static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine) |
118 | { |
119 | qreal ret = 0.0; |
120 | QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item); |
121 | switch(anchorLine) { |
122 | case QDeclarativeAnchorLine::Left: |
123 | ret = 0.0; |
124 | break; |
125 | case QDeclarativeAnchorLine::Right: |
126 | ret = d->width(); |
127 | break; |
128 | case QDeclarativeAnchorLine::Top: |
129 | ret = 0.0; |
130 | break; |
131 | case QDeclarativeAnchorLine::Bottom: |
132 | ret = d->height(); |
133 | break; |
134 | case QDeclarativeAnchorLine::HCenter: |
135 | ret = hcenter(item); |
136 | break; |
137 | case QDeclarativeAnchorLine::VCenter: |
138 | ret = vcenter(item); |
139 | break; |
140 | case QDeclarativeAnchorLine::Baseline: |
141 | if (d->isDeclarativeItem) |
142 | ret = static_cast<QDeclarativeItem*>(item)->baselineOffset(); |
143 | break; |
144 | default: |
145 | break; |
146 | } |
147 | |
148 | return ret; |
149 | } |
150 | |
151 | QDeclarativeAnchors::QDeclarativeAnchors(QObject *parent) |
152 | : QObject(*new QDeclarativeAnchorsPrivate(0), parent) |
153 | { |
154 | qFatal("QDeclarativeAnchors::QDeclarativeAnchors(QObject*) called" ); |
155 | } |
156 | |
157 | QDeclarativeAnchors::QDeclarativeAnchors(QGraphicsObject *item, QObject *parent) |
158 | : QObject(*new QDeclarativeAnchorsPrivate(item), parent) |
159 | { |
160 | } |
161 | |
162 | QDeclarativeAnchors::~QDeclarativeAnchors() |
163 | { |
164 | Q_D(QDeclarativeAnchors); |
165 | d->remDepend(d->fill); |
166 | d->remDepend(d->centerIn); |
167 | d->remDepend(d->left.item); |
168 | d->remDepend(d->right.item); |
169 | d->remDepend(d->top.item); |
170 | d->remDepend(d->bottom.item); |
171 | d->remDepend(d->vCenter.item); |
172 | d->remDepend(d->hCenter.item); |
173 | d->remDepend(d->baseline.item); |
174 | } |
175 | |
176 | void QDeclarativeAnchorsPrivate::fillChanged() |
177 | { |
178 | Q_Q(QDeclarativeAnchors); |
179 | if (!fill || !isItemComplete()) |
180 | return; |
181 | |
182 | if (updatingFill < 2) { |
183 | ++updatingFill; |
184 | |
185 | qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin; |
186 | |
187 | if (fill == item->parentItem()) { //child-parent |
188 | setItemPos(QPointF(horizontalMargin, topMargin)); |
189 | } else if (fill->parentItem() == item->parentItem()) { //siblings |
190 | setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin)); |
191 | } |
192 | QGraphicsItemPrivate *fillPrivate = QGraphicsItemPrivate::get(fill); |
193 | setItemSize(QSizeF(fillPrivate->width()-leftMargin-rightMargin, fillPrivate->height()-topMargin-bottomMargin)); |
194 | |
195 | --updatingFill; |
196 | } else { |
197 | // ### Make this certain :) |
198 | qmlInfo(item) << QDeclarativeAnchors::tr("Possible anchor loop detected on fill." ); |
199 | } |
200 | |
201 | } |
202 | |
203 | void QDeclarativeAnchorsPrivate::centerInChanged() |
204 | { |
205 | Q_Q(QDeclarativeAnchors); |
206 | if (!centerIn || fill || !isItemComplete()) |
207 | return; |
208 | |
209 | if (updatingCenterIn < 2) { |
210 | ++updatingCenterIn; |
211 | |
212 | qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset; |
213 | if (centerIn == item->parentItem()) { |
214 | QPointF p(hcenter(item->parentItem()) - hcenter(item) + effectiveHCenterOffset, |
215 | vcenter(item->parentItem()) - vcenter(item) + vCenterOffset); |
216 | setItemPos(p); |
217 | |
218 | } else if (centerIn->parentItem() == item->parentItem()) { |
219 | QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset, |
220 | centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset); |
221 | setItemPos(p); |
222 | } |
223 | |
224 | --updatingCenterIn; |
225 | } else { |
226 | // ### Make this certain :) |
227 | qmlInfo(item) << QDeclarativeAnchors::tr("Possible anchor loop detected on centerIn." ); |
228 | } |
229 | } |
230 | |
231 | void QDeclarativeAnchorsPrivate::clearItem(QGraphicsObject *item) |
232 | { |
233 | if (!item) |
234 | return; |
235 | if (fill == item) |
236 | fill = 0; |
237 | if (centerIn == item) |
238 | centerIn = 0; |
239 | if (left.item == item) { |
240 | left.item = 0; |
241 | usedAnchors &= ~QDeclarativeAnchors::LeftAnchor; |
242 | } |
243 | if (right.item == item) { |
244 | right.item = 0; |
245 | usedAnchors &= ~QDeclarativeAnchors::RightAnchor; |
246 | } |
247 | if (top.item == item) { |
248 | top.item = 0; |
249 | usedAnchors &= ~QDeclarativeAnchors::TopAnchor; |
250 | } |
251 | if (bottom.item == item) { |
252 | bottom.item = 0; |
253 | usedAnchors &= ~QDeclarativeAnchors::BottomAnchor; |
254 | } |
255 | if (vCenter.item == item) { |
256 | vCenter.item = 0; |
257 | usedAnchors &= ~QDeclarativeAnchors::VCenterAnchor; |
258 | } |
259 | if (hCenter.item == item) { |
260 | hCenter.item = 0; |
261 | usedAnchors &= ~QDeclarativeAnchors::HCenterAnchor; |
262 | } |
263 | if (baseline.item == item) { |
264 | baseline.item = 0; |
265 | usedAnchors &= ~QDeclarativeAnchors::BaselineAnchor; |
266 | } |
267 | } |
268 | |
269 | void QDeclarativeAnchorsPrivate::addDepend(QGraphicsObject *item) |
270 | { |
271 | if (!item) |
272 | return; |
273 | QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item); |
274 | if (itemPrivate->isDeclarativeItem) { |
275 | QDeclarativeItemPrivate *p = |
276 | static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item)); |
277 | p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); |
278 | } else if(itemPrivate->isWidget) { |
279 | Q_Q(QDeclarativeAnchors); |
280 | QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item); |
281 | QObject::connect(widget, SIGNAL(destroyed(QObject*)), q, SLOT(_q_widgetDestroyed(QObject*))); |
282 | QObject::connect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged())); |
283 | } |
284 | } |
285 | |
286 | void QDeclarativeAnchorsPrivate::remDepend(QGraphicsObject *item) |
287 | { |
288 | if (!item) |
289 | return; |
290 | QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item); |
291 | if (itemPrivate->isDeclarativeItem) { |
292 | QDeclarativeItemPrivate *p = |
293 | static_cast<QDeclarativeItemPrivate *>(itemPrivate); |
294 | p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry); |
295 | } else if(itemPrivate->isWidget) { |
296 | Q_Q(QDeclarativeAnchors); |
297 | QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item); |
298 | QObject::disconnect(widget, SIGNAL(destroyed(QObject*)), q, SLOT(_q_widgetDestroyed(QObject*))); |
299 | QObject::disconnect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged())); |
300 | } |
301 | } |
302 | |
303 | bool QDeclarativeAnchorsPrivate::isItemComplete() const |
304 | { |
305 | return componentComplete; |
306 | } |
307 | |
308 | void QDeclarativeAnchors::classBegin() |
309 | { |
310 | Q_D(QDeclarativeAnchors); |
311 | d->componentComplete = false; |
312 | } |
313 | |
314 | void QDeclarativeAnchors::componentComplete() |
315 | { |
316 | Q_D(QDeclarativeAnchors); |
317 | d->componentComplete = true; |
318 | } |
319 | |
320 | bool QDeclarativeAnchors::mirrored() |
321 | { |
322 | Q_D(QDeclarativeAnchors); |
323 | QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(d->item); |
324 | return itemPrivate->isDeclarativeItem ? static_cast<QDeclarativeItemPrivate *>(itemPrivate)->effectiveLayoutMirror : false; |
325 | } |
326 | |
327 | void QDeclarativeAnchorsPrivate::setItemHeight(qreal v) |
328 | { |
329 | updatingMe = true; |
330 | QGraphicsItemPrivate::get(item)->setHeight(v); |
331 | updatingMe = false; |
332 | } |
333 | |
334 | void QDeclarativeAnchorsPrivate::setItemWidth(qreal v) |
335 | { |
336 | updatingMe = true; |
337 | QGraphicsItemPrivate::get(item)->setWidth(v); |
338 | updatingMe = false; |
339 | } |
340 | |
341 | void QDeclarativeAnchorsPrivate::setItemX(qreal v) |
342 | { |
343 | updatingMe = true; |
344 | item->setX(v); |
345 | updatingMe = false; |
346 | } |
347 | |
348 | void QDeclarativeAnchorsPrivate::setItemY(qreal v) |
349 | { |
350 | updatingMe = true; |
351 | item->setY(v); |
352 | updatingMe = false; |
353 | } |
354 | |
355 | void QDeclarativeAnchorsPrivate::setItemPos(const QPointF &v) |
356 | { |
357 | updatingMe = true; |
358 | item->setPos(v); |
359 | updatingMe = false; |
360 | } |
361 | |
362 | void QDeclarativeAnchorsPrivate::setItemSize(const QSizeF &v) |
363 | { |
364 | updatingMe = true; |
365 | if(QGraphicsItemPrivate::get(item)->isWidget) |
366 | static_cast<QGraphicsWidget *>(item)->resize(v); |
367 | else if (QGraphicsItemPrivate::get(item)->isDeclarativeItem) |
368 | static_cast<QDeclarativeItem *>(item)->setSize(v); |
369 | updatingMe = false; |
370 | } |
371 | |
372 | void QDeclarativeAnchorsPrivate::updateMe() |
373 | { |
374 | if (updatingMe) { |
375 | updatingMe = false; |
376 | return; |
377 | } |
378 | |
379 | fillChanged(); |
380 | centerInChanged(); |
381 | updateHorizontalAnchors(); |
382 | updateVerticalAnchors(); |
383 | } |
384 | |
385 | void QDeclarativeAnchorsPrivate::updateOnComplete() |
386 | { |
387 | fillChanged(); |
388 | centerInChanged(); |
389 | updateHorizontalAnchors(); |
390 | updateVerticalAnchors(); |
391 | } |
392 | |
393 | void QDeclarativeAnchorsPrivate::_q_widgetDestroyed(QObject *obj) |
394 | { |
395 | clearItem(qobject_cast<QGraphicsObject*>(obj)); |
396 | } |
397 | |
398 | void QDeclarativeAnchorsPrivate::_q_widgetGeometryChanged() |
399 | { |
400 | fillChanged(); |
401 | centerInChanged(); |
402 | updateHorizontalAnchors(); |
403 | updateVerticalAnchors(); |
404 | } |
405 | |
406 | void QDeclarativeAnchorsPrivate::itemGeometryChanged(QDeclarativeItem *, const QRectF &newG, const QRectF &oldG) |
407 | { |
408 | fillChanged(); |
409 | centerInChanged(); |
410 | if (newG.x() != oldG.x() || newG.width() != oldG.width()) |
411 | updateHorizontalAnchors(); |
412 | if (newG.y() != oldG.y() || newG.height() != oldG.height()) |
413 | updateVerticalAnchors(); |
414 | } |
415 | |
416 | QGraphicsObject *QDeclarativeAnchors::fill() const |
417 | { |
418 | Q_D(const QDeclarativeAnchors); |
419 | return d->fill; |
420 | } |
421 | |
422 | void QDeclarativeAnchors::setFill(QGraphicsObject *f) |
423 | { |
424 | Q_D(QDeclarativeAnchors); |
425 | if (d->fill == f) |
426 | return; |
427 | |
428 | if (!f) { |
429 | d->remDepend(d->fill); |
430 | d->fill = f; |
431 | emit fillChanged(); |
432 | return; |
433 | } |
434 | if (f != d->item->parentItem() && f->parentItem() != d->item->parentItem()){ |
435 | qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling." ); |
436 | return; |
437 | } |
438 | d->remDepend(d->fill); |
439 | d->fill = f; |
440 | d->addDepend(d->fill); |
441 | emit fillChanged(); |
442 | d->fillChanged(); |
443 | } |
444 | |
445 | void QDeclarativeAnchors::resetFill() |
446 | { |
447 | setFill(0); |
448 | } |
449 | |
450 | QGraphicsObject *QDeclarativeAnchors::centerIn() const |
451 | { |
452 | Q_D(const QDeclarativeAnchors); |
453 | return d->centerIn; |
454 | } |
455 | |
456 | void QDeclarativeAnchors::setCenterIn(QGraphicsObject* c) |
457 | { |
458 | Q_D(QDeclarativeAnchors); |
459 | if (d->centerIn == c) |
460 | return; |
461 | |
462 | if (!c) { |
463 | d->remDepend(d->centerIn); |
464 | d->centerIn = c; |
465 | emit centerInChanged(); |
466 | return; |
467 | } |
468 | if (c != d->item->parentItem() && c->parentItem() != d->item->parentItem()){ |
469 | qmlInfo(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling." ); |
470 | return; |
471 | } |
472 | |
473 | d->remDepend(d->centerIn); |
474 | d->centerIn = c; |
475 | d->addDepend(d->centerIn); |
476 | emit centerInChanged(); |
477 | d->centerInChanged(); |
478 | } |
479 | |
480 | void QDeclarativeAnchors::resetCenterIn() |
481 | { |
482 | setCenterIn(0); |
483 | } |
484 | |
485 | bool QDeclarativeAnchorsPrivate::calcStretch(const QDeclarativeAnchorLine &edge1, |
486 | const QDeclarativeAnchorLine &edge2, |
487 | qreal offset1, |
488 | qreal offset2, |
489 | QDeclarativeAnchorLine::AnchorLine line, |
490 | qreal &stretch) |
491 | { |
492 | bool edge1IsParent = (edge1.item == item->parentItem()); |
493 | bool edge2IsParent = (edge2.item == item->parentItem()); |
494 | bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem()); |
495 | bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem()); |
496 | |
497 | bool invalid = false; |
498 | if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) { |
499 | stretch = (position(edge2.item, edge2.anchorLine) + offset2) |
500 | - (position(edge1.item, edge1.anchorLine) + offset1); |
501 | } else if (edge2IsParent && edge1IsSibling) { |
502 | stretch = (position(edge2.item, edge2.anchorLine) + offset2) |
503 | - (position(item->parentObject(), line) |
504 | + position(edge1.item, edge1.anchorLine) + offset1); |
505 | } else if (edge2IsSibling && edge1IsParent) { |
506 | stretch = (position(item->parentObject(), line) + position(edge2.item, edge2.anchorLine) + offset2) |
507 | - (position(edge1.item, edge1.anchorLine) + offset1); |
508 | } else |
509 | invalid = true; |
510 | |
511 | return invalid; |
512 | } |
513 | |
514 | void QDeclarativeAnchorsPrivate::updateVerticalAnchors() |
515 | { |
516 | if (fill || centerIn || !isItemComplete()) |
517 | return; |
518 | |
519 | if (updatingVerticalAnchor < 2) { |
520 | ++updatingVerticalAnchor; |
521 | QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); |
522 | if (usedAnchors & QDeclarativeAnchors::TopAnchor) { |
523 | //Handle stretching |
524 | bool invalid = true; |
525 | qreal height = 0.0; |
526 | if (usedAnchors & QDeclarativeAnchors::BottomAnchor) { |
527 | invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QDeclarativeAnchorLine::Top, height); |
528 | } else if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) { |
529 | invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QDeclarativeAnchorLine::Top, height); |
530 | height *= 2; |
531 | } |
532 | if (!invalid) |
533 | setItemHeight(height); |
534 | |
535 | //Handle top |
536 | if (top.item == item->parentItem()) { |
537 | setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin); |
538 | } else if (top.item->parentItem() == item->parentItem()) { |
539 | setItemY(position(top.item, top.anchorLine) + topMargin); |
540 | } |
541 | } else if (usedAnchors & QDeclarativeAnchors::BottomAnchor) { |
542 | //Handle stretching (top + bottom case is handled above) |
543 | if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) { |
544 | qreal height = 0.0; |
545 | bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin, |
546 | QDeclarativeAnchorLine::Top, height); |
547 | if (!invalid) |
548 | setItemHeight(height*2); |
549 | } |
550 | |
551 | //Handle bottom |
552 | if (bottom.item == item->parentItem()) { |
553 | setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin); |
554 | } else if (bottom.item->parentItem() == item->parentItem()) { |
555 | setItemY(position(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin); |
556 | } |
557 | } else if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) { |
558 | //(stetching handled above) |
559 | |
560 | //Handle vCenter |
561 | if (vCenter.item == item->parentItem()) { |
562 | setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine) |
563 | - vcenter(item) + vCenterOffset); |
564 | } else if (vCenter.item->parentItem() == item->parentItem()) { |
565 | setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset); |
566 | } |
567 | } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor) { |
568 | //Handle baseline |
569 | if (baseline.item == item->parentItem()) { |
570 | if (itemPrivate->isDeclarativeItem) |
571 | setItemY(adjustedPosition(baseline.item, baseline.anchorLine) |
572 | - static_cast<QDeclarativeItem *>(item)->baselineOffset() + baselineOffset); |
573 | } else if (baseline.item->parentItem() == item->parentItem()) { |
574 | if (itemPrivate->isDeclarativeItem) |
575 | setItemY(position(baseline.item, baseline.anchorLine) |
576 | - static_cast<QDeclarativeItem *>(item)->baselineOffset() + baselineOffset); |
577 | } |
578 | } |
579 | --updatingVerticalAnchor; |
580 | } else { |
581 | // ### Make this certain :) |
582 | qmlInfo(item) << QDeclarativeAnchors::tr("Possible anchor loop detected on vertical anchor." ); |
583 | } |
584 | } |
585 | |
586 | inline QDeclarativeAnchorLine::AnchorLine reverseAnchorLine(QDeclarativeAnchorLine::AnchorLine anchorLine) { |
587 | if (anchorLine == QDeclarativeAnchorLine::Left) { |
588 | return QDeclarativeAnchorLine::Right; |
589 | } else if (anchorLine == QDeclarativeAnchorLine::Right) { |
590 | return QDeclarativeAnchorLine::Left; |
591 | } else { |
592 | return anchorLine; |
593 | } |
594 | } |
595 | |
596 | void QDeclarativeAnchorsPrivate::updateHorizontalAnchors() |
597 | { |
598 | Q_Q(QDeclarativeAnchors); |
599 | if (fill || centerIn || !isItemComplete()) |
600 | return; |
601 | |
602 | if (updatingHorizontalAnchor < 3) { |
603 | ++updatingHorizontalAnchor; |
604 | qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset; |
605 | QDeclarativeAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter; |
606 | QDeclarativeAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor; |
607 | if (q->mirrored()) { |
608 | effectiveLeftAnchor = QDeclarativeAnchors::RightAnchor; |
609 | effectiveRightAnchor = QDeclarativeAnchors::LeftAnchor; |
610 | effectiveLeft.item = right.item; |
611 | effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine); |
612 | effectiveRight.item = left.item; |
613 | effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine); |
614 | effectiveHorizontalCenter.item = hCenter.item; |
615 | effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine); |
616 | effectiveLeftMargin = rightMargin; |
617 | effectiveRightMargin = leftMargin; |
618 | effectiveHorizontalCenterOffset = -hCenterOffset; |
619 | } else { |
620 | effectiveLeftAnchor = QDeclarativeAnchors::LeftAnchor; |
621 | effectiveRightAnchor = QDeclarativeAnchors::RightAnchor; |
622 | effectiveLeft = left; |
623 | effectiveRight = right; |
624 | effectiveHorizontalCenter = hCenter; |
625 | effectiveLeftMargin = leftMargin; |
626 | effectiveRightMargin = rightMargin; |
627 | effectiveHorizontalCenterOffset = hCenterOffset; |
628 | } |
629 | |
630 | QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); |
631 | if (usedAnchors & effectiveLeftAnchor) { |
632 | //Handle stretching |
633 | bool invalid = true; |
634 | qreal width = 0.0; |
635 | if (usedAnchors & effectiveRightAnchor) { |
636 | invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QDeclarativeAnchorLine::Left, width); |
637 | } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) { |
638 | invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QDeclarativeAnchorLine::Left, width); |
639 | width *= 2; |
640 | } |
641 | if (!invalid) |
642 | setItemWidth(width); |
643 | |
644 | //Handle left |
645 | if (effectiveLeft.item == item->parentItem()) { |
646 | setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin); |
647 | } else if (effectiveLeft.item->parentItem() == item->parentItem()) { |
648 | setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin); |
649 | } |
650 | } else if (usedAnchors & effectiveRightAnchor) { |
651 | //Handle stretching (left + right case is handled in updateLeftAnchor) |
652 | if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) { |
653 | qreal width = 0.0; |
654 | bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin, |
655 | QDeclarativeAnchorLine::Left, width); |
656 | if (!invalid) |
657 | setItemWidth(width*2); |
658 | } |
659 | |
660 | //Handle right |
661 | if (effectiveRight.item == item->parentItem()) { |
662 | setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - itemPrivate->width() - effectiveRightMargin); |
663 | } else if (effectiveRight.item->parentItem() == item->parentItem()) { |
664 | setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - itemPrivate->width() - effectiveRightMargin); |
665 | } |
666 | } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) { |
667 | //Handle hCenter |
668 | if (effectiveHorizontalCenter.item == item->parentItem()) { |
669 | setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset); |
670 | } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) { |
671 | setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset); |
672 | } |
673 | } |
674 | --updatingHorizontalAnchor; |
675 | } else { |
676 | // ### Make this certain :) |
677 | qmlInfo(item) << QDeclarativeAnchors::tr("Possible anchor loop detected on horizontal anchor." ); |
678 | } |
679 | } |
680 | |
681 | QDeclarativeAnchorLine QDeclarativeAnchors::top() const |
682 | { |
683 | Q_D(const QDeclarativeAnchors); |
684 | return d->top; |
685 | } |
686 | |
687 | void QDeclarativeAnchors::setTop(const QDeclarativeAnchorLine &edge) |
688 | { |
689 | Q_D(QDeclarativeAnchors); |
690 | if (!d->checkVAnchorValid(edge) || d->top == edge) |
691 | return; |
692 | |
693 | d->usedAnchors |= TopAnchor; |
694 | |
695 | if (!d->checkVValid()) { |
696 | d->usedAnchors &= ~TopAnchor; |
697 | return; |
698 | } |
699 | |
700 | d->remDepend(d->top.item); |
701 | d->top = edge; |
702 | d->addDepend(d->top.item); |
703 | emit topChanged(); |
704 | d->updateVerticalAnchors(); |
705 | } |
706 | |
707 | void QDeclarativeAnchors::resetTop() |
708 | { |
709 | Q_D(QDeclarativeAnchors); |
710 | d->usedAnchors &= ~TopAnchor; |
711 | d->remDepend(d->top.item); |
712 | d->top = QDeclarativeAnchorLine(); |
713 | emit topChanged(); |
714 | d->updateVerticalAnchors(); |
715 | } |
716 | |
717 | QDeclarativeAnchorLine QDeclarativeAnchors::bottom() const |
718 | { |
719 | Q_D(const QDeclarativeAnchors); |
720 | return d->bottom; |
721 | } |
722 | |
723 | void QDeclarativeAnchors::setBottom(const QDeclarativeAnchorLine &edge) |
724 | { |
725 | Q_D(QDeclarativeAnchors); |
726 | if (!d->checkVAnchorValid(edge) || d->bottom == edge) |
727 | return; |
728 | |
729 | d->usedAnchors |= BottomAnchor; |
730 | |
731 | if (!d->checkVValid()) { |
732 | d->usedAnchors &= ~BottomAnchor; |
733 | return; |
734 | } |
735 | |
736 | d->remDepend(d->bottom.item); |
737 | d->bottom = edge; |
738 | d->addDepend(d->bottom.item); |
739 | emit bottomChanged(); |
740 | d->updateVerticalAnchors(); |
741 | } |
742 | |
743 | void QDeclarativeAnchors::resetBottom() |
744 | { |
745 | Q_D(QDeclarativeAnchors); |
746 | d->usedAnchors &= ~BottomAnchor; |
747 | d->remDepend(d->bottom.item); |
748 | d->bottom = QDeclarativeAnchorLine(); |
749 | emit bottomChanged(); |
750 | d->updateVerticalAnchors(); |
751 | } |
752 | |
753 | QDeclarativeAnchorLine QDeclarativeAnchors::verticalCenter() const |
754 | { |
755 | Q_D(const QDeclarativeAnchors); |
756 | return d->vCenter; |
757 | } |
758 | |
759 | void QDeclarativeAnchors::setVerticalCenter(const QDeclarativeAnchorLine &edge) |
760 | { |
761 | Q_D(QDeclarativeAnchors); |
762 | if (!d->checkVAnchorValid(edge) || d->vCenter == edge) |
763 | return; |
764 | |
765 | d->usedAnchors |= VCenterAnchor; |
766 | |
767 | if (!d->checkVValid()) { |
768 | d->usedAnchors &= ~VCenterAnchor; |
769 | return; |
770 | } |
771 | |
772 | d->remDepend(d->vCenter.item); |
773 | d->vCenter = edge; |
774 | d->addDepend(d->vCenter.item); |
775 | emit verticalCenterChanged(); |
776 | d->updateVerticalAnchors(); |
777 | } |
778 | |
779 | void QDeclarativeAnchors::resetVerticalCenter() |
780 | { |
781 | Q_D(QDeclarativeAnchors); |
782 | d->usedAnchors &= ~VCenterAnchor; |
783 | d->remDepend(d->vCenter.item); |
784 | d->vCenter = QDeclarativeAnchorLine(); |
785 | emit verticalCenterChanged(); |
786 | d->updateVerticalAnchors(); |
787 | } |
788 | |
789 | QDeclarativeAnchorLine QDeclarativeAnchors::baseline() const |
790 | { |
791 | Q_D(const QDeclarativeAnchors); |
792 | return d->baseline; |
793 | } |
794 | |
795 | void QDeclarativeAnchors::setBaseline(const QDeclarativeAnchorLine &edge) |
796 | { |
797 | Q_D(QDeclarativeAnchors); |
798 | if (!d->checkVAnchorValid(edge) || d->baseline == edge) |
799 | return; |
800 | |
801 | d->usedAnchors |= BaselineAnchor; |
802 | |
803 | if (!d->checkVValid()) { |
804 | d->usedAnchors &= ~BaselineAnchor; |
805 | return; |
806 | } |
807 | |
808 | d->remDepend(d->baseline.item); |
809 | d->baseline = edge; |
810 | d->addDepend(d->baseline.item); |
811 | emit baselineChanged(); |
812 | d->updateVerticalAnchors(); |
813 | } |
814 | |
815 | void QDeclarativeAnchors::resetBaseline() |
816 | { |
817 | Q_D(QDeclarativeAnchors); |
818 | d->usedAnchors &= ~BaselineAnchor; |
819 | d->remDepend(d->baseline.item); |
820 | d->baseline = QDeclarativeAnchorLine(); |
821 | emit baselineChanged(); |
822 | d->updateVerticalAnchors(); |
823 | } |
824 | |
825 | QDeclarativeAnchorLine QDeclarativeAnchors::left() const |
826 | { |
827 | Q_D(const QDeclarativeAnchors); |
828 | return d->left; |
829 | } |
830 | |
831 | void QDeclarativeAnchors::setLeft(const QDeclarativeAnchorLine &edge) |
832 | { |
833 | Q_D(QDeclarativeAnchors); |
834 | if (!d->checkHAnchorValid(edge) || d->left == edge) |
835 | return; |
836 | |
837 | d->usedAnchors |= LeftAnchor; |
838 | |
839 | if (!d->checkHValid()) { |
840 | d->usedAnchors &= ~LeftAnchor; |
841 | return; |
842 | } |
843 | |
844 | d->remDepend(d->left.item); |
845 | d->left = edge; |
846 | d->addDepend(d->left.item); |
847 | emit leftChanged(); |
848 | d->updateHorizontalAnchors(); |
849 | } |
850 | |
851 | void QDeclarativeAnchors::resetLeft() |
852 | { |
853 | Q_D(QDeclarativeAnchors); |
854 | d->usedAnchors &= ~LeftAnchor; |
855 | d->remDepend(d->left.item); |
856 | d->left = QDeclarativeAnchorLine(); |
857 | emit leftChanged(); |
858 | d->updateHorizontalAnchors(); |
859 | } |
860 | |
861 | QDeclarativeAnchorLine QDeclarativeAnchors::right() const |
862 | { |
863 | Q_D(const QDeclarativeAnchors); |
864 | return d->right; |
865 | } |
866 | |
867 | void QDeclarativeAnchors::setRight(const QDeclarativeAnchorLine &edge) |
868 | { |
869 | Q_D(QDeclarativeAnchors); |
870 | if (!d->checkHAnchorValid(edge) || d->right == edge) |
871 | return; |
872 | |
873 | d->usedAnchors |= RightAnchor; |
874 | |
875 | if (!d->checkHValid()) { |
876 | d->usedAnchors &= ~RightAnchor; |
877 | return; |
878 | } |
879 | |
880 | d->remDepend(d->right.item); |
881 | d->right = edge; |
882 | d->addDepend(d->right.item); |
883 | emit rightChanged(); |
884 | d->updateHorizontalAnchors(); |
885 | } |
886 | |
887 | void QDeclarativeAnchors::resetRight() |
888 | { |
889 | Q_D(QDeclarativeAnchors); |
890 | d->usedAnchors &= ~RightAnchor; |
891 | d->remDepend(d->right.item); |
892 | d->right = QDeclarativeAnchorLine(); |
893 | emit rightChanged(); |
894 | d->updateHorizontalAnchors(); |
895 | } |
896 | |
897 | QDeclarativeAnchorLine QDeclarativeAnchors::horizontalCenter() const |
898 | { |
899 | Q_D(const QDeclarativeAnchors); |
900 | return d->hCenter; |
901 | } |
902 | |
903 | void QDeclarativeAnchors::setHorizontalCenter(const QDeclarativeAnchorLine &edge) |
904 | { |
905 | Q_D(QDeclarativeAnchors); |
906 | if (!d->checkHAnchorValid(edge) || d->hCenter == edge) |
907 | return; |
908 | |
909 | d->usedAnchors |= HCenterAnchor; |
910 | |
911 | if (!d->checkHValid()) { |
912 | d->usedAnchors &= ~HCenterAnchor; |
913 | return; |
914 | } |
915 | |
916 | d->remDepend(d->hCenter.item); |
917 | d->hCenter = edge; |
918 | d->addDepend(d->hCenter.item); |
919 | emit horizontalCenterChanged(); |
920 | d->updateHorizontalAnchors(); |
921 | } |
922 | |
923 | void QDeclarativeAnchors::resetHorizontalCenter() |
924 | { |
925 | Q_D(QDeclarativeAnchors); |
926 | d->usedAnchors &= ~HCenterAnchor; |
927 | d->remDepend(d->hCenter.item); |
928 | d->hCenter = QDeclarativeAnchorLine(); |
929 | emit horizontalCenterChanged(); |
930 | d->updateHorizontalAnchors(); |
931 | } |
932 | |
933 | qreal QDeclarativeAnchors::leftMargin() const |
934 | { |
935 | Q_D(const QDeclarativeAnchors); |
936 | return d->leftMargin; |
937 | } |
938 | |
939 | void QDeclarativeAnchors::setLeftMargin(qreal offset) |
940 | { |
941 | Q_D(QDeclarativeAnchors); |
942 | if (d->leftMargin == offset) |
943 | return; |
944 | d->leftMargin = offset; |
945 | if(d->fill) |
946 | d->fillChanged(); |
947 | else |
948 | d->updateHorizontalAnchors(); |
949 | emit leftMarginChanged(); |
950 | } |
951 | |
952 | qreal QDeclarativeAnchors::rightMargin() const |
953 | { |
954 | Q_D(const QDeclarativeAnchors); |
955 | return d->rightMargin; |
956 | } |
957 | |
958 | void QDeclarativeAnchors::setRightMargin(qreal offset) |
959 | { |
960 | Q_D(QDeclarativeAnchors); |
961 | if (d->rightMargin == offset) |
962 | return; |
963 | d->rightMargin = offset; |
964 | if(d->fill) |
965 | d->fillChanged(); |
966 | else |
967 | d->updateHorizontalAnchors(); |
968 | emit rightMarginChanged(); |
969 | } |
970 | |
971 | qreal QDeclarativeAnchors::margins() const |
972 | { |
973 | Q_D(const QDeclarativeAnchors); |
974 | return d->margins; |
975 | } |
976 | |
977 | void QDeclarativeAnchors::setMargins(qreal offset) |
978 | { |
979 | Q_D(QDeclarativeAnchors); |
980 | if (d->margins == offset) |
981 | return; |
982 | //###Is it significantly faster to set them directly so we can call fillChanged only once? |
983 | if(!d->rightMargin || d->rightMargin == d->margins) |
984 | setRightMargin(offset); |
985 | if(!d->leftMargin || d->leftMargin == d->margins) |
986 | setLeftMargin(offset); |
987 | if(!d->topMargin || d->topMargin == d->margins) |
988 | setTopMargin(offset); |
989 | if(!d->bottomMargin || d->bottomMargin == d->margins) |
990 | setBottomMargin(offset); |
991 | d->margins = offset; |
992 | emit marginsChanged(); |
993 | |
994 | } |
995 | |
996 | qreal QDeclarativeAnchors::horizontalCenterOffset() const |
997 | { |
998 | Q_D(const QDeclarativeAnchors); |
999 | return d->hCenterOffset; |
1000 | } |
1001 | |
1002 | void QDeclarativeAnchors::setHorizontalCenterOffset(qreal offset) |
1003 | { |
1004 | Q_D(QDeclarativeAnchors); |
1005 | if (d->hCenterOffset == offset) |
1006 | return; |
1007 | d->hCenterOffset = offset; |
1008 | if(d->centerIn) |
1009 | d->centerInChanged(); |
1010 | else |
1011 | d->updateHorizontalAnchors(); |
1012 | emit horizontalCenterOffsetChanged(); |
1013 | } |
1014 | |
1015 | qreal QDeclarativeAnchors::topMargin() const |
1016 | { |
1017 | Q_D(const QDeclarativeAnchors); |
1018 | return d->topMargin; |
1019 | } |
1020 | |
1021 | void QDeclarativeAnchors::setTopMargin(qreal offset) |
1022 | { |
1023 | Q_D(QDeclarativeAnchors); |
1024 | if (d->topMargin == offset) |
1025 | return; |
1026 | d->topMargin = offset; |
1027 | if(d->fill) |
1028 | d->fillChanged(); |
1029 | else |
1030 | d->updateVerticalAnchors(); |
1031 | emit topMarginChanged(); |
1032 | } |
1033 | |
1034 | qreal QDeclarativeAnchors::bottomMargin() const |
1035 | { |
1036 | Q_D(const QDeclarativeAnchors); |
1037 | return d->bottomMargin; |
1038 | } |
1039 | |
1040 | void QDeclarativeAnchors::setBottomMargin(qreal offset) |
1041 | { |
1042 | Q_D(QDeclarativeAnchors); |
1043 | if (d->bottomMargin == offset) |
1044 | return; |
1045 | d->bottomMargin = offset; |
1046 | if(d->fill) |
1047 | d->fillChanged(); |
1048 | else |
1049 | d->updateVerticalAnchors(); |
1050 | emit bottomMarginChanged(); |
1051 | } |
1052 | |
1053 | qreal QDeclarativeAnchors::verticalCenterOffset() const |
1054 | { |
1055 | Q_D(const QDeclarativeAnchors); |
1056 | return d->vCenterOffset; |
1057 | } |
1058 | |
1059 | void QDeclarativeAnchors::setVerticalCenterOffset(qreal offset) |
1060 | { |
1061 | Q_D(QDeclarativeAnchors); |
1062 | if (d->vCenterOffset == offset) |
1063 | return; |
1064 | d->vCenterOffset = offset; |
1065 | if(d->centerIn) |
1066 | d->centerInChanged(); |
1067 | else |
1068 | d->updateVerticalAnchors(); |
1069 | emit verticalCenterOffsetChanged(); |
1070 | } |
1071 | |
1072 | qreal QDeclarativeAnchors::baselineOffset() const |
1073 | { |
1074 | Q_D(const QDeclarativeAnchors); |
1075 | return d->baselineOffset; |
1076 | } |
1077 | |
1078 | void QDeclarativeAnchors::setBaselineOffset(qreal offset) |
1079 | { |
1080 | Q_D(QDeclarativeAnchors); |
1081 | if (d->baselineOffset == offset) |
1082 | return; |
1083 | d->baselineOffset = offset; |
1084 | d->updateVerticalAnchors(); |
1085 | emit baselineOffsetChanged(); |
1086 | } |
1087 | |
1088 | QDeclarativeAnchors::Anchors QDeclarativeAnchors::usedAnchors() const |
1089 | { |
1090 | Q_D(const QDeclarativeAnchors); |
1091 | return d->usedAnchors; |
1092 | } |
1093 | |
1094 | bool QDeclarativeAnchorsPrivate::checkHValid() const |
1095 | { |
1096 | if (usedAnchors & QDeclarativeAnchors::LeftAnchor && |
1097 | usedAnchors & QDeclarativeAnchors::RightAnchor && |
1098 | usedAnchors & QDeclarativeAnchors::HCenterAnchor) { |
1099 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot specify left, right, and hcenter anchors." ); |
1100 | return false; |
1101 | } |
1102 | |
1103 | return true; |
1104 | } |
1105 | |
1106 | bool QDeclarativeAnchorsPrivate::checkHAnchorValid(QDeclarativeAnchorLine anchor) const |
1107 | { |
1108 | if (!anchor.item) { |
1109 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to a null item." ); |
1110 | return false; |
1111 | } else if (anchor.anchorLine & QDeclarativeAnchorLine::Vertical_Mask) { |
1112 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor a horizontal edge to a vertical edge." ); |
1113 | return false; |
1114 | } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){ |
1115 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to an item that isn't a parent or sibling." ); |
1116 | return false; |
1117 | } else if (anchor.item == item) { |
1118 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor item to self." ); |
1119 | return false; |
1120 | } |
1121 | |
1122 | return true; |
1123 | } |
1124 | |
1125 | bool QDeclarativeAnchorsPrivate::checkVValid() const |
1126 | { |
1127 | if (usedAnchors & QDeclarativeAnchors::TopAnchor && |
1128 | usedAnchors & QDeclarativeAnchors::BottomAnchor && |
1129 | usedAnchors & QDeclarativeAnchors::VCenterAnchor) { |
1130 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot specify top, bottom, and vcenter anchors." ); |
1131 | return false; |
1132 | } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor && |
1133 | (usedAnchors & QDeclarativeAnchors::TopAnchor || |
1134 | usedAnchors & QDeclarativeAnchors::BottomAnchor || |
1135 | usedAnchors & QDeclarativeAnchors::VCenterAnchor)) { |
1136 | qmlInfo(item) << QDeclarativeAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors." ); |
1137 | return false; |
1138 | } |
1139 | |
1140 | return true; |
1141 | } |
1142 | |
1143 | bool QDeclarativeAnchorsPrivate::checkVAnchorValid(QDeclarativeAnchorLine anchor) const |
1144 | { |
1145 | if (!anchor.item) { |
1146 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to a null item." ); |
1147 | return false; |
1148 | } else if (anchor.anchorLine & QDeclarativeAnchorLine::Horizontal_Mask) { |
1149 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor a vertical edge to a horizontal edge." ); |
1150 | return false; |
1151 | } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){ |
1152 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to an item that isn't a parent or sibling." ); |
1153 | return false; |
1154 | } else if (anchor.item == item){ |
1155 | qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor item to self." ); |
1156 | return false; |
1157 | } |
1158 | |
1159 | return true; |
1160 | } |
1161 | |
1162 | QT_END_NAMESPACE |
1163 | |
1164 | #include <moc_qdeclarativeanchors_p.cpp> |
1165 | |
1166 | |