1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Robert Bieber
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include <QGraphicsSceneMouseEvent>
28 #include "rbmovable.h"
30 const double RBMovable::handleSize
= 7;
32 RBMovable::RBMovable(QGraphicsItem
* parent
)
33 : QGraphicsItem(parent
), dragMode(None
)
35 setFlags(ItemIsMovable
| ItemIsSelectable
| ItemSendsGeometryChanges
);
38 RBMovable::~RBMovable()
42 void RBMovable::paint(QPainter
*painter
, const QStyleOptionGraphicsItem
*option
,
47 painter
->setBrush(Qt::NoBrush
);
49 pen
.setStyle(Qt::DashLine
);
50 pen
.setColor(Qt::green
);
52 painter
->drawRect(boundingRect());
54 painter
->fillRect(topLeftHandle(), Qt::green
);
55 painter
->fillRect(topRightHandle(), Qt::green
);
56 painter
->fillRect(bottomLeftHandle(), Qt::green
);
57 painter
->fillRect(bottomRightHandle(), Qt::green
);
61 QVariant
RBMovable::itemChange(GraphicsItemChange change
, const QVariant
&value
)
63 if(change
== ItemPositionChange
)
65 QPointF pos
= value
.toPointF();
66 QRectF bound
= parentItem()->boundingRect();
68 pos
.setX(qMax(0., floor(pos
.x())));
69 pos
.setX(qMin(pos
.x(), bound
.width() - boundingRect().width()));
71 pos
.setY(qMax(0., floor(pos
.y())));
72 pos
.setY(qMin(pos
.y(), bound
.height() - boundingRect().height()));
78 return QGraphicsItem::itemChange(change
, value
);
81 void RBMovable::mousePressEvent(QGraphicsSceneMouseEvent
*event
)
85 QGraphicsItem::mousePressEvent(event
);
89 if(topLeftHandle().contains(event
->pos()))
91 dragStartClick
= event
->pos() + pos();
93 dragStartSize
= boundingRect();
95 dWidthMin
= -1. * pos().x();
96 dWidthMax
= boundingRect().width() - childrenBoundingRect().right();
98 dHeightMin
= -1. * pos().y();
99 dHeightMax
= boundingRect().height() - childrenBoundingRect().bottom();
103 else if(topRightHandle().contains(event
->pos()))
105 dragStartClick
= event
->pos() + pos();
106 dragStartPos
= pos();
107 dragStartSize
= boundingRect();
109 dWidthMin
= childrenBoundingRect().width() - boundingRect().width();
110 dWidthMin
= qMax(dWidthMin
, -1. * size
.width());
111 dWidthMax
= parentItem()->boundingRect().width()
112 - boundingRect().width() - pos().x();
114 dHeightMin
= -1. * pos().y();
115 dHeightMax
= boundingRect().height() - childrenBoundingRect().bottom();
116 dHeightMax
= qMin(dHeightMax
, boundingRect().height());
120 else if(bottomLeftHandle().contains(event
->pos()))
122 dragStartClick
= event
->pos() + pos();
123 dragStartPos
= pos();
124 dragStartSize
= boundingRect();
126 dWidthMin
= -1. * pos().x();
127 dWidthMax
= boundingRect().width() - childrenBoundingRect().right();
128 dWidthMax
= qMin(dWidthMax
, size
.width());
130 dHeightMin
= -1. * (boundingRect().height()
131 - childrenBoundingRect().bottom());
132 dHeightMin
= qMax(dHeightMin
, -1. * boundingRect().height());
134 dragMode
= BottomLeft
;
136 else if(bottomRightHandle().contains(event
->pos()))
138 dragStartClick
= event
->pos() + pos();
139 dragStartPos
= pos();
140 dragStartSize
= boundingRect();
142 dWidthMin
= -1. * (boundingRect().width()
143 - childrenBoundingRect().right());
144 dWidthMin
= qMax(dWidthMin
, -1. * boundingRect().width());
145 dWidthMax
= parentItem()->boundingRect().width() -
146 boundingRect().width() - pos().x();
148 dHeightMin
= -1. * (boundingRect().height()
149 - childrenBoundingRect().bottom());
150 dHeightMin
= qMax(dHeightMin
, -1. * boundingRect().height());
151 dHeightMax
= parentItem()->boundingRect().height() -
152 boundingRect().height() - pos().y();
154 dragMode
= BottomRight
;
158 QGraphicsItem::mousePressEvent(event
);
162 void RBMovable::mouseMoveEvent(QGraphicsSceneMouseEvent
*event
)
171 QGraphicsItem::mouseMoveEvent(event
);
175 /* Dragging from the top left corner */
176 absPos
= event
->pos() + pos();
177 dMouse
= QPointF(floor(absPos
.x() - dragStartClick
.x()),
178 floor(absPos
.y() - dragStartClick
.y()));
180 dPos
.setX(qMin(dMouse
.x(), dWidthMax
));
181 dPos
.setX(qMax(dPos
.x(), dWidthMin
));
183 dPos
.setY(qMin(dMouse
.y(), dHeightMax
));
184 dPos
.setY(qMax(dPos
.y(), dHeightMin
));
186 prepareGeometryChange();
188 setPos(dragStartPos
+ dPos
);
190 size
.setWidth(dragStartSize
.width() - dPos
.x());
191 size
.setHeight(dragStartSize
.height() - dPos
.y());
196 /* Dragging from the top right corner */
197 absPos
= event
->pos() + pos();
198 dMouse
= QPointF(floor(absPos
.x() - dragStartClick
.x()),
199 floor(absPos
.y() - dragStartClick
.y()));
201 dPos
.setX(qMin(dMouse
.x(), dWidthMax
));
202 dPos
.setX(qMax(dPos
.x(), dWidthMin
));
204 dPos
.setY(qMin(dMouse
.y(), dHeightMax
));
205 dPos
.setY(qMax(dPos
.y(), dHeightMin
));
207 prepareGeometryChange();
209 setPos(dragStartPos
.x(), dragStartPos
.y() + dPos
.y());
211 size
.setWidth(dragStartSize
.width() + dPos
.x());
212 size
.setHeight(dragStartSize
.height() - dPos
.y());
217 /* Dragging from the bottom left corner */
218 absPos
= event
->pos() + pos();
219 dMouse
= QPointF(floor(absPos
.x() - dragStartClick
.x()),
220 floor(absPos
.y() - dragStartClick
.y()));
222 dPos
.setX(qMin(dMouse
.x(), dWidthMax
));
223 dPos
.setX(qMax(dPos
.x(), dWidthMin
));
225 dPos
.setY(qMin(dMouse
.y(), dHeightMax
));
226 dPos
.setY(qMax(dPos
.y(), dHeightMin
));
228 prepareGeometryChange();
229 setPos(dragStartPos
.x() + dPos
.x(), dragStartPos
.y());
230 size
.setHeight(dragStartSize
.height() + dPos
.y());
231 size
.setWidth(dragStartSize
.width() - dPos
.x());
236 /* Dragging from the bottom right corner */
237 absPos
= event
->pos() + pos();
238 dMouse
= QPointF(floor(absPos
.x() - dragStartClick
.x()),
239 floor(absPos
.y() - dragStartClick
.y()));
241 dPos
.setX(qMin(dMouse
.x(), dWidthMax
));
242 dPos
.setX(qMax(dPos
.x(), dWidthMin
));
244 dPos
.setY(qMin(dMouse
.y(), dHeightMax
));
245 dPos
.setY(qMax(dPos
.y(), dHeightMin
));
247 prepareGeometryChange();
249 size
.setWidth(dragStartSize
.width() + dPos
.x());
250 size
.setHeight(dragStartSize
.height() + dPos
.y());
256 void RBMovable::mouseReleaseEvent(QGraphicsSceneMouseEvent
*event
)
258 QGraphicsItem::mouseReleaseEvent(event
);
268 QRectF
RBMovable::topLeftHandle()
270 QRectF bounds
= boundingRect();
271 double width
= qMin(bounds
.width() / 2. - .5, handleSize
);
272 double height
= qMin(bounds
.height() / 2. - .5, handleSize
);
273 double size
= qMin(width
, height
);
275 return QRectF(0, 0, size
, size
);
278 QRectF
RBMovable::topRightHandle()
280 QRectF bounds
= boundingRect();
281 double width
= qMin(bounds
.width() / 2. - .5, handleSize
);
282 double height
= qMin(bounds
.height() / 2. - .5, handleSize
);
283 double size
= qMin(width
, height
);
285 return QRectF(bounds
.width() - size
, 0, size
, size
);
288 QRectF
RBMovable::bottomLeftHandle()
290 QRectF bounds
= boundingRect();
291 double width
= qMin(bounds
.width() / 2. - .5, handleSize
);
292 double height
= qMin(bounds
.height() / 2. - .5, handleSize
);
293 double size
= qMin(width
, height
);
295 return QRectF(0, bounds
.height() - size
, size
, size
);
298 QRectF
RBMovable::bottomRightHandle()
300 QRectF bounds
= boundingRect();
301 double width
= qMin(bounds
.width() / 2. - .5, handleSize
);
302 double height
= qMin(bounds
.height() / 2. - .5, handleSize
);
303 double size
= qMin(width
, height
);
305 return QRectF(bounds
.width() - size
, bounds
.height() - size
, size
, size
);