This repository has been archived by the owner. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cafa5da
commit a5c0898
Showing
5 changed files
with
170 additions
and
20 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#include "ResizeHelper.h" | ||
|
||
/// The set of edges intersecting a rectangle of given pen width | ||
QFlags<Qt::Edge> edgesAt(const QPointF & p, const QRectF & r, qreal w) { | ||
QFlags<Qt::Edge> edges; | ||
auto hw = w / 2.0; | ||
if (QRectF(r.x()-hw, r.y()-hw, w, r.height()+w).contains(p)) edges |= Qt::LeftEdge; | ||
if (QRectF(r.x()+r.width()-hw, r.y()-hw, w, r.height()+w).contains(p)) edges |= Qt::RightEdge; | ||
if (QRectF(r.x()-hw, r.y()-hw, r.width()+w, w).contains(p)) edges |= Qt::TopEdge; | ||
if (QRectF(r.x()-hw, r.y()+r.height()-hw, r.width()+w, w).contains(p)) edges |= Qt::BottomEdge; | ||
return edges; | ||
} | ||
|
||
ResizeHelper::ResizeHelper(QObject *parent) { | ||
setAcceptedMouseButtons(Qt::LeftButton); | ||
m_pen.setColor(QColor(255, 0, 0, 128)); | ||
m_pen.setStyle(Qt::SolidLine); | ||
} | ||
|
||
QRectF ResizeHelper::boundingRect() const { | ||
auto hWidth = m_pen.widthF()/2.0; | ||
return m_rect.adjusted(-hWidth, -hWidth, hWidth, hWidth); | ||
} | ||
|
||
void ResizeHelper::selectionChanged() { | ||
if (!scene()) { setVisible(false); return; } | ||
auto sel = scene()->selectedItems(); | ||
if (sel.isEmpty() || sel.size() > 1) { setVisible(false); return; } | ||
auto item = sel.at(0); | ||
if (! traits.isGraphicsItemResizeable(item)) { setVisible(false); return; } | ||
setParentItem(item); | ||
newGeometry(); | ||
setVisible(true); | ||
} | ||
|
||
void ResizeHelper::paint(QPainter * p, const QStyleOptionGraphicsItem *, QWidget *) { | ||
p->setPen(m_pen); | ||
p->drawRect(m_rect); | ||
} | ||
|
||
void ResizeHelper::mousePressEvent(QGraphicsSceneMouseEvent * ev) { | ||
m_edges = edgesAt(ev->pos(), m_rect, m_pen.widthF()); | ||
if (!m_edges){ /*Moving: Store click location | ||
//ev->ignore(); /*Ignore if moved*/ | ||
clickPos = ev->pos(); | ||
} | ||
ev->accept(); | ||
} | ||
|
||
void ResizeHelper::mouseMoveEvent(QGraphicsSceneMouseEvent * ev) { | ||
auto pos = mapToItem(parentItem(), ev->pos()); | ||
auto rect = traits.rectFor(parentItem()); | ||
|
||
if (m_edges & Qt::LeftEdge) rect.setLeft(pos.x()); | ||
if (m_edges & Qt::TopEdge) rect.setTop(pos.y()); | ||
if (m_edges & Qt::RightEdge) rect.setRight(pos.x()); | ||
if (m_edges & Qt::BottomEdge) rect.setBottom(pos.y()); | ||
if (!!m_edges) { | ||
traits.setRectOn(parentItem(), rect); | ||
newGeometry(); | ||
}else{ /*Moving*/ | ||
QPointF d = clickPos - ev->pos(); | ||
rect.setLeft(rect.left()-d.x()); | ||
rect.setTop(rect.top()-d.y()); | ||
rect.setRight(rect.right()-d.x()); | ||
rect.setBottom(rect.bottom()-d.y()); | ||
traits.setRectOn(parentItem(), rect); | ||
newGeometry(); | ||
clickPos = ev->pos(); | ||
} | ||
} | ||
|
||
void ResizeHelper::newGeometry() { | ||
prepareGeometryChange(); | ||
auto parentRect = traits.rectFor(parentItem()); | ||
m_rect.setTopLeft(mapFromParent(parentRect.topLeft())); | ||
m_rect.setBottomRight(mapFromParent(parentRect.bottomRight())); | ||
m_pen.setWidthF(std::min(m_rect.width(), m_rect.height()) * 0.1); | ||
m_pen.setJoinStyle(Qt::MiterJoin); | ||
emit(itemChanged(parentItem())); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#ifndef ResizeHelper_H | ||
#define ResizeHelper_H | ||
|
||
#include <QObject> | ||
#include <QGraphicsObject> | ||
#include <QPen> | ||
#include <QPainter> | ||
#include <QGraphicsScene> | ||
#include <QGraphicsSceneMouseEvent> | ||
#include <ResizeTraits.h> | ||
#include <QDebug> | ||
|
||
class ResizeHelper : public QGraphicsObject | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
ResizeTraits traits; | ||
QRectF m_rect; | ||
QPen m_pen; | ||
QPointF clickPos; | ||
QFlags<Qt::Edge> m_edges; | ||
ResizeHelper(QObject *parent = 0); | ||
QRectF boundingRect() const Q_DECL_OVERRIDE; | ||
void newGeometry(); | ||
void paint(QPainter * p, const QStyleOptionGraphicsItem *, QWidget *); | ||
void mousePressEvent(QGraphicsSceneMouseEvent * ev) Q_DECL_OVERRIDE; | ||
void mouseMoveEvent(QGraphicsSceneMouseEvent * ev) Q_DECL_OVERRIDE; | ||
signals: | ||
void itemChanged(QGraphicsItem* item); | ||
public slots: | ||
void selectionChanged(); | ||
}; | ||
|
||
#endif // ResizeHelper_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#include "ResizeTraits.h" | ||
|
||
/// Determines whether an item is manually resizeable. | ||
bool ResizeTraits::isGraphicsItemResizeable(QGraphicsItem * item) { | ||
auto resizeableItem1 = dynamic_cast<QGraphicsEllipseItem*>(item); | ||
if(resizeableItem1){ | ||
return resizeableItem1; | ||
} | ||
auto resizeableItem2 = dynamic_cast<QGraphicsRectItem*>(item); | ||
if(resizeableItem2){ | ||
return resizeableItem2; | ||
} | ||
return false; | ||
} | ||
|
||
/// Gives the rectangle one can base the resize operations on for an item | ||
QRectF ResizeTraits::rectFor(QGraphicsItem * item) { | ||
auto resizeableItem1 = dynamic_cast<QGraphicsEllipseItem*>(item); | ||
if(resizeableItem1){ | ||
return resizeableItem1->rect(); | ||
} | ||
auto resizeableItem2 = dynamic_cast<QGraphicsRectItem*>(item); | ||
if(resizeableItem2){ | ||
return resizeableItem2->rect(); | ||
} | ||
return QRectF(); | ||
} | ||
|
||
/// Sets a new rectangle on the item | ||
void ResizeTraits::setRectOn(QGraphicsItem * item, const QRectF & rect) { | ||
auto resizeableItem1 = dynamic_cast<QGraphicsEllipseItem*>(item); | ||
if (resizeableItem1){ | ||
return resizeableItem1->setRect(rect); | ||
} | ||
auto resizeableItem2 = dynamic_cast<QGraphicsRectItem*>(item); | ||
if (resizeableItem2){ | ||
return resizeableItem2->setRect(rect); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#ifndef SIMPLETRAITS_H | ||
#define SIMPLETRAITS_H | ||
#include <QGraphicsItem> | ||
#include <QRectF> | ||
|
||
class SimpleTraits | ||
{ | ||
public: | ||
static bool isGraphicsItemResizeable(QGraphicsItem * item); | ||
static QRectF rectFor(QGraphicsItem * item); | ||
static void setRectOn(QGraphicsItem * item, const QRectF & rect); | ||
|
||
}; | ||
|
||
#endif // SIMPLETRAITS_H |