{
enum Handle{None = -1, TL, T, TR, R, BR, B, BL, L, NrOfHandles};
Handle _selectedItem;
public:
ResizeItem()
: _selectedItem(None)
{
for(int i = 0;i<NrOfHandles;i++)
{
handles[i]->setFlags(ItemIgnoresTransformations);
handles[i]->setPen(Qt::NoPen);
handles[i]->setBrush(Qt::black);
}
handles
[TL
]->setCursor
(QCursor(Qt
::SizeFDiagCursor));
handles
[T
]->setCursor
(QCursor(Qt
::SizeVerCursor));
handles
[TR
]->setCursor
(QCursor(Qt
::SizeBDiagCursor));
handles
[R
]->setCursor
(QCursor(Qt
::SizeHorCursor));
handles
[BR
]->setCursor
(QCursor(Qt
::SizeFDiagCursor));
handles
[B
]->setCursor
(QCursor(Qt
::SizeVerCursor));
handles
[BL
]->setCursor
(QCursor(Qt
::SizeBDiagCursor));
handles
[L
]->setCursor
(QCursor(Qt
::SizeHorCursor));
hide();
}
protected:
{
if (change == ItemParentChange && scene())
{
QGraphicsRectItem* rectItem
= qgraphicsitem_cast<QGraphicsRectItem
*>
(value.
value<QGraphicsItem
*>
());
if(rectItem==0){
hide();
return 0;
}
repositionChildren(rectItem->rect());
show();
}
}
void repositionChildren
(QRectF rect
) {
handles[TL]->setPos(rect.left(), rect.top());
handles[T ]->setPos(rect.center().x(), rect.top());
handles[TR]->setPos(rect.right(), rect.top());
handles[R ]->setPos(rect.right(), rect.center().y());
handles[BR]->setPos(rect.right(), rect.bottom());
handles[B ]->setPos(rect.center().x(), rect.bottom());
handles[BL]->setPos(rect.left(), rect.bottom());
handles[L ]->setPos(rect.left(), rect.center().y());
}
{
// Find out which handle was clicked
int minDist = 10000000;
int closestHandle = None;
for(int i = 0;i<NrOfHandles;i++)
{
int dist = (event->pos()-handles[i]->pos()).manhattanLength();
if(dist<minDist)
{
closestHandle = i;
minDist = dist;
}
}
_selectedItem = (Handle)closestHandle;
event->accept();
}
{
if(rectItem==0)
return;
QRectF rect
= rectItem
->rect
();
QPointF pos
= event
->scenePos
()-scenePos
();
if(_selectedItem==TR || _selectedItem==R || _selectedItem==BR)
rect.setRight(qMax(rect.left(), pos.x()));
else if(_selectedItem==TL || _selectedItem==L || _selectedItem==BL)
rect.setLeft(qMin(rect.right(), pos.x()));
if(_selectedItem==BL || _selectedItem==B || _selectedItem==BR)
rect.setBottom(qMax(rect.top(), pos.y()));
else if(_selectedItem==TL || _selectedItem==T || _selectedItem==TR)
rect.setTop(qMin(rect.bottom(), pos.y()));
rectItem->setRect(rect);
repositionChildren(rectItem->boundingRect());
}
{
_selectedItem=None;
}
};
class ResizeItem : public QGraphicsItemGroup
{
enum Handle{None = -1, TL, T, TR, R, BR, B, BL, L, NrOfHandles};
QGraphicsRectItem* handles[NrOfHandles];
Handle _selectedItem;
public:
ResizeItem()
: _selectedItem(None)
{
for(int i = 0;i<NrOfHandles;i++)
{
handles[i] = new QGraphicsRectItem(QRectF(-2,-2,5,5), this);
handles[i]->setFlags(ItemIgnoresTransformations);
handles[i]->setPen(Qt::NoPen);
handles[i]->setBrush(Qt::black);
}
handles[TL]->setCursor(QCursor(Qt::SizeFDiagCursor));
handles[T ]->setCursor(QCursor(Qt::SizeVerCursor));
handles[TR]->setCursor(QCursor(Qt::SizeBDiagCursor));
handles[R ]->setCursor(QCursor(Qt::SizeHorCursor));
handles[BR]->setCursor(QCursor(Qt::SizeFDiagCursor));
handles[B ]->setCursor(QCursor(Qt::SizeVerCursor));
handles[BL]->setCursor(QCursor(Qt::SizeBDiagCursor));
handles[L ]->setCursor(QCursor(Qt::SizeHorCursor));
hide();
}
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemParentChange && scene())
{
QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(value.value<QGraphicsItem*>());
if(rectItem==0){
hide();
return 0;
}
repositionChildren(rectItem->rect());
show();
}
return QGraphicsItem::itemChange(change, value);
}
void repositionChildren(QRectF rect)
{
handles[TL]->setPos(rect.left(), rect.top());
handles[T ]->setPos(rect.center().x(), rect.top());
handles[TR]->setPos(rect.right(), rect.top());
handles[R ]->setPos(rect.right(), rect.center().y());
handles[BR]->setPos(rect.right(), rect.bottom());
handles[B ]->setPos(rect.center().x(), rect.bottom());
handles[BL]->setPos(rect.left(), rect.bottom());
handles[L ]->setPos(rect.left(), rect.center().y());
}
void mousePressEvent ( QGraphicsSceneMouseEvent * event )
{
// Find out which handle was clicked
int minDist = 10000000;
int closestHandle = None;
for(int i = 0;i<NrOfHandles;i++)
{
int dist = (event->pos()-handles[i]->pos()).manhattanLength();
if(dist<minDist)
{
closestHandle = i;
minDist = dist;
}
}
_selectedItem = (Handle)closestHandle;
event->accept();
}
void mouseMoveEvent ( QGraphicsSceneMouseEvent * event )
{
QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(parentItem());
if(rectItem==0)
return;
QRectF rect = rectItem->rect();
QPointF pos = event->scenePos()-scenePos();
if(_selectedItem==TR || _selectedItem==R || _selectedItem==BR)
rect.setRight(qMax(rect.left(), pos.x()));
else if(_selectedItem==TL || _selectedItem==L || _selectedItem==BL)
rect.setLeft(qMin(rect.right(), pos.x()));
if(_selectedItem==BL || _selectedItem==B || _selectedItem==BR)
rect.setBottom(qMax(rect.top(), pos.y()));
else if(_selectedItem==TL || _selectedItem==T || _selectedItem==TR)
rect.setTop(qMin(rect.bottom(), pos.y()));
rectItem->setRect(rect);
repositionChildren(rectItem->boundingRect());
}
void mouseReleaseEvent ( QGraphicsSceneMouseEvent * )
{
_selectedItem=None;
}
};
To copy to clipboard, switch view to plain text mode
main.cpp
#include <QtGui>
// There is one global resize item, which stays hidden most of the time.
ResizeItem* resizeItem;
{
public:
{
setFlags(ItemIsSelectable|ItemIsMovable);
setBrush((Qt::GlobalColor)((qrand()%14)+4));
}
{
// When this item is selected, we grab the resizeItem by calling setParentItem(this)
if (change == ItemSelectedChange)
resizeItem->setParentItem(value.toBool() ? this : 0);
}
};
int main(int argc, char* argv[])
{
scene.setSceneRect(0, 0, 600, 600);
scene.addItem(resizeItem = new ResizeItem);
for(int i=0;i<50;i++)
scene.
addItem(new RectItem
(QRectF(qrand
()%500, qrand
()%500,
100,
100)));
view.setScene(&scene);
view.show();
return app.exec();
}
#include <QtGui>
// There is one global resize item, which stays hidden most of the time.
ResizeItem* resizeItem;
class RectItem : public QGraphicsRectItem
{
public:
RectItem(QRectF rect)
: QGraphicsRectItem(rect)
{
setFlags(ItemIsSelectable|ItemIsMovable);
setBrush((Qt::GlobalColor)((qrand()%14)+4));
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
// When this item is selected, we grab the resizeItem by calling setParentItem(this)
if (change == ItemSelectedChange)
resizeItem->setParentItem(value.toBool() ? this : 0);
return QGraphicsItem::itemChange(change, value);
}
};
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QGraphicsScene scene;
scene.setSceneRect(0, 0, 600, 600);
scene.addItem(resizeItem = new ResizeItem);
for(int i=0;i<50;i++)
scene.addItem(new RectItem(QRectF(qrand()%500, qrand()%500, 100, 100)));
QGraphicsView view;
view.setScene(&scene);
view.show();
return app.exec();
}
To copy to clipboard, switch view to plain text mode
Bookmarks