QColor color, HandleItem
::HandleRole role,
{
m_role = role;
m_color = color;
m_item = item;
m_handles = handles;
m_pressed = false;
setZValue( 100 );
setFlag( ItemIsMovable );
}
QRectF HandleItem
::boundingRect() const {
QPointF point
= m_item
->boundingRect
().
center();
switch( m_role ){
case CenterHandle:
case RightHandle:
point.setX( m_item->boundingRect().right() );
case TopHandle:
point.setY( m_item->boundingRect().top() );
}
}
{
paint->setPen( m_color );
paint->setBrush( m_color );
QVector<QPointF> points;
switch( m_role ){
case CenterHandle:
paint->drawEllipse( rect );
break;
case RightHandle:
paint
->drawConvexPolygon
( QPolygonF(points
) );
break;
case TopHandle:
paint
->drawConvexPolygon
( QPolygonF(points
) );
break;
}
}
{
m_pressed = true;
}
{
m_pressed = false;
}
QVariant HandleItem
::itemChange( GraphicsItemChange change,
const QVariant &data
) {
if( change == ItemPositionChange && m_pressed ){
QPointF movement
= data.
toPoint() - pos
();
QPointF center
= m_item
->boundingRect
().
center();
switch( m_role ){
case CenterHandle:
m_item->moveBy( movement.x(), movement.y() );
foreach( HandleItem *handle, m_handles )
handle->translate( movement.x(), movement.y() );
break;
case TopHandle:
if( -2*movement.y() + m_item->sceneBoundingRect().height() <= 5 )
movement.setX( 0 );
m_item->translate( center.x(), center.y() );
m_item->scale( 1, 1.0-2.0*movement.y() /(m_item->sceneBoundingRect().height()) );
m_item->translate( -center.x(), -center.y() );
break;
case RightHandle:
if( 2*movement.x() + m_item->sceneBoundingRect().width() <= 5 )
movement.setY( 0 );
m_item->translate( center.x(), center.y() );
m_item->scale( 1.0+2.0*movement.x()/(m_item->sceneBoundingRect().width()), 1 );
m_item->translate( -center.x(), -center.y() );
break;
}
}
}
HandleItem::HandleItem( QGraphicsItem *item, QGraphicsScene *scene,
QColor color, HandleItem::HandleRole role,
QList<HandleItem*> handles ) : QGraphicsItem( 0, scene )
{
m_role = role;
m_color = color;
m_item = item;
m_handles = handles;
m_pressed = false;
setZValue( 100 );
setFlag( ItemIsMovable );
}
QRectF HandleItem::boundingRect() const
{
QPointF point = m_item->boundingRect().center();
switch( m_role ){
case CenterHandle:
return QRectF( point-QPointF(5, 5), QSize( 10, 10 ) );
case RightHandle:
point.setX( m_item->boundingRect().right() );
return QRectF( point-QPointF(3, 5), QSize( 6, 10 ) );
case TopHandle:
point.setY( m_item->boundingRect().top() );
return QRectF( point-QPointF(5, 3), QSize( 10, 6 ) );
}
return QRectF();
}
void HandleItem::paint( QPainter *paint, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
paint->setPen( m_color );
paint->setBrush( m_color );
QRectF rect = boundingRect();
QVector<QPointF> points;
switch( m_role ){
case CenterHandle:
paint->drawEllipse( rect );
break;
case RightHandle:
points << rect.center()+QPointF(3,0) << rect.center()+QPointF(-3,-5) << rect.center()+QPointF(-3,5);
paint->drawConvexPolygon( QPolygonF(points) );
break;
case TopHandle:
points << rect.center()+QPointF(0,-3) << rect.center()+QPointF(-5,3) << rect.center()+QPointF(5,3);
paint->drawConvexPolygon( QPolygonF(points) );
break;
}
}
void HandleItem::mousePressEvent( QGraphicsSceneMouseEvent *event )
{
m_pressed = true;
QGraphicsItem::mousePressEvent( event );
}
void HandleItem::mouseReleaseEvent( QGraphicsSceneMouseEvent *event )
{
m_pressed = false;
QGraphicsItem::mouseReleaseEvent( event );
}
QVariant HandleItem::itemChange( GraphicsItemChange change, const QVariant &data )
{
if( change == ItemPositionChange && m_pressed ){
QPointF movement = data.toPoint() - pos();
QPointF center = m_item->boundingRect().center();
switch( m_role ){
case CenterHandle:
m_item->moveBy( movement.x(), movement.y() );
foreach( HandleItem *handle, m_handles )
handle->translate( movement.x(), movement.y() );
break;
case TopHandle:
if( -2*movement.y() + m_item->sceneBoundingRect().height() <= 5 )
return QGraphicsItem::itemChange( change, pos() );
movement.setX( 0 );
m_item->translate( center.x(), center.y() );
m_item->scale( 1, 1.0-2.0*movement.y() /(m_item->sceneBoundingRect().height()) );
m_item->translate( -center.x(), -center.y() );
break;
case RightHandle:
if( 2*movement.x() + m_item->sceneBoundingRect().width() <= 5 )
return QGraphicsItem::itemChange( change, pos() );
movement.setY( 0 );
m_item->translate( center.x(), center.y() );
m_item->scale( 1.0+2.0*movement.x()/(m_item->sceneBoundingRect().width()), 1 );
m_item->translate( -center.x(), -center.y() );
break;
}
return QGraphicsItem::itemChange( change, pos()+movement );
}
return QGraphicsItem::itemChange( change, data );
}
To copy to clipboard, switch view to plain text mode
class:
{
public:
enum HandleRole { CenterHandle, RightHandle, TopHandle };
QColor color, HandleRole role
= CenterHandle,
QList<HandleItem*> handles = QList<HandleItem*>() );
protected:
private:
HandleRole m_role;
QList<HandleItem*> m_handles;
bool m_pressed;
};
class HandleItem : public QGraphicsItem
{
public:
enum HandleRole { CenterHandle, RightHandle, TopHandle };
HandleItem( QGraphicsItem *item, QGraphicsScene *scene,
QColor color, HandleRole role = CenterHandle,
QList<HandleItem*> handles = QList<HandleItem*>() );
void paint( QPainter *paint, const QStyleOptionGraphicsItem *option, QWidget *widget );
QRectF boundingRect() const;
protected:
void mousePressEvent( QGraphicsSceneMouseEvent *event );
void mouseReleaseEvent( QGraphicsSceneMouseEvent *event );
QVariant itemChange( GraphicsItemChange change, const QVariant &data );
private:
QGraphicsItem *m_item;
HandleRole m_role;
QColor m_color;
QList<HandleItem*> m_handles;
bool m_pressed;
};
To copy to clipboard, switch view to plain text mode
It is OK, but I dont know how translate coordition system to my item has CenterHandle, TopHandle and RightHandle at same pocition...
Bookmarks