[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [tikzkit] qtikzgui: first success of resizing an Ellipse Path
From: Dominik Haumann <dhaumann () kde ! org>
Date: 2013-12-31 18:40:45
Message-ID: E1Vy4FB-0000pn-GG () scm ! kde ! org
[Download RAW message or body]
Git commit 86c1d35b59e0d8e3033e8670749cb66d5d5ea962 by Dominik Haumann.
Committed on 31/12/2013 at 15:34.
Pushed by dhaumann into branch 'master'.
first success of resizing an Ellipse Path
M +2 -0 qtikzgui/CMakeLists.txt
M +3 -2 qtikzgui/TikzPath.cpp
M +7 -0 qtikzgui/TikzPath.h
M +1 -1 qtikzgui/TikzScene.cpp
M +5 -0 qtikzgui/paths/AbstractTikzPath.cpp
M +6 -0 qtikzgui/paths/AbstractTikzPath.h
A +93 -0 qtikzgui/paths/PathHandle.cpp [License: LGPL (v2+)]
A +89 -0 qtikzgui/paths/PathHandle.h [License: LGPL (v2+)]
M +121 -6 qtikzgui/paths/ellipse/TikzEllipsePath.cpp
M +29 -11 qtikzgui/paths/ellipse/TikzEllipsePath.h
http://commits.kde.org/tikzkit/86c1d35b59e0d8e3033e8670749cb66d5d5ea962
diff --git a/qtikzgui/CMakeLists.txt b/qtikzgui/CMakeLists.txt
index 8377c67..094de59 100644
--- a/qtikzgui/CMakeLists.txt
+++ b/qtikzgui/CMakeLists.txt
@@ -30,6 +30,7 @@ set(qtikzgui_SOURCES
paths/AbstractTikzPath.cpp
paths/ellipse/TikzEllipsePath.cpp
+ paths/PathHandle.cpp
TikzScene.cpp
TikzView.cpp
@@ -73,6 +74,7 @@ set(qtikzgui_HEADERS
paths/AbstractTikzPath.h
paths/ellipse/TikzEllipsePath.h
+ paths/PathHandle.h
TikzScene.h
TikzView.h
diff --git a/qtikzgui/TikzPath.cpp b/qtikzgui/TikzPath.cpp
index e704cf7..d8fd2ce 100644
--- a/qtikzgui/TikzPath.cpp
+++ b/qtikzgui/TikzPath.cpp
@@ -135,11 +135,13 @@ void TikzPath::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
void TikzPath::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
d->backendPath->mousePressEvent(event);
+ TikzItem::mousePressEvent(event);
}
void TikzPath::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
d->backendPath->mouseReleaseEvent(event);
+ TikzItem::mouseReleaseEvent(event);
}
QVariant TikzPath::itemChange(GraphicsItemChange change, const QVariant & value)
@@ -147,8 +149,7 @@ QVariant TikzPath::itemChange(GraphicsItemChange change, const QVariant & value)
if (change == ItemSelectedHasChanged) {
// show / hide handles if selected
const bool selected = value.toBool();
-
- // FIXME: implement ?
+ emit itemSelected(selected);
}
return QGraphicsObject::itemChange(change, value);
diff --git a/qtikzgui/TikzPath.h b/qtikzgui/TikzPath.h
index 59a43ef..56c9b1e 100644
--- a/qtikzgui/TikzPath.h
+++ b/qtikzgui/TikzPath.h
@@ -105,6 +105,13 @@ class TIKZGUI_EXPORT TikzPath : public TikzItem
*/
bool contains(const QPointF & point) const;
+ Q_SIGNALS:
+ /**
+ * This signal is emitted whenever the item selection changes.
+ * @param selected @p true, if the item is selected, otherwise @p false
+ */
+ void itemSelected(bool selected);
+
//
// Mouse handling and overrides
//
diff --git a/qtikzgui/TikzScene.cpp b/qtikzgui/TikzScene.cpp
index 59aae4e..57153dd 100644
--- a/qtikzgui/TikzScene.cpp
+++ b/qtikzgui/TikzScene.cpp
@@ -191,7 +191,7 @@ void TikzScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
const QRectF br(itemsBoundingRect());
if (br.isValid()) {
- setSceneRect(itemsBoundingRect());
+// setSceneRect(itemsBoundingRect()); // FIXME: needed?
} else {
qWarning() << "TikzScene::mouseMoveEvent: invalid bounding rect, ignoring";
}
diff --git a/qtikzgui/paths/AbstractTikzPath.cpp b/qtikzgui/paths/AbstractTikzPath.cpp
index 98c133e..66f8875 100644
--- a/qtikzgui/paths/AbstractTikzPath.cpp
+++ b/qtikzgui/paths/AbstractTikzPath.cpp
@@ -54,6 +54,11 @@ tikz::EdgeStyle* AbstractTikzPath::style() const
return m_path->style();
}
+QGraphicsScene * AbstractTikzPath::scene() const
+{
+ return m_path->scene();
+}
+
void AbstractTikzPath::update()
{
m_path->update();
diff --git a/qtikzgui/paths/AbstractTikzPath.h b/qtikzgui/paths/AbstractTikzPath.h
index 6e94e0c..e26842a 100644
--- a/qtikzgui/paths/AbstractTikzPath.h
+++ b/qtikzgui/paths/AbstractTikzPath.h
@@ -33,6 +33,7 @@ namespace tikz {
class QPainter;
class QStyleOptionGraphicsItem;
class QGraphicsSceneMouseEvent;
+class QGraphicsScene;
class TikzDocument;
class TikzPath;
@@ -75,6 +76,11 @@ class AbstractTikzPath : public QObject
public:
/**
+ * Get the graphics scene this item is associated with.
+ */
+ QGraphicsScene * scene() const;
+
+ /**
* Request a repaint of this item.
*/
void update();
diff --git a/qtikzgui/paths/PathHandle.cpp b/qtikzgui/paths/PathHandle.cpp
new file mode 100644
index 0000000..281995a
--- /dev/null
+++ b/qtikzgui/paths/PathHandle.cpp
@@ -0,0 +1,93 @@
+/* This file is part of the TikZKit project.
+ *
+ * Copyright (C) 2013 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 "PathHandle.h"
+#include "TikzPath.h"
+
+#include <QPainter>
+#include <QStyleOptionGraphicsItem>
+#include <QEvent>
+#include <QGraphicsSceneMouseEvent>
+
+#include <QDebug>
+
+PathHandle::PathHandle(TikzPath * path)
+ : TikzItem(path)
+{
+ // show above paths
+ setZValue(10.0);
+
+ setFlag(QGraphicsItem::ItemIsSelectable, true);
+}
+
+PathHandle::~PathHandle()
+{
+}
+
+int PathHandle::type() const
+{
+ return UserType + 5;
+}
+
+void PathHandle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(widget);
+ Q_UNUSED(option);
+
+ // debugging
+// painter->drawRect(boundingRect());
+
+ painter->save();
+ painter->setRenderHints(QPainter::Antialiasing);
+
+ painter->setPen(isHovered() || isSelected() ? Qt::green : Qt::blue);
+ painter->setBrush(isHovered() || isSelected() ? QColor(0, 255, 0, 125) : QColor(0, 0, 255, 125));
+ painter->drawEllipse(QPointF(0, 0), 0.2, 0.2);
+
+ painter->restore();
+}
+
+QRectF PathHandle::boundingRect() const
+{
+ return QRectF(-0.25, -0.25, 0.5, 0.5);
+}
+
+bool PathHandle::contains(const QPointF &point) const
+{
+ // within circle of 2.5 mm?
+ return (point.x() * point.x() + point.y() * point.y()) <= (0.25 * 0.25);
+}
+
+void PathHandle::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
+{
+ event->accept();
+ emit positionChanged(this, event->scenePos());
+}
+
+void PathHandle::mousePressEvent(QGraphicsSceneMouseEvent * event)
+{
+ event->accept();
+}
+
+void PathHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
+{
+ event->accept();
+}
+
+// kate: indent-width 4; replace-tabs on;
diff --git a/qtikzgui/paths/PathHandle.h b/qtikzgui/paths/PathHandle.h
new file mode 100644
index 0000000..44712b6
--- /dev/null
+++ b/qtikzgui/paths/PathHandle.h
@@ -0,0 +1,89 @@
+/* This file is part of the TikZKit project.
+ *
+ * Copyright (C) 2013 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_PATH_HANDLE_H
+#define TIKZ_PATH_HANDLE_H
+
+#include "tikzgui_export.h"
+#include "tikz.h"
+
+#include "TikzItem.h"
+
+class QPainter;
+class TikzPath;
+class PathHandlePrivate;
+
+class PathHandle : public TikzItem
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor.
+ */
+ PathHandle(TikzPath * path = 0);
+
+ /**
+ * Destructor
+ */
+ virtual ~PathHandle();
+
+ /**
+ * Reimplment to return a proper UserType + 4.
+ */
+ int type() const override;
+
+ Q_SIGNALS:
+ /**
+ * This signal is emitted whenever the position of this handle
+ * changed through user interaction.
+ */
+ void positionChanged(PathHandle * handle, const QPointF & pos);
+
+ //
+ // reimplemented from QGraphicsItem
+ //
+ public:
+ /**
+ * Paint this item.
+ */
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+
+ /**
+ * Returns the bounding rect of this item.
+ */
+ QRectF boundingRect() const override;
+
+ /**
+ * Returns @p true, if @p point is contained in this handle.
+ */
+ bool contains(const QPointF &point) const override;
+
+ //
+ // protected overrides
+ //
+ protected:
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent * event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event);
+};
+
+#endif // TIKZ_PATH_HANDLE_H
+
+// kate: indent-width 4; replace-tabs on;
diff --git a/qtikzgui/paths/ellipse/TikzEllipsePath.cpp b/qtikzgui/paths/ellipse/TikzEllipsePath.cpp
index ad74071..007752c 100644
--- a/qtikzgui/paths/ellipse/TikzEllipsePath.cpp
+++ b/qtikzgui/paths/ellipse/TikzEllipsePath.cpp
@@ -25,6 +25,7 @@
#include "TikzNode.h"
#include "TikzDocument.h"
#include "EdgeStyle.h"
+#include "PathHandle.h"
#include <QPainter>
#include <QGraphicsScene>
@@ -37,6 +38,16 @@
TikzEllipsePath::TikzEllipsePath(TikzPath * path)
: AbstractTikzPath(path)
{
+ m_topLeft = 0;
+ m_top = 0;
+ m_topRight = 0;
+ m_left = 0;
+ m_center = 0;
+ m_right = 0;
+ m_bottomLeft = 0;
+ m_bottom = 0;
+ m_bottomRight = 0;
+
// FIXME: some sort of init needed?
// init();
@@ -46,6 +57,7 @@ TikzEllipsePath::TikzEllipsePath(TikzPath * path)
this, SLOT(updateNode(tikz::Node*)));
connect(path->path(), SIGNAL(changed()), this, SLOT(slotUpdate()));
+ connect(path, SIGNAL(itemSelected(bool)), this, SLOT(setShowHandles(bool)));
}
TikzEllipsePath::~TikzEllipsePath()
@@ -103,6 +115,8 @@ void TikzEllipsePath::slotUpdate()
path()->prepareGeometryChange();
m_dirty = true;
+
+ updateHandlePositions();
}
void TikzEllipsePath::paint(QPainter *painter,
@@ -133,8 +147,6 @@ void TikzEllipsePath::paint(QPainter *painter,
painter->setPen(p);
painter->drawPath(m_ellipse);
}
-
- painter->restore();
}
QRectF TikzEllipsePath::boundingRect() const
@@ -158,16 +170,18 @@ bool TikzEllipsePath::contains(const QPointF & point) const
const_cast<TikzEllipsePath*>(this)->updateCache();
// contains depends on the type of fill color/brush
- if (style()->fillColor() == Qt::transparent) {
- return m_hoverPath.contains(point);
- } else {
+// if (style()->fillColor() == Qt::transparent) {
+// return m_hoverPath.contains(point);
+// } else {
return m_ellipse.contains(point)
|| m_hoverPath.contains(point);
- }
+// }
}
void TikzEllipsePath::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
+ ellipsePath()->setPos(event->scenePos());
+ updateHandlePositions();
// if (!d->dragging) {
// event->ignore();
// TikzItem::mouseMoveEvent(event);
@@ -224,6 +238,10 @@ void TikzEllipsePath::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
void TikzEllipsePath::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
+ qDebug() << "Path selected" << path()->isSelected();
+ if (path()->isSelected()) {
+ updateHandlePositions();
+ }
/*if (!contains(event->pos()) || !isSelected()) {
TikzItem::mousePressEvent(event);
} else*/ {
@@ -300,4 +318,101 @@ tikz::EllipsePath * TikzEllipsePath::ellipsePath() const
return p;
}
+void TikzEllipsePath::setShowHandles(bool show)
+{
+ // handles already visible?
+ if (show && m_topLeft != nullptr) {
+ return;
+ }
+
+ // delete handles, if hide
+ if (!show && m_topLeft != nullptr) {
+ delete m_topLeft;
+ delete m_top;
+ delete m_topRight;
+ delete m_left;
+ delete m_center;
+ delete m_right;
+ delete m_bottomLeft;
+ delete m_bottom;
+ delete m_bottomRight;
+
+ m_topLeft = 0;
+ m_top = 0;
+ m_topRight = 0;
+ m_left = 0;
+ m_center = 0;
+ m_right = 0;
+ m_bottomLeft = 0;
+ m_bottom = 0;
+ m_bottomRight = 0;
+
+ return;
+ }
+
+ m_topLeft = new PathHandle();
+ m_top = new PathHandle();
+ m_topRight = new PathHandle();
+ m_left = new PathHandle();
+ m_center = new PathHandle();
+ m_right = new PathHandle();
+ m_bottomLeft = new PathHandle();
+ m_bottom = new PathHandle();
+ m_bottomRight = new PathHandle();
+
+ QGraphicsScene * s = scene();
+ s->addItem(m_topLeft);
+ s->addItem(m_top);
+ s->addItem(m_topRight);
+ s->addItem(m_left);
+ s->addItem(m_center);
+ s->addItem(m_right);
+ s->addItem(m_bottomLeft);
+ s->addItem(m_bottom);
+ s->addItem(m_bottomRight);
+
+ updateHandlePositions();
+
+ m_topLeft->show();
+ m_top->show();
+ m_topRight->show();
+ m_left->show();
+ m_center->show();
+ m_right->show();
+ m_bottomLeft->show();
+ m_bottom->show();
+ m_bottomRight->show();
+ connect(m_topLeft, SIGNAL(positionChanged(PathHandle *, const QPointF &)),
+ this, SLOT(handleMoved(PathHandle *, const QPointF &)));
+}
+
+void TikzEllipsePath::updateHandlePositions()
+{
+ if (!m_topLeft) return;
+
+ const qreal rx = style()->radiusX();
+ const qreal ry = style()->radiusY();
+
+ m_topLeft->setPos(ellipsePath()->pos() + QPointF(-rx, ry));
+ m_top->setPos(ellipsePath()->pos() + QPointF(0, ry));
+ m_topRight->setPos(ellipsePath()->pos() + QPointF(rx, ry));
+ m_left->setPos(ellipsePath()->pos() + QPointF(-rx, 0));
+ m_center->setPos(ellipsePath()->pos() + QPointF(0, 0));
+ m_right->setPos(ellipsePath()->pos() + QPointF(rx, 0));
+ m_bottomLeft->setPos(ellipsePath()->pos() + QPointF(-rx, -ry));
+ m_bottom->setPos(ellipsePath()->pos() + QPointF(0, -ry));
+ m_bottomRight->setPos(ellipsePath()->pos() + QPointF(rx, -ry));
+}
+
+void TikzEllipsePath::handleMoved(PathHandle * handle, const QPointF & pos)
+{
+ const QPointF center = ellipsePath()->pos();
+ const qreal dx = qAbs(center.x() - pos.x());
+ const qreal dy = qAbs(center.y() - pos.y());
+
+ qDebug() << "updating: " << dx << dy;
+ style()->setRadiusX(dx);
+ style()->setRadiusY(dy);
+}
+
// kate: indent-width 4; replace-tabs on;
diff --git a/qtikzgui/paths/ellipse/TikzEllipsePath.h b/qtikzgui/paths/ellipse/TikzEllipsePath.h
index 3ece25c..32e788d 100644
--- a/qtikzgui/paths/ellipse/TikzEllipsePath.h
+++ b/qtikzgui/paths/ellipse/TikzEllipsePath.h
@@ -32,7 +32,7 @@ namespace tikz {
class QPainter;
-class CurveHandle;
+class PathHandle;
class TikzDocument;
class TikzNode;
class TikzPath;
@@ -138,13 +138,31 @@ class TikzEllipsePath : public AbstractTikzPath
*/
void updateNode(tikz::Node * node);
- private:
+ private Q_SLOTS:
/**
* Updates the cache of the ellipse.
*/
void updateCache();
/**
+ * Show / hide resize, move and rotate handles according to @p show.
+ */
+ void setShowHandles(bool show);
+
+ /**
+ * set the handle positions.
+ */
+ void updateHandlePositions();
+
+ /**
+ * This slot is called whenever a handle moved.
+ * The ellipse then is either moved, resized or rotated according to
+ * the sender @p handle.
+ */
+ void handleMoved(PathHandle * handle, const QPointF & pos);
+
+ private:
+ /**
* Returns the tikz::Path object, casted to tikz::EllipsePath
*/
tikz::EllipsePath * ellipsePath() const;
@@ -171,15 +189,15 @@ class TikzEllipsePath : public AbstractTikzPath
QRectF m_boundingRect;
private:
- CurveHandle * m_topLeft;
- CurveHandle * m_top;
- CurveHandle * m_topRight;
- CurveHandle * m_left;
- CurveHandle * m_center;
- CurveHandle * m_right;
- CurveHandle * m_bottomLeft;
- CurveHandle * m_bottom;
- CurveHandle * m_bottomRight;
+ PathHandle * m_topLeft;
+ PathHandle * m_top;
+ PathHandle * m_topRight;
+ PathHandle * m_left;
+ PathHandle * m_center;
+ PathHandle * m_right;
+ PathHandle * m_bottomLeft;
+ PathHandle * m_bottom;
+ PathHandle * m_bottomRight;
};
#endif // GUI_TIKZ_ELLIPSE_PATH_H
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic