Developer Documentation
arrow.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 //== INCLUDES =================================================================
51 
52 #include <QPainterPath>
53 #include <QGraphicsItem>
54 #include <QGraphicsSceneMouseEvent>
55 
57 
58 #include "arrow.hh"
59 #include "graphicsScene.hh"
60 
61 //== NAMESPACES ===============================================================
62 namespace VSI {
63 
64 //=============================================================================
65 //
66 // CLASS VSI::Arrow - IMPLEMENTATION
67 //
68 //=============================================================================
69 
70 
72 Arrow::Arrow (GraphicsScene *_scene, QGraphicsItem *_parent, Direction _dir) :
73  QGraphicsPixmapItem (_parent),
74  scene_ (_scene),
75  dir_ (_dir),
76  highlight_ (false)
77 {
78  // load icon depending on direction
79  switch (_dir)
80  {
81  case North:
82  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-up.png");
83  break;
84  case South:
85  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-down.png");
86  break;
87  case East:
88  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-right.png");
89  break;
90  case West:
91  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-left.png");
92  break;
93  case Center:
94  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-center.png");
95  break;
96  }
97 
98  setOpacity ((highlight_)? 0.5 : 0.2);
99 
100  setAcceptHoverEvents (true);
101 
102  connect (&timer_, SIGNAL (timeout ()), this, SLOT (timeout ()));
103 }
104 
105 //------------------------------------------------------------------------------
106 
109 {
110 }
111 
112 //------------------------------------------------------------------------------
113 
114 // make the widget opaque if the mouse is over it
115 void Arrow::hoverEnterEvent (QGraphicsSceneHoverEvent * /*_event*/)
116 {
117  setOpacity (1.0);
118 }
119 
120 //------------------------------------------------------------------------------
121 
122 // make the widget transparent if the mouse leaves it
123 void Arrow::hoverLeaveEvent (QGraphicsSceneHoverEvent * /*_event*/)
124 {
125  setOpacity ((highlight_)? 0.5 : 0.2);
126 }
127 
128 //------------------------------------------------------------------------------
129 
130 // move the scene on mouse press
131 void Arrow::mousePressEvent (QGraphicsSceneMouseEvent *_event)
132 {
133  _event->accept ();
134 
135  qreal dx = 0.0, dy = 0.0;
136 
137  switch (dir_)
138  {
139  case North:
140  dy = 5;
141  break;
142  case South:
143  dy = -5;
144  break;
145  case East:
146  dx = -5;
147  break;
148  case West:
149  dx = 5;
150  break;
151  case Center:
152  {
153  QRectF bb = scene_->elementsBoundingRect ();
154  QRectF rect = scene_->sceneRect();
155  dx = qMax (qMin ((rect.center () - bb.center ()).x (), 5.0), -5.0);
156  dy = qMax (qMin ((rect.center () - bb.center ()).y (), 5.0), -5.0);
157  }
158  break;
159  }
160  scene_->moveElements (dx, dy, true);
161 
162  // start timer for movement during the mouse is pressed
163  timer_.start (500);
164  moveSelected_ = true;
165 }
166 
167 //------------------------------------------------------------------------------
168 
169 // stop movement on release
170 void Arrow::mouseReleaseEvent (QGraphicsSceneMouseEvent *_event)
171 {
172  _event->accept ();
173  timer_.stop ();
174 }
175 
176 //------------------------------------------------------------------------------
177 
178 // move on mouse wheel
179 void Arrow::wheelEvent (QGraphicsSceneWheelEvent *_event)
180 {
181  _event->accept ();
182 
183  qreal dx = 0.0, dy = 0.0;
184 
185  switch (dir_)
186  {
187  case North:
188  case South:
189  dy = 1;
190  break;
191  case East:
192  case West:
193  dx = 1;
194  break;
195  case Center:
196  break;
197  }
198  dx *= _event->delta () / 4;
199  dy *= _event->delta () / 4;
200  scene_->moveElements (dx, dy, true);
201 }
202 
203 //------------------------------------------------------------------------------
204 
205 // move the scene on timeout and decrease timer interval for faster movement
206 void Arrow::timeout ()
207 {
208  if (timer_.interval () == 500)
209  interval_ = 50;
210  timer_.setInterval (interval_ );
211  if (interval_ > 5)
212  interval_--;
213 
214  qreal dx = 0.0, dy = 0.0;
215 
216  switch (dir_)
217  {
218  case North:
219  dy = 1;
220  break;
221  case South:
222  dy = -1;
223  break;
224  case East:
225  dx = -1;
226  break;
227  case West:
228  dx = 1;
229  break;
230  case Center:
231  {
232  QRectF bb = scene_->elementsBoundingRect ();
233  QRectF rect = scene_->sceneRect();
234  dx = qMax (qMin ((rect.center () - bb.center ()).x (), 2.0), -2.0);
235  dy = qMax (qMin ((rect.center () - bb.center ()).y (), 2.0), -2.0);
236  }
237  break;
238  }
239  scene_->moveElements (dx, dy, moveSelected_);
240 }
241 
242 //------------------------------------------------------------------------------
243 
246 {
247  setOpacity (1.0);
248  moveSelected_ = false;
249  if (!timer_.isActive ())
250  timer_.start (500);
251 }
252 
253 //------------------------------------------------------------------------------
254 
257 {
258  setOpacity ((highlight_)? 0.5 : 0.2);
259  timer_.stop ();
260 }
261 
262 //------------------------------------------------------------------------------
263 
264 // set geometry
265 void Arrow::setGeometry (const QRectF &_rect)
266 {
267  QGraphicsPixmapItem::setPos (_rect.topLeft ());
268  QGraphicsLayoutItem::setGeometry (_rect);
269 }
270 
271 //------------------------------------------------------------------------------
272 
273 // return size information for layouting
274 QSizeF Arrow::sizeHint (Qt::SizeHint _which, const QSizeF &/*_constraint*/) const
275 {
276  QSizeF sh;
277  switch (_which) {
278  case Qt::MinimumSize:
279  case Qt::PreferredSize:
280  case Qt::MaximumSize:
281  sh = QSizeF (pixmap ().width (), pixmap ().height ());
282  break;
283  default:
284  break;
285  }
286 
287  return sh;
288 }
289 
290 //------------------------------------------------------------------------------
291 
293 void Arrow::setHighlight (bool _highlight)
294 {
295  highlight_ = _highlight;
296 
297  if (opacity () != 1.0)
298  setOpacity ((highlight_)? 0.5 : 0.2);
299 
300 }
301 
302 //------------------------------------------------------------------------------
303 }
304 
void reset()
Stop the timer.
Definition: arrow.cc:256
virtual void setGeometry(const QRectF &_rect)
Sets the geometry.
Definition: arrow.cc:265
QRectF elementsBoundingRect()
Bounding rectangle of all scene elements.
void activate()
Activates the timer for movement (will be called if an element is moved above)
Definition: arrow.cc:245
Arrow(GraphicsScene *_scene, QGraphicsItem *_parent, Direction _dir)
Constructor.
Definition: arrow.cc:72
void setHighlight(bool _highlight)
Highlights the widget if the scene can be moved in this direction.
Definition: arrow.cc:293
~Arrow()
Destructor.
Definition: arrow.cc:108
void moveElements(qreal _dx, qreal _dy, bool _selected=false)
Moves all elements.
Direction
Movement direction.
Definition: arrow.hh:76