[Kst] branches/work/kst/portto4/kst/src/libkstapp

Barth Netterfield netterfield at astro.utoronto.ca
Thu Feb 23 16:56:14 UTC 2012


SVN commit 1281890 by netterfield:

Fix last known bugs in 'annotations fixed to data' mode.

To make an annotation object (eg, label, arrow) be fixed relative to the
data (rather than the plot window) select "Lock Position To Data" in the
dimensions tab of the edit view object dialog.

Behavior: 
-the endpoints of Arrow and lines are fixed to the data.  Line width and
arrow head size do not scale when zooming

-the center and rotation of label objects is fixed to the data.  The
font remains fixed when zooming. 

-Boxes: the center, width, and heigh of boxes scale/tranlate with the
data.  Rotation stays fixed to the screen.  Note: we can't just fix the
corners of rotated boxes to the data, or they wouldn't stay boxes.  We
can and do for un-rotated boxes.  I'm not totally happy with the
behavior of rotated boxes under zoom.

What is this useful for?
   -an arrow and text pointing to an interesting event in the data stays
fixed to the data, even if the plot ranges are changed (eg, the event
scrolls away, or we zoom in.)
   -a polygon region drawn in RA/Dec space will stay fixed in RA/Dec
space even if the plot zoom changes.


 M  +53 -0     labelitem.cpp  
 M  +3 -0      labelitem.h  
 M  +81 -5     lineitem.cpp  
 M  +3 -0      lineitem.h  
 M  +13 -33    viewitem.cpp  
 M  +4 -3      viewitem.h  


--- branches/work/kst/portto4/kst/src/libkstapp/labelitem.cpp #1281889:1281890
@@ -21,6 +21,8 @@
 
 #include "debug.h"
 #include "dialogdefaults.h"
+#include "plotitem.h"
+#include "cartesianrenderitem.h"
 
 #include <QDebug>
 #include <QInputDialog>
@@ -362,6 +364,57 @@
 }
 
 
+void LabelItem::updateDataRelativeRect( bool force) {
+  CartesianRenderItem* plot = dynamic_cast<CartesianRenderItem*>(parentViewItem());
+  if (plot) {
+    if ((!lockPosToData()) || force) {
+      QPointF P1 = (rect().topLeft() + rect().bottomLeft())/2;
+      QPointF P2 = (rect().topRight() + rect().bottomRight())/2;
+      _dataRelativeRect.setTopLeft(plot->plotItem()->mapToProjection(mapToParent(P1)));
+      _dataRelativeRect.setBottomRight(plot->plotItem()->mapToProjection(mapToParent(P2)));
+      _dataRelativeRect.moveCenter(plot->plotItem()->mapToProjection(mapToParent(rect().center())));
 }
+  }
+}
 
+
+void LabelItem::applyDataLockedDimensions() {
+  PlotRenderItem *render_item = qgraphicsitem_cast<PlotRenderItem *>(parentViewItem());
+  if (render_item) {
+    qreal parentWidth = render_item->width();
+    qreal parentHeight = render_item->height();
+    qreal parentX = render_item->rect().x();
+    qreal parentY = render_item->rect().y();
+    qreal parentDX = render_item->plotItem()->xMax() - render_item->plotItem()->xMin();
+    qreal parentDY = render_item->plotItem()->yMax() - render_item->plotItem()->yMin();
+
+    QPointF drP1 = _dataRelativeRect.topLeft();
+    QPointF drP2 = _dataRelativeRect.bottomRight();
+
+    QPointF P1(parentX + parentWidth*(drP1.x()-render_item->plotItem()->xMin())/parentDX,
+                       parentY + parentHeight*(render_item->plotItem()->yMax() - drP1.y())/parentDY);
+    QPointF P2(parentX + parentWidth*(drP2.x()-render_item->plotItem()->xMin())/parentDX,
+                       parentY + parentHeight*(render_item->plotItem()->yMax() - drP2.y())/parentDY);
+
+    QPointF centerP = (P1 + P2) * 0.5;
+    qreal theta = atan2(P2.y() - P1.y(), P2.x() - P1.x());
+    qreal height = rect().height();
+    qreal width = rect().width();
+
+    setPos(centerP.x(), centerP.y());
+    setViewRect(-width*0.5, -height*0.5, width, height);
+
+    QTransform transform;
+    transform.rotateRadians(theta);
+
+    setTransform(transform);
+    updateRelativeSize();
+
+  } else {
+    qDebug() << "apply data locked dimensions called without a render item (!)";
+  }
+}
+
+}
+
 // vim: ts=2 sw=2 et
--- branches/work/kst/portto4/kst/src/libkstapp/labelitem.h #1281889:1281890
@@ -58,6 +58,9 @@
 
     virtual void setFont(const QFont &f, const QColor &c);
 
+    virtual void updateDataRelativeRect(bool force = false);
+    virtual void applyDataLockedDimensions();
+
   public Q_SLOTS:
     virtual void edit();
     void setDirty() { _dirty = true; };
--- branches/work/kst/portto4/kst/src/libkstapp/lineitem.cpp #1281889:1281890
@@ -21,6 +21,9 @@
 #include <QGraphicsScene>
 #include <QGraphicsSceneContextMenuEvent>
 
+#include "plotitem.h"
+#include "cartesianrenderitem.h"
+
 namespace Kst {
 
 LineItem::LineItem(View *parent)
@@ -187,25 +190,98 @@
     return QGraphicsRectItem::mouseMoveEvent(event);
 
   QPointF p = event->pos();
-  //QPointF s = event->scenePos();
 
+  double width = 0;
+  double height = 0;
+  double theta = 0;
+  QPointF centerP;
+  QPointF P1, P2;
+
   if (gripMode() == ViewItem::Resize) {
     switch(activeGrip()) {
     case RightMidGrip:
-      resizeRight(p.x() - rightMidGrip().controlPointRect().center().x());
-      rotateTowards(rightMidGrip().controlPointRect().center(), p);
+      P1 = mapToParent(QPoint(rect().left(), rect().center().y()));
+      P2 = mapToParent(event->pos());
       break;
     case LeftMidGrip:
-      resizeLeft(p.x() - leftMidGrip().controlPointRect().center().x());
-      rotateTowards(leftMidGrip().controlPointRect().center(), p);
+      P1 = mapToParent(event->pos());
+      P2 = mapToParent(QPoint(rect().right(), rect().center().y()));
       break;
     default:
       break;
     }
+    centerP = (P1 + P2) * 0.5;
+    theta = atan2(P2.y() - P1.y(), P2.x() - P1.x());
+    height = rect().height();
+    double dx = P1.x() - P2.x();
+    double dy = P1.y() - P2.y();
+    width = sqrt(dx*dx + dy*dy)+1.0;
   }
+
+  setPos(centerP.x(), centerP.y());
+  setViewRect(-width*0.5, -height*0.5, width, height);
+
+  QTransform transform;
+  transform.rotateRadians(theta);
+
+  setTransform(transform);
+  updateRelativeSize(true);
+
 }
 
 
+void LineItem::updateDataRelativeRect(bool force) {
+  CartesianRenderItem* plot = dynamic_cast<CartesianRenderItem*>(parentViewItem());
+  if (plot) {
+    if ((!lockPosToData()) || force) {
+      QPointF P1 = (rect().topLeft() + rect().bottomLeft())/2;
+      QPointF P2 = (rect().topRight() + rect().bottomRight())/2;
+      _dataRelativeRect.setTopLeft(plot->plotItem()->mapToProjection(mapToParent(P1)));
+      _dataRelativeRect.setBottomRight(plot->plotItem()->mapToProjection(mapToParent(P2)));
+    }
+  }
+}
+
+
+void LineItem::applyDataLockedDimensions() {
+  PlotRenderItem *render_item = qgraphicsitem_cast<PlotRenderItem *>(parentViewItem());
+  if (render_item) {
+    qreal parentWidth = render_item->width();
+    qreal parentHeight = render_item->height();
+    qreal parentX = render_item->rect().x();
+    qreal parentY = render_item->rect().y();
+    qreal parentDX = render_item->plotItem()->xMax() - render_item->plotItem()->xMin();
+    qreal parentDY = render_item->plotItem()->yMax() - render_item->plotItem()->yMin();
+
+    QPointF drP1 = _dataRelativeRect.topLeft();
+    QPointF drP2 = _dataRelativeRect.bottomRight();
+
+    QPointF P1(parentX + parentWidth*(drP1.x()-render_item->plotItem()->xMin())/parentDX,
+                       parentY + parentHeight*(render_item->plotItem()->yMax() - drP1.y())/parentDY);
+    QPointF P2(parentX + parentWidth*(drP2.x()-render_item->plotItem()->xMin())/parentDX,
+                       parentY + parentHeight*(render_item->plotItem()->yMax() - drP2.y())/parentDY);
+
+    QPointF centerP = (P1 + P2) * 0.5;
+    qreal theta = atan2(P2.y() - P1.y(), P2.x() - P1.x());
+    qreal height = rect().height();
+    qreal dx = P1.x() - P2.x();
+    qreal dy = P1.y() - P2.y();
+    qreal width = sqrt(dx*dx + dy*dy)+1.0;
+
+    setPos(centerP.x(), centerP.y());
+    setViewRect(-width*0.5, -height*0.5, width, height);
+
+    QTransform transform;
+    transform.rotateRadians(theta);
+
+    setTransform(transform);
+    updateRelativeSize();
+
+  } else {
+    qDebug() << "apply data locked dimensions called without a render item (!)";
+  }
+}
+
 void LineItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
   ViewItem::mousePressEvent(event);
 }
--- branches/work/kst/portto4/kst/src/libkstapp/lineitem.h #1281889:1281890
@@ -42,6 +42,9 @@
 
     virtual QPointF centerOfRotation() const;
 
+    virtual void updateDataRelativeRect(bool force = false);
+    virtual void applyDataLockedDimensions();
+
   protected Q_SLOTS:
     virtual void creationPolygonChanged(View::CreationEvent event);
 
--- branches/work/kst/portto4/kst/src/libkstapp/viewitem.cpp #1281889:1281890
@@ -48,9 +48,7 @@
 
 #define DEBUG_GEOMETRY 0
 #define DEBUG_REPARENT 0
-#define DEBUG_CHILD_GEOMETRY 0
 
-
 // enable drag & drop
 #define KST_ENABLE_DD
 
@@ -277,7 +275,6 @@
     } else {
       height = relativeHeight * parentHeight;
     }
-
     setPos(parentX + relativeX*parentWidth, parentY + (1.0-relativeY)*parentHeight);
     setViewRect(-width/2, -height/2, width, height);
 
@@ -540,7 +537,7 @@
 
 void ViewItem::setParentViewItem(ViewItem* parent) {
   QGraphicsItem::setParentItem(parent);
-  updateRelativeSize();
+  updateRelativeSize(true);
 }
 
 
@@ -1339,7 +1336,7 @@
       break;
     }
   }
-  updateRelativeSize();
+  updateRelativeSize(true);
 }
 
 
@@ -1836,9 +1833,10 @@
 }
 
 
-void ViewItem::updateDataRelativeRect() {
+void ViewItem::updateDataRelativeRect(bool force) {
   CartesianRenderItem* plot = dynamic_cast<CartesianRenderItem*>(parentViewItem());
   if (plot) {
+    if ((!lockPosToData()) || force) {
     qreal rotation = rotationAngle();
     QTransform transform;
     setTransform(transform);
@@ -1850,8 +1848,9 @@
     setTransform(transform);
   }
 }
+}
 
-void ViewItem::updateRelativeSize() {
+void ViewItem::updateRelativeSize(bool force_data) {
   if (parentViewItem()) {
     _parentRelativeHeight = (height() / parentViewItem()->height());
     _parentRelativeWidth = (width() / parentViewItem()->width());
@@ -1859,7 +1858,7 @@
     _parentRelativeCenter =  QPointF(_parentRelativeCenter.x() / parentViewItem()->width(), _parentRelativeCenter.y() / parentViewItem()->height());
     _parentRelativePosition =  mapToParent(rect().topLeft()) - parentViewItem()->rect().topLeft();
     _parentRelativePosition =  QPointF(_parentRelativePosition.x() / parentViewItem()->width(), _parentRelativePosition.y() / parentViewItem()->height());
-    updateDataRelativeRect();
+    updateDataRelativeRect(force_data);
    } else if (view()) {
     _parentRelativeHeight = (height() / view()->height());
     _parentRelativeWidth = (width() / view()->width());
@@ -1877,26 +1876,13 @@
 
 
 void ViewItem::updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect) {
-#if DEBUG_CHILD_GEOMETRY
-  qDebug() << "ViewItem::updateChildGeometry" << this << oldParentRect << newParentRect << endl;
-#else
   Q_UNUSED(oldParentRect);
-#endif
 
   QRectF itemRect = rect();
   //Lock aspect ratio for rotating objects or children with a lockedAspectRatio
   //FIXME is the child rotated with respect to the parent is the real question...
   if (transform().isRotating() || lockAspectRatio()) {
-
-#if DEBUG_CHILD_GEOMETRY
-    qDebug() << "ViewItem::updateChildGeometry Fixed Ratio" << mapToParent(rect().center()) << _parentRelativeCenter;
-#endif
-
     if (!_fixedSize) {
-#if DEBUG_CHILD_GEOMETRY
-      qDebug() << "not fixed size";
-#endif
-
       qreal newHeight = relativeHeight() * newParentRect.height();
       qreal newWidth = relativeWidth() * newParentRect.width();
 
@@ -1922,10 +1908,6 @@
     qreal newHeight = relativeHeight() * newParentRect.height();
     qreal newWidth = relativeWidth() * newParentRect.width();
 
-#if DEBUG_CHILD_GEOMETRY
-    qDebug() << "ViewItem::updateChildGeometry non-Fixed Ratio" << "relativeHeight = " << relativeHeight() << "relative Width" << relativeWidth();
-#endif
-
     QPointF newTopLeft = newParentRect.topLeft() - itemRect.topLeft() +
                          QPointF(newParentRect.width() * _parentRelativePosition.x(),
                                  newParentRect.height() * _parentRelativePosition.y());
@@ -1935,13 +1917,6 @@
     setPos(newTopLeft);
   }
 
-#if DEBUG_CHILD_GEOMETRY
-  qDebug() << "resize"
-            << "\nbefore:" << rect()
-            << "\nafter:" << itemRect
-            << endl;
-#endif
-
   setViewRect(itemRect, true);
 }
 
@@ -2126,7 +2101,7 @@
   setPos(newpos);
   new MoveCommand(this, _originalPosition, pos);
   updateViewItemParent();
-  updateRelativeSize();
+  updateRelativeSize(true);
 }
 
 void ViewItem::viewMouseModeChanged(View::MouseMode oldMode) {
@@ -2221,6 +2196,11 @@
 }
 
 
+qreal ViewItem::rotationAngleRadians() const {
+  return atan2(transform().m12(), transform().m11());
+}
+
+
 void ViewItem::setSupportsTiedZoom(const bool supports) {
   if (supports != _supportsTiedZoom) {
 
--- branches/work/kst/portto4/kst/src/libkstapp/viewitem.h #1281889:1281890
@@ -97,8 +97,8 @@
     ViewItem *parentViewItem() const;
     void setParentViewItem(ViewItem *parent);
 
-    virtual void updateRelativeSize();
-    virtual void updateDataRelativeRect();
+    virtual void updateRelativeSize(bool force_data = false);
+    virtual void updateDataRelativeRect(bool force = false);
 
     void moveTo(const QPointF& pos);
     
@@ -113,6 +113,7 @@
     void setRelativePosition(const QPointF pos) { _parentRelativePosition = pos; }
     
     qreal rotationAngle() const;
+    qreal rotationAngleRadians() const;
 
     GripMode gripMode() const;
     void setGripMode(GripMode mode);
@@ -335,6 +336,7 @@
     QPointF dragStartPosition;
     void startDragging(QWidget *widget, const QPointF& hotspot);
     ActiveGrip _activeGrip;
+    QRectF _dataRelativeRect;
 
   private:
     GripMode _gripMode;
@@ -366,7 +368,6 @@
     QTransform _rotationTransform;
     QHash<QString, QAction*> _shortcutMap;
     qreal _parentRelativeHeight, _parentRelativeWidth;
-    QRectF _dataRelativeRect;
 
     bool _lockPosToData;
 


More information about the Kst mailing list