Prepare new maemo release
[maemo-rb.git] / utils / themeeditor / graphics / rbmovable.cpp
blob1507c77a7183be294d20043daba3b00e59f47f7a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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>
23 #include <QPainter>
24 #include <QDebug>
26 #include <cmath>
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,
43 QWidget *widget)
45 if(isSelected())
47 painter->setBrush(Qt::NoBrush);
48 QPen pen;
49 pen.setStyle(Qt::DashLine);
50 pen.setColor(Qt::green);
51 painter->setPen(pen);
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()));
75 return pos;
78 return QGraphicsItem::itemChange(change, value);
81 void RBMovable::mousePressEvent(QGraphicsSceneMouseEvent *event)
83 if(!isSelected())
85 QGraphicsItem::mousePressEvent(event);
86 return;
89 if(topLeftHandle().contains(event->pos()))
91 dragStartClick = event->pos() + pos();
92 dragStartPos = 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();
101 dragMode = TopLeft;
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());
118 dragMode = TopRight;
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;
156 else
158 QGraphicsItem::mousePressEvent(event);
162 void RBMovable::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
165 QPointF absPos;
166 QPointF dPos;
167 QPointF dMouse;
168 switch(dragMode)
170 case None:
171 QGraphicsItem::mouseMoveEvent(event);
172 break;
174 case TopLeft:
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());
193 break;
195 case TopRight:
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());
214 break;
216 case BottomLeft:
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());
233 break;
235 case BottomRight:
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());
252 break;
256 void RBMovable::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
258 QGraphicsItem::mouseReleaseEvent(event);
260 dragMode = None;
262 if(isSelected())
264 saveGeometry();
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);