Skip to content
This repository has been archived by the owner. It is now read-only.

Commit

Permalink
Added roi resize with mouse
Browse files Browse the repository at this point in the history
  • Loading branch information
MPIBR-kretschmerf committed Apr 25, 2017
1 parent cafa5da commit a5c0898
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 20 deletions.
20 changes: 0 additions & 20 deletions NotifyingQGraphicsRectItem.h

This file was deleted.

81 changes: 81 additions & 0 deletions ResizeHelper.cpp
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()));
}
35 changes: 35 additions & 0 deletions ResizeHelper.h
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
39 changes: 39 additions & 0 deletions ResizeTraits.cpp
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);
}
}
15 changes: 15 additions & 0 deletions ResizeTraits.h
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

0 comments on commit a5c0898

Please sign in to comment.