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 //== INCLUDES =================================================================
45 
46 #include <QPainterPath>
47 #include <QGraphicsItem>
48 #include <QGraphicsSceneMouseEvent>
49 
51 
52 #include "arrow.hh"
53 #include "graphicsScene.hh"
54 
55 //== NAMESPACES ===============================================================
56 namespace VSI {
57 
58 //=============================================================================
59 //
60 // CLASS VSI::Arrow - IMPLEMENTATION
61 //
62 //=============================================================================
63 
64 
66 Arrow::Arrow (GraphicsScene *_scene, QGraphicsItem *_parent, Direction _dir) :
67  QGraphicsPixmapItem (_parent),
68  scene_ (_scene),
69  dir_ (_dir),
70  highlight_ (false)
71 {
72  // load icon depending on direction
73  switch (_dir)
74  {
75  case North:
76  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-up.png");
77  break;
78  case South:
79  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-down.png");
80  break;
81  case East:
82  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-right.png");
83  break;
84  case West:
85  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-left.png");
86  break;
87  case Center:
88  setPixmap (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-center.png");
89  break;
90  }
91 
92  setOpacity ((highlight_)? 0.5 : 0.2);
93 
94  setAcceptHoverEvents (true);
95 
96  connect (&timer_, SIGNAL (timeout ()), this, SLOT (timeout ()));
97 }
98 
99 //------------------------------------------------------------------------------
100 
103 {
104 }
105 
106 //------------------------------------------------------------------------------
107 
108 // make the widget opaque if the mouse is over it
109 void Arrow::hoverEnterEvent (QGraphicsSceneHoverEvent * /*_event*/)
110 {
111  setOpacity (1.0);
112 }
113 
114 //------------------------------------------------------------------------------
115 
116 // make the widget transparent if the mouse leaves it
117 void Arrow::hoverLeaveEvent (QGraphicsSceneHoverEvent * /*_event*/)
118 {
119  setOpacity ((highlight_)? 0.5 : 0.2);
120 }
121 
122 //------------------------------------------------------------------------------
123 
124 // move the scene on mouse press
125 void Arrow::mousePressEvent (QGraphicsSceneMouseEvent *_event)
126 {
127  _event->accept ();
128 
129  qreal dx = 0.0, dy = 0.0;
130 
131  switch (dir_)
132  {
133  case North:
134  dy = 5;
135  break;
136  case South:
137  dy = -5;
138  break;
139  case East:
140  dx = -5;
141  break;
142  case West:
143  dx = 5;
144  break;
145  case Center:
146  {
147  QRectF bb = scene_->elementsBoundingRect ();
148  QRectF rect = scene_->sceneRect();
149  dx = qMax (qMin ((rect.center () - bb.center ()).x (), 5.0), -5.0);
150  dy = qMax (qMin ((rect.center () - bb.center ()).y (), 5.0), -5.0);
151  }
152  break;
153  }
154  scene_->moveElements (dx, dy, true);
155 
156  // start timer for movement during the mouse is pressed
157  timer_.start (500);
158  moveSelected_ = true;
159 }
160 
161 //------------------------------------------------------------------------------
162 
163 // stop movement on release
164 void Arrow::mouseReleaseEvent (QGraphicsSceneMouseEvent *_event)
165 {
166  _event->accept ();
167  timer_.stop ();
168 }
169 
170 //------------------------------------------------------------------------------
171 
172 // move on mouse wheel
173 void Arrow::wheelEvent (QGraphicsSceneWheelEvent *_event)
174 {
175  _event->accept ();
176 
177  qreal dx = 0.0, dy = 0.0;
178 
179  switch (dir_)
180  {
181  case North:
182  case South:
183  dy = 1;
184  break;
185  case East:
186  case West:
187  dx = 1;
188  break;
189  case Center:
190  break;
191  }
192  dx *= _event->delta () / 4;
193  dy *= _event->delta () / 4;
194  scene_->moveElements (dx, dy, true);
195 }
196 
197 //------------------------------------------------------------------------------
198 
199 // move the scene on timeout and decrease timer interval for faster movement
200 void Arrow::timeout ()
201 {
202  if (timer_.interval () == 500)
203  interval_ = 50;
204  timer_.setInterval (interval_ );
205  if (interval_ > 5)
206  interval_--;
207 
208  qreal dx = 0.0, dy = 0.0;
209 
210  switch (dir_)
211  {
212  case North:
213  dy = 1;
214  break;
215  case South:
216  dy = -1;
217  break;
218  case East:
219  dx = -1;
220  break;
221  case West:
222  dx = 1;
223  break;
224  case Center:
225  {
226  QRectF bb = scene_->elementsBoundingRect ();
227  QRectF rect = scene_->sceneRect();
228  dx = qMax (qMin ((rect.center () - bb.center ()).x (), 2.0), -2.0);
229  dy = qMax (qMin ((rect.center () - bb.center ()).y (), 2.0), -2.0);
230  }
231  break;
232  }
233  scene_->moveElements (dx, dy, moveSelected_);
234 }
235 
236 //------------------------------------------------------------------------------
237 
240 {
241  setOpacity (1.0);
242  moveSelected_ = false;
243  if (!timer_.isActive ())
244  timer_.start (500);
245 }
246 
247 //------------------------------------------------------------------------------
248 
251 {
252  setOpacity ((highlight_)? 0.5 : 0.2);
253  timer_.stop ();
254 }
255 
256 //------------------------------------------------------------------------------
257 
258 // set geometry
259 void Arrow::setGeometry (const QRectF &_rect)
260 {
261  QGraphicsPixmapItem::setPos (_rect.topLeft ());
262  QGraphicsLayoutItem::setGeometry (_rect);
263 }
264 
265 //------------------------------------------------------------------------------
266 
267 // return size information for layouting
268 QSizeF Arrow::sizeHint (Qt::SizeHint _which, const QSizeF &/*_constraint*/) const
269 {
270  QSizeF sh;
271  switch (_which) {
272  case Qt::MinimumSize:
273  case Qt::PreferredSize:
274  case Qt::MaximumSize:
275  sh = QSizeF (pixmap ().width (), pixmap ().height ());
276  break;
277  default:
278  break;
279  }
280 
281  return sh;
282 }
283 
284 //------------------------------------------------------------------------------
285 
287 void Arrow::setHighlight (bool _highlight)
288 {
289  highlight_ = _highlight;
290 
291  if (opacity () != 1.0)
292  setOpacity ((highlight_)? 0.5 : 0.2);
293 
294 }
295 
296 //------------------------------------------------------------------------------
297 }
298 
virtual void setGeometry(const QRectF &_rect)
Sets the geometry.
Definition: arrow.cc:259
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:239
~Arrow()
Destructor.
Definition: arrow.cc:102
void moveElements(qreal _dx, qreal _dy, bool _selected=false)
Moves all elements.
void reset()
Stop the timer.
Definition: arrow.cc:250
Direction
Movement direction.
Definition: arrow.hh:70
Arrow(GraphicsScene *_scene, QGraphicsItem *_parent, Direction _dir)
Constructor.
Definition: arrow.cc:66
void setHighlight(bool _highlight)
Highlights the widget if the scene can be moved in this direction.
Definition: arrow.cc:287