src/declarative/graphicsitems/qdeclarativeanchors.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
--- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp	Wed Aug 18 10:37:55 2010 +0300
@@ -53,6 +53,30 @@
 //TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
 //TODO: support non-parent, non-sibling (need to find lowest common ancestor)
 
+static qreal hcenter(QGraphicsItem *i)
+{
+    QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i);
+
+    qreal width = item->width();
+    int iw = width;
+    if (iw % 2)
+        return (width + 1) / 2;
+    else
+        return width / 2;
+}
+
+static qreal vcenter(QGraphicsItem *i)
+{
+    QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i);
+
+    qreal height = item->height();
+    int ih = height;
+    if (ih % 2)
+        return (height + 1) / 2;
+    else
+        return height / 2;
+}
+
 //### const item?
 //local position
 static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
@@ -73,10 +97,10 @@
         ret = item->y() + d->height();
         break;
     case QDeclarativeAnchorLine::HCenter:
-        ret = item->x() + d->width()/2;
+        ret = item->x() + hcenter(item);
         break;
     case QDeclarativeAnchorLine::VCenter:
-        ret = item->y() + d->height()/2;
+        ret = item->y() + vcenter(item);
         break;
     case QDeclarativeAnchorLine::Baseline:
         if (d->isDeclarativeItem)
@@ -92,26 +116,26 @@
 //position when origin is 0,0
 static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
 {
-    int ret = 0;
+    qreal ret = 0.0;
     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item);
     switch(anchorLine) {
     case QDeclarativeAnchorLine::Left:
-        ret = 0;
+        ret = 0.0;
         break;
     case QDeclarativeAnchorLine::Right:
         ret = d->width();
         break;
     case QDeclarativeAnchorLine::Top:
-        ret = 0;
+        ret = 0.0;
         break;
     case QDeclarativeAnchorLine::Bottom:
         ret = d->height();
         break;
     case QDeclarativeAnchorLine::HCenter:
-        ret = d->width()/2;
+        ret = hcenter(item);
         break;
     case QDeclarativeAnchorLine::VCenter:
-        ret = d->height()/2;
+        ret = vcenter(item);
         break;
     case QDeclarativeAnchorLine::Baseline:
         if (d->isDeclarativeItem)
@@ -189,17 +213,14 @@
 
     if (updatingCenterIn < 2) {
         ++updatingCenterIn;
-        QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item);
         if (centerIn == item->parentItem()) {
-            QGraphicsItemPrivate *parentPrivate = QGraphicsItemPrivate::get(item->parentItem());
-            QPointF p((parentPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset,
-                      (parentPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset);
+            QPointF p(hcenter(item->parentItem()) - hcenter(item) + hCenterOffset,
+                      vcenter(item->parentItem()) - vcenter(item) + vCenterOffset);
             setItemPos(p);
 
         } else if (centerIn->parentItem() == item->parentItem()) {
-            QGraphicsItemPrivate *centerPrivate = QGraphicsItemPrivate::get(centerIn);
-            QPointF p(centerIn->x() + (centerPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset,
-                      centerIn->y() + (centerPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset);
+            QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + hCenterOffset,
+                      centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
             setItemPos(p);
         }
 
@@ -459,10 +480,10 @@
 
 bool QDeclarativeAnchorsPrivate::calcStretch(const QDeclarativeAnchorLine &edge1,
                                     const QDeclarativeAnchorLine &edge2,
-                                    int offset1,
-                                    int offset2,
+                                    qreal offset1,
+                                    qreal offset2,
                                     QDeclarativeAnchorLine::AnchorLine line,
-                                    int &stretch)
+                                    qreal &stretch)
 {
     bool edge1IsParent = (edge1.item == item->parentItem());
     bool edge2IsParent = (edge2.item == item->parentItem());
@@ -471,15 +492,15 @@
 
     bool invalid = false;
     if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
-        stretch = ((int)position(edge2.item, edge2.anchorLine) + offset2)
-                    - ((int)position(edge1.item, edge1.anchorLine) + offset1);
+        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
+                    - (position(edge1.item, edge1.anchorLine) + offset1);
     } else if (edge2IsParent && edge1IsSibling) {
-        stretch = ((int)position(edge2.item, edge2.anchorLine) + offset2)
-                    - ((int)position(item->parentObject(), line)
-                    + (int)position(edge1.item, edge1.anchorLine) + offset1);
+        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
+                    - (position(item->parentObject(), line)
+                    + position(edge1.item, edge1.anchorLine) + offset1);
     } else if (edge2IsSibling && edge1IsParent) {
-        stretch = ((int)position(item->parentObject(), line) + (int)position(edge2.item, edge2.anchorLine) + offset2)
-                    - ((int)position(edge1.item, edge1.anchorLine) + offset1);
+        stretch = (position(item->parentObject(), line) + position(edge2.item, edge2.anchorLine) + offset2)
+                    - (position(edge1.item, edge1.anchorLine) + offset1);
     } else
         invalid = true;
 
@@ -497,7 +518,7 @@
         if (usedAnchors & QDeclarativeAnchors::TopAnchor) {
             //Handle stretching
             bool invalid = true;
-            int height = 0;
+            qreal height = 0.0;
             if (usedAnchors & QDeclarativeAnchors::BottomAnchor) {
                 invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QDeclarativeAnchorLine::Top, height);
             } else if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
@@ -516,7 +537,7 @@
         } else if (usedAnchors & QDeclarativeAnchors::BottomAnchor) {
             //Handle stretching (top + bottom case is handled above)
             if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
-                int height = 0;
+                qreal height = 0.0;
                 bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin,
                                               QDeclarativeAnchorLine::Top, height);
                 if (!invalid)
@@ -535,9 +556,9 @@
             //Handle vCenter
             if (vCenter.item == item->parentItem()) {
                 setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine)
-                              - itemPrivate->height()/2 + vCenterOffset);
+                              - vcenter(item) + vCenterOffset);
             } else if (vCenter.item->parentItem() == item->parentItem()) {
-                setItemY(position(vCenter.item, vCenter.anchorLine) - itemPrivate->height()/2 + vCenterOffset);
+                setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset);
             }
         } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor) {
             //Handle baseline
@@ -569,7 +590,7 @@
         if (usedAnchors & QDeclarativeAnchors::LeftAnchor) {
             //Handle stretching
             bool invalid = true;
-            int width = 0;
+            qreal width = 0.0;
             if (usedAnchors & QDeclarativeAnchors::RightAnchor) {
                 invalid = calcStretch(left, right, leftMargin, -rightMargin, QDeclarativeAnchorLine::Left, width);
             } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
@@ -588,7 +609,7 @@
         } else if (usedAnchors & QDeclarativeAnchors::RightAnchor) {
             //Handle stretching (left + right case is handled in updateLeftAnchor)
             if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
-                int width = 0;
+                qreal width = 0.0;
                 bool invalid = calcStretch(hCenter, right, hCenterOffset, -rightMargin,
                                               QDeclarativeAnchorLine::Left, width);
                 if (!invalid)
@@ -604,9 +625,9 @@
         } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
             //Handle hCenter
             if (hCenter.item == item->parentItem()) {
-                setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset);
+                setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - hcenter(item) + hCenterOffset);
             } else if (hCenter.item->parentItem() == item->parentItem()) {
-                setItemX(position(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset);
+                setItemX(position(hCenter.item, hCenter.anchorLine) - hcenter(item) + hCenterOffset);
             }
         }