[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [tikzkit] src/ui: add proper Grid implementation and grid snapping
From:       Dominik Haumann <dhaumann () kde ! org>
Date:       2014-04-30 22:16:27
Message-ID: E1Wfcnj-0000mg-RY () scm ! kde ! org
[Download RAW message or body]

Git commit c754c3f290d07075ad14bf672ac9da098f4bc0c8 by Dominik Haumann.
Committed on 30/04/2014 at 22:15.
Pushed by dhaumann into branch 'master'.

add proper Grid implementation and grid snapping

M  +1    -0    src/ui/CMakeLists.txt
M  +48   -16   src/ui/TikzView.cpp
M  +20   -0    src/ui/TikzView.h
M  +9    -26   src/ui/tools/EllipseTool.cpp
M  +8    -5    src/ui/tools/LineTool.cpp
M  +8    -25   src/ui/tools/NodeTool.cpp
A  +168  -0    src/ui/utils/Grid.cpp     [License: LGPL (v2+)]
A  +75   -0    src/ui/utils/Grid.h     [License: LGPL (v2+)]

http://commits.kde.org/tikzkit/c754c3f290d07075ad14bf672ac9da098f4bc0c8

diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 4508428..60d638a 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -52,6 +52,7 @@ set(qtikzui_SOURCES
 
     utils/AnchorManager.cpp
     utils/Ruler.cpp
+    utils/Grid.cpp
 
     TikzScene.cpp
     TikzView.cpp
diff --git a/src/ui/TikzView.cpp b/src/ui/TikzView.cpp
index 73aeb8c..227ee54 100644
--- a/src/ui/TikzView.cpp
+++ b/src/ui/TikzView.cpp
@@ -19,10 +19,12 @@
 
 #include "TikzView.h"
 #include "Ruler.h"
+#include "Grid.h"
 
 #include <tikz/core/Document.h>
 
 #include <math.h>
+#include <QApplication>
 #include <QDebug>
 #include <QScrollBar>
 
@@ -35,8 +37,9 @@ class TikzViewPrivate
 {
 public:
     TikzDocument * doc;
-    tikz::ui::Ruler * m_hRuler;
-    tikz::ui::Ruler * m_vRuler;
+    tikz::ui::Grid * grid;
+    tikz::ui::Ruler * hRuler;
+    tikz::ui::Ruler * vRuler;
     QPointF lastMousePos;
     bool handTool;
 };
@@ -54,18 +57,20 @@ TikzView::TikzView(TikzDocument * doc, QWidget * parent)
     gridLayout->setSpacing(0);
     gridLayout->setMargin(0);
 
-    d->m_hRuler = new tikz::ui::Ruler(Qt::Horizontal, this);
-    d->m_vRuler = new tikz::ui::Ruler(Qt::Vertical, this);
+    d->grid = new tikz::ui::Grid(this);
 
-    d->m_hRuler->setUnit(tikz::Centimeter);
-    d->m_vRuler->setUnit(tikz::Centimeter);
+    d->hRuler = new tikz::ui::Ruler(Qt::Horizontal, this);
+    d->vRuler = new tikz::ui::Ruler(Qt::Vertical, this);
+
+    d->hRuler->setUnit(tikz::Centimeter);
+    d->vRuler->setUnit(tikz::Centimeter);
 
     QWidget* top = new QWidget();
     top->setBackgroundRole(QPalette::Window);
     top->setFixedSize(s_ruler_size, s_ruler_size);
     gridLayout->addWidget(top, 0, 0);
-    gridLayout->addWidget(d->m_hRuler, 0, 1);
-    gridLayout->addWidget(d->m_vRuler, 1, 0);
+    gridLayout->addWidget(d->hRuler, 0, 1);
+    gridLayout->addWidget(d->vRuler, 1, 0);
     gridLayout->addWidget(viewport(), 1, 1);
 
     setLayout(gridLayout);
@@ -81,6 +86,24 @@ TikzDocument * TikzView::document() const
     return d->doc;
 }
 
+tikz::Value TikzView::snapValue(const tikz::Value & value) const
+{
+    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
+    return snap ? d->grid->snapValue(value) : value;
+}
+
+tikz::Pos TikzView::snapPos(const tikz::Pos & pos) const
+{
+    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
+    return snap ? d->grid->snapPos(pos) : pos;
+}
+
+qreal TikzView::snapAngle(qreal angle) const
+{
+    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
+    return snap ? (qRound(angle / 15) * 15) : angle;
+}
+
 void TikzView::mousePressEvent(QMouseEvent* event)
 {
     d->lastMousePos = event->pos();
@@ -111,11 +134,11 @@ void TikzView::mouseMoveEvent(QMouseEvent* event)
     }
 
     // update mouse indicator on rulers
-    d->m_hRuler->setOrigin(d->m_hRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
                0)))).x());
-    d->m_vRuler->setOrigin(d->m_vRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
0)))).y()); +    d->hRuler->setOrigin(d->hRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
0)))).x()); +    d->vRuler->setOrigin(d->vRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
0)))).y());  
-    d->m_hRuler->setMousePos(event->globalPos());
-    d->m_vRuler->setMousePos(event->globalPos());
+    d->hRuler->setMousePos(event->globalPos());
+    d->vRuler->setMousePos(event->globalPos());
 
     // track last mouse position
     d->lastMousePos = event->pos();
@@ -149,15 +172,24 @@ void TikzView::wheelEvent(QWheelEvent* event)
 
 bool TikzView::viewportEvent(QEvent * event)
 {
-    d->m_hRuler->setOrigin(d->m_hRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
                0)))).x());
-    d->m_vRuler->setOrigin(d->m_vRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
0)))).y()); +    d->hRuler->setOrigin(d->hRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
0)))).x()); +    d->vRuler->setOrigin(d->vRuler->mapFromGlobal(viewport()->mapToGlobal(mapFromScene(QPointF(0, \
0)))).y());  const qreal s = tikz::Value(1, tikz::Inch).toPoint();
-    d->m_hRuler->setZoom(transform().m11() / physicalDpiX() * s);
-    d->m_vRuler->setZoom(qAbs(transform().m22()) / physicalDpiY() * s);
+    d->hRuler->setZoom(transform().m11() / physicalDpiX() * s);
+    d->vRuler->setZoom(qAbs(transform().m22()) / physicalDpiY() * s);
 
     return QGraphicsView::viewportEvent(event);
 }
 
+void TikzView::drawBackground(QPainter * painter, const QRectF & rect)
+{
+    // draw default background (typically nothing)
+    QGraphicsView::drawBackground(painter, rect);
+
+    // draw raster on top
+    d->grid->draw(painter, rect);
+}
+
 }
 }
 
diff --git a/src/ui/TikzView.h b/src/ui/TikzView.h
index 0ca758d..61f7fe4 100644
--- a/src/ui/TikzView.h
+++ b/src/ui/TikzView.h
@@ -24,6 +24,9 @@
 
 #include "tikzgui_export.h"
 
+#include <tikz/core/Value.h>
+#include <tikz/core/Pos.h>
+
 
 namespace tikz {
 namespace ui {
@@ -51,6 +54,22 @@ class TIKZUI_EXPORT TikzView : public QGraphicsView
          */
         TikzDocument * document() const;
 
+        /**
+         * Snap @p value to the grid.
+         */
+        tikz::Value snapValue(const tikz::Value & value) const;
+
+        /**
+         * Snap x/y components of @p pos to the grid.
+         */
+        tikz::Pos snapPos(const tikz::Pos & pos) const;
+
+        /**
+         * Snap @p angle in degrees to a 15 ° raster.
+         */
+        qreal snapAngle(qreal angle) const;
+
+
     protected:
         void mousePressEvent(QMouseEvent* event) override;
         void mouseMoveEvent(QMouseEvent* event) override;
@@ -58,6 +77,7 @@ class TIKZUI_EXPORT TikzView : public QGraphicsView
         void wheelEvent(QWheelEvent* event) override;
         bool viewportEvent(QEvent * event) override;
 
+        void drawBackground(QPainter * painter, const QRectF & rect) override;
 
     private:
         TikzViewPrivate * const d;
diff --git a/src/ui/tools/EllipseTool.cpp b/src/ui/tools/EllipseTool.cpp
index a35da53..8350758 100644
--- a/src/ui/tools/EllipseTool.cpp
+++ b/src/ui/tools/EllipseTool.cpp
@@ -24,6 +24,7 @@
 #include "EllipsePathItem.h"
 #include "AnchorManager.h"
 #include "TikzDocument.h"
+#include "TikzView.h"
 #include <tikz/core/EdgeStyle.h>
 #include <tikz/core/EllipsePath.h>
 
@@ -136,26 +137,9 @@ QPointF EllipseTool::handlePos(Handle::Position pos)
     return c + t.map(p);
 }
 
-static void snapPos(tikz::Pos & pos)
-{
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
-    if (snap) {
-        pos = tikz::Pos(qRound(pos.x().value() / 0.2) * 0.2,
-                        qRound(pos.y().value() / 0.2) * 0.2, pos.x().unit());
-    }
-}
-
-static void snapValue(tikz::Value & val)
-{
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
-    if (snap) {
-        val = tikz::Value(qRound(val.value() / 0.2) * 0.2, val.unit());
-    }
-}
-
 void EllipseTool::handleMoved(Handle * handle, const QPointF & scenePos, \
QGraphicsView * view)  {
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
+    TikzView * tikzView = qobject_cast<TikzView *>(view);
 
     //
     // rotate
@@ -163,8 +147,7 @@ void EllipseTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphi  if (handle->handleType() == Handle::RotateHandle) {
         const QPointF delta = m_path->pos() - scenePos;
         const qreal rad = atan2(-delta.y(), -delta.x());
-        qreal deg = rad * 180 / M_PI + 90;
-        if (snap) deg = qRound(deg / 15) * 15;
+        const qreal deg = tikzView->snapAngle(rad * 180 / M_PI + 90);
         tikz::core::EdgeStyle s;
         s.setStyle(*m_path->style());
         s.setRotation(deg);
@@ -183,9 +166,9 @@ void EllipseTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphi  // try to attach to anchor
         tikz::core::EllipsePath * ep = m_path->ellipsePath();
         tikz::core::MetaPos metaPos = m_anchorManager->anchorAt(scenePos, view);
-        if (snap && ! metaPos.node()) {
+        if (! metaPos.node()) {
             tikz::Pos p = tikz::Pos(scenePos).convertTo(unit);
-            snapPos(p);
+            p = tikzView->snapPos(p);
             metaPos.setPos(p);
         }
 
@@ -213,8 +196,8 @@ void EllipseTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphi  h = delta.y();
 
             // snap to raster
-            snapValue(w);
-            snapValue(h);
+            w = tikzView->snapValue(w);
+            h = tikzView->snapValue(h);
 
             break;
         }
@@ -222,14 +205,14 @@ void EllipseTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphi  case Handle::BottomBorder: {
             h = delta.y();
             // snap to raster
-            snapValue(h);
+            h = tikzView->snapValue(h);
             break;
         }
         case Handle::LeftBorder:
         case Handle::RightBorder: {
             w = delta.x();
             // snap to raster
-            snapValue(w);
+            w = tikzView->snapValue(w);
             break;
         }
         case Handle::Center: Q_ASSERT(false);
diff --git a/src/ui/tools/LineTool.cpp b/src/ui/tools/LineTool.cpp
index aa76fdb..6b648fa 100644
--- a/src/ui/tools/LineTool.cpp
+++ b/src/ui/tools/LineTool.cpp
@@ -24,6 +24,7 @@
 #include "EdgePathItem.h"
 #include "AnchorManager.h"
 #include "TikzDocument.h"
+#include "TikzView.h"
 
 #include <tikz/core/EdgeStyle.h>
 #include <tikz/core/EdgePath.h>
@@ -114,15 +115,17 @@ QPointF LineTool::handlePos(Handle::Position pos)
 
 void LineTool::handleMoved(Handle * handle, const QPointF & scenePos, QGraphicsView \
* view)  {
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
+    TikzView * tikzView = qobject_cast<TikzView *>(view);
+
+    // later: preferred unit
+    const tikz::Unit unit = tikz::Centimeter;
 
     // try to attach to anchor
     tikz::core::MetaPos metaPos = m_anchorManager->anchorAt(scenePos, view);
 
-    if (snap && ! metaPos.node()) {
-        QPointF p = scenePos;
-        p.rx() = qRound(p.x() / 0.2) * 0.2;
-        p.ry() = qRound(p.y() / 0.2) * 0.2;
+    if (! metaPos.node()) {
+        tikz::Pos p = tikz::Pos(scenePos).convertTo(unit);
+        p = tikzView->snapPos(p);
         metaPos.setPos(p);
     }
 
diff --git a/src/ui/tools/NodeTool.cpp b/src/ui/tools/NodeTool.cpp
index 32ea756..868eb27 100644
--- a/src/ui/tools/NodeTool.cpp
+++ b/src/ui/tools/NodeTool.cpp
@@ -23,6 +23,7 @@
 #include "MoveHandle.h"
 #include "NodeItem.h"
 #include "TikzDocument.h"
+#include "TikzView.h"
 #include <tikz/core/NodeStyle.h>
 
 #include <QApplication>
@@ -135,26 +136,9 @@ QPointF NodeTool::handlePos(Handle::Position pos)
     return c + t.map(p);
 }
 
-static void snapPos(tikz::Pos & pos)
-{
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
-    if (snap) {
-        pos = tikz::Pos(qRound(pos.x().value() / 0.2) * 0.2,
-                        qRound(pos.y().value() / 0.2) * 0.2, pos.x().unit());
-    }
-}
-
-static void snapValue(tikz::Value & val)
-{
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
-    if (snap) {
-        val = tikz::Value(qRound(val.value() / 0.2) * 0.2, val.unit());
-    }
-}
-
 void NodeTool::handleMoved(Handle * handle, const QPointF & scenePos, QGraphicsView \
* view)  {
-    const bool snap = QApplication::keyboardModifiers() ^ Qt::ShiftModifier;
+    TikzView * tikzView = qobject_cast<TikzView *>(view);
 
     // later: preferred unit
     const tikz::Unit unit = tikz::Centimeter;
@@ -165,8 +149,7 @@ void NodeTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphicsV  if (handle->handleType() == Handle::RotateHandle) {
         const QPointF delta = m_node->node()->pos() - tikz::Pos(scenePos);
         const qreal rad = atan2(-delta.y(), -delta.x());
-        qreal deg = rad * 180 / M_PI + 90;
-        if (snap) deg = qRound(deg / 15) * 15;
+        const qreal deg = tikzView->snapAngle(rad * 180 / M_PI + 90);
         tikz::core::NodeStyle s;
         s.setStyle(*m_node->style());
         s.setRotation(deg);
@@ -180,7 +163,7 @@ void NodeTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphicsV  //
     if (handle->handlePos() == Handle::Center) {
         tikz::Pos p = tikz::Pos(scenePos).convertTo(unit);
-        snapPos(p);
+        p = tikzView->snapPos(p);
         m_node->node()->setPos(p);
         return;
     }
@@ -205,8 +188,8 @@ void NodeTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphicsV  h = delta.y();
 
             // snap to raster
-            snapValue(w);
-            snapValue(h);
+            w = tikzView->snapValue(w);
+            h = tikzView->snapValue(h);
 
             break;
         }
@@ -214,14 +197,14 @@ void NodeTool::handleMoved(Handle * handle, const QPointF & \
scenePos, QGraphicsV  case Handle::BottomBorder: {
             h = delta.y();
             // snap to raster
-            snapValue(h);
+            h = tikzView->snapValue(h);
             break;
         }
         case Handle::LeftBorder:
         case Handle::RightBorder: {
             w = delta.x();
             // snap to raster
-            snapValue(w);
+            w = tikzView->snapValue(w);
             break;
         }
         case Handle::Center: Q_ASSERT(false);
diff --git a/src/ui/utils/Grid.cpp b/src/ui/utils/Grid.cpp
new file mode 100644
index 0000000..6365221
--- /dev/null
+++ b/src/ui/utils/Grid.cpp
@@ -0,0 +1,168 @@
+/* This file is part of the TikZKit project.
+ *
+ * Copyright (C) 2014 Dominik Haumann <dhaumann@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "Grid.h"
+
+#include <tikz/core/Value.h>
+
+#include <QGraphicsView>
+#include <QDebug>
+
+namespace tikz {
+namespace ui {
+
+class GridPrivate
+{
+public:
+    QGraphicsView * view;
+    qreal zoom = 1000000000;
+    QRectF rect;
+
+    QVarLengthArray<QLineF, 256> majorLines;
+    QVarLengthArray<QLineF, 256> minorLines;
+
+    /**
+     * Returns the number of lines that are visible per unit:
+     * - 1 equals only major lines
+     * - 2 means each unit is subdivided by one minor line
+     * - 3, ...
+     * The return value is guaranteed to be greater or equal to 1.
+     */
+    int linesPerUnit(tikz::Unit unit) const
+    {
+        const qreal s = tikz::Value(1, tikz::Inch).toPoint();
+        const qreal zoom = view->transform().m11() / view->physicalDpiX() * s;
+
+        // how much space does one unit have on screen [cm] ?
+        const tikz::Value oneUnitOnScreen = tikz::Value(zoom, \
unit);//.convertTo(tikz::Centimeter); +
+        // we want a line each 5 mm
+        int linesPerUnit = 1;
+        while ((oneUnitOnScreen / linesPerUnit) >= tikz::Value(10, \
tikz::Millimeter)) { +            linesPerUnit *= 2;
+        }
+
+        Q_ASSERT(linesPerUnit > 0);
+        return linesPerUnit;
+    }
+
+    /**
+     * Update the cached major and minor lines.
+     */
+    void updateCache(const QRectF & r)
+    {
+        const qreal s = tikz::Value(1, tikz::Inch).toPoint();
+        const qreal z = view->transform().m11() / view->physicalDpiX() * s;
+
+        if (rect != r || zoom != z) {
+            rect = r;
+            zoom = z;
+
+            // TODO (later): make this unit configurable
+            const tikz::Unit unit = tikz::Centimeter;
+
+            // we want a line each 5 mm
+            const int lpu = linesPerUnit(unit);
+            qDebug() << "lines per unit" << lpu;
+
+            majorLines.clear();
+            minorLines.clear();
+
+            const Value one(1, unit);
+
+            tikz::Value left = \
tikz::Value(tikz::Value(rect.left()).convertTo(unit).value()); +            left = \
tikz::Value(std::floor(left.value()), unit); +
+            tikz::Value top = \
tikz::Value(tikz::Value(rect.top()).convertTo(unit).value()); +            top = \
tikz::Value(std::ceil(top.value()), unit); +
+            QVarLengthArray<QLineF, 100> lines;
+            int i = 0;
+            for (tikz::Value x = left; x.toPoint() < rect.right(); x += one / lpu) {
+                if ((i % lpu) == 0) {
+                    majorLines.append(QLineF(x.toPoint(), rect.top(), x.toPoint(), \
rect.bottom())); +                } else {
+                    minorLines.append(QLineF(x.toPoint(), rect.top(), x.toPoint(), \
rect.bottom())); +                }
+                ++i;
+            }
+
+            i = 0;
+            for (tikz::Value y = top; y.toPoint() < rect.bottom(); y += one / lpu) {
+                if ((i % lpu) == 0) {
+                    majorLines.append(QLineF(rect.left(), y.toPoint(), rect.right(), \
y.toPoint())); +                } else {
+                    minorLines.append(QLineF(rect.left(), y.toPoint(), rect.right(), \
y.toPoint())); +                }
+                ++i;
+            }
+
+        }
+    }
+};
+
+Grid::Grid(QGraphicsView * view)
+    : d(new GridPrivate())
+{
+    d->view = view;
+}
+
+Grid::~Grid()
+{
+    delete d;
+}
+
+void Grid::draw(QPainter * p, const QRectF & rect)
+{
+    d->updateCache(rect);
+
+    p->save();
+//     QPen pen(QColor(243, 243, 243));
+    QPen pen(QColor(230, 230, 230));
+    pen.setWidth(0);
+    p->setPen(pen);
+    p->drawLines(d->majorLines.data(), d->majorLines.size());
+
+    pen.setDashPattern(QVector<qreal>() << 5 << 5);
+    p->setPen(pen);
+    p->drawLines(d->minorLines.data(), d->minorLines.size());
+    p->restore();
+}
+
+tikz::Value Grid::snapValue(const tikz::Value & value) const
+{
+    // TODO (later): make this unit configurable
+    const tikz::Unit unit = tikz::Centimeter;
+    const int lpu = d->linesPerUnit(unit);
+    const Value one(1.0 / lpu, unit);
+
+    const auto snappedValue = tikz::Value(qRound(value.convertTo(unit).value() / \
one.value()) * one.value(), unit).convertTo(value.unit()); +//     qDebug() << value \
<< "converts to:" << snappedValue; +    return snappedValue;
+}
+
+tikz::Pos Grid::snapPos(const tikz::Pos & pos) const
+{
+    return tikz::Pos(snapValue(pos.x()), snapValue(pos.y()));
+}
+
+}
+}
+
+// kate: indent-width 4; replace-tabs on;
diff --git a/src/ui/utils/Grid.h b/src/ui/utils/Grid.h
new file mode 100644
index 0000000..ed56835
--- /dev/null
+++ b/src/ui/utils/Grid.h
@@ -0,0 +1,75 @@
+/* This file is part of the TikZKit project.
+ *
+ * Copyright (C) 2014 Dominik Haumann <dhaumann@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TIKZ_UI_GRID_H
+#define TIKZ_UI_GRID_H
+
+#include <QVarLengthArray>
+#include <QRectF>
+#include <QLineF>
+
+#include <tikz/core/Value.h>
+#include <tikz/core/Pos.h>
+
+class QGraphicsView;
+class QPainter;
+
+namespace tikz {
+namespace ui {
+
+class GridPrivate;
+
+class Grid
+{
+public:
+    /**
+     * Constructor with required @p view.
+     */
+    Grid(QGraphicsView * view);
+
+    /**
+     * Destructor.
+     */
+    ~Grid();
+
+    /**
+     * Draw the grid using the painter @p p.
+     */
+    void draw(QPainter * p, const QRectF & rect);
+
+    /**
+     * Snap @p value to the grid.
+     */
+    tikz::Value snapValue(const tikz::Value & value) const;
+
+    /**
+     * Snap x/y components of @p pos to the grid.
+     */
+    tikz::Pos snapPos(const tikz::Pos & pos) const;
+
+private:
+    GridPrivate * const d;
+};
+
+}
+}
+
+#endif // TIKZ_UI_GRID_H
+
+// kate: indent-width 4; replace-tabs on;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic