OpenWalnut  1.5.0dev
WQtNetworkItemGrid.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WQTNETWORKITEMGRID_H
26 #define WQTNETWORKITEMGRID_H
27 
28 #include <map>
29 #include <memory>
30 
31 #include <QGraphicsItem>
32 #include <QWidget>
33 #include <QtCore/QObject>
34 #include <QtCore/QPoint>
35 
36 /**
37  * Compare two QPoints. Needed for std::map.
38  *
39  * \param lhs left operator
40  * \param rhs right operator
41  *
42  * \return result lhs < rhs
43  */
44 inline bool operator< ( const QPoint& lhs, const QPoint& rhs )
45 {
46  return ( lhs.x() < rhs.x() ) || ( !( rhs.x() < lhs.x() ) && ( lhs.y() < rhs.y() ) );
47 }
48 
49 /**
50  * Implement a virtual grid for placing QGraphicsItems. It itself is a QGraphicsItem to allow drawing the grid or parts of the grid.
51  *
52  * \note all coordinates are originating from zero
53  */
55 {
56  Q_OBJECT
57 public:
58  /**
59  * Convenience typedef for a std::shared_ptr< WQtNetworkItemGrid >.
60  */
61  typedef std::shared_ptr< WQtNetworkItemGrid > SPtr;
62 
63  /**
64  * Convenience typedef for a std::shared_ptr< const WQtNetworkItemGrid >.
65  */
66  typedef std::shared_ptr< const WQtNetworkItemGrid > ConstSPtr;
67 
68  /**
69  * Default constructor.
70  */
72 
73  /**
74  * Destructor.
75  */
76  virtual ~WQtNetworkItemGrid();
77 
78  /**
79  * The bounding area of the item.
80  *
81  * \return the bounding rect
82  */
83  virtual QRectF boundingRect() const;
84 
85  /**
86  * Returns the boundaries in grid coordinates. If you need world coords, use \ref boundingRect instead.
87  *
88  * \return the grid bounds
89  */
90  virtual QRect getGridBoundingRect() const;
91 
92  /**
93  * Update the m_dimensions. This method rebuilds the bounding area of the grid by re-reading all items in the grid. This is useful, whenever
94  * you do a lot of complex operations while suppressing all updates. Then use this method to force a complete update of the dimensions.
95  */
96  void updateDimensions();
97 
98  /**
99  * Paint the item.
100  *
101  * \param painter implements drawing commands
102  * \param option provides style options for the item, such as its state, exposed area and its level-of-detail hints
103  * \param widget the widget on which is painted. Can be NULL.
104  */
105  virtual void paint( QPainter* painter, const QStyleOptionGraphicsItem* option,
106  QWidget* widget );
107 
108  /**
109  * Return the index of the first empty column.
110  *
111  * \return the index
112  */
113  int getFirstFreeColumn() const;
114 
115  /**
116  * Set the specified item to the specified position.
117  *
118  * \param item the item to set
119  * \param col the column ( x coordinate )
120  * \param row the row ( y coordinate )
121  *
122  * \return false if there already is an element
123  */
124  bool setItem( QGraphicsItem* item, int col, int row );
125 
126  /**
127  * Set the specified item to the specified position.
128  *
129  * \param item the item to set
130  * \param cell the column ( x coordinate )
131  *
132  * \return false if there already is an element
133  */
134  bool setItem( QGraphicsItem* item, QPoint cell );
135 
136  /**
137  * Remove the item at the given position.
138  *
139  * \param col the column ( x coordinate )
140  * \param row the row ( y coordinate )
141  */
142  void removeItem( int col, int row );
143 
144  /**
145  * Remove the item from the list.
146  *
147  * \param item the item
148  *
149  * \return true if found and removed.
150  */
151  bool removeItem( QGraphicsItem* item );
152 
153  /**
154  * Move item from its current position to the specified one. If the item does not exist right now, it will get moved from its current
155  * position. If the target position is occupied right now, nothing happens and false will be returned.
156  *
157  * \param item the item
158  * \param col target columns
159  * \param row target row
160  *
161  * \return true if successful. False if the target was occupied.
162  */
163  bool moveItem( QGraphicsItem* item, int col, int row );
164 
165  /**
166  * Move item from its current position to the specified one. If the item does not exist right now, it will get moved from its current
167  * position. If the target position is occupied right now, nothing happens and false will be returned.
168  *
169  * \param item the item
170  * \param cell target cell
171  *
172  * \return true if successful. False if the target was occupied.
173  */
174  bool moveItem( QGraphicsItem* item, QPoint cell );
175 
176  /**
177  * Is there an element at the given position?
178  *
179  * \param col the column ( x coordinate )
180  * \param row the row ( y coordinate )
181  *
182  * \return true if there is an item already
183  */
184  bool isOccupied( int col, int row );
185 
186  /**
187  * Is there an element at the given position?
188  *
189  * \param cell the cell
190  *
191  * \return true if there is an item already
192  */
193  bool isOccupied( QPoint cell );
194 
195  /**
196  * Map the grid coordinate to world coordinates.
197  *
198  * \param col the column ( x coordinate )
199  * \param row the row ( y coordinate )
200  *
201  * \return the top,left corner of the grid box
202  */
203  virtual QPointF mapToWorld( int col, int row );
204 
205  /**
206  * Map the grid coordinate to world coordinates.
207  *
208  * \param gridCoord the grid coordinates
209  *
210  * \return the world coords
211  */
212  virtual QPointF mapToWorld( QPoint gridCoord );
213 
214  /**
215  * Build a rect which covers the cell area in world space.
216  *
217  * \param cell the cell to create the rect for
218  *
219  * \return the rect covering the cell
220  */
221  virtual QRectF mapCellAreaToWorld( QPoint cell );
222 
223  /**
224  * Build a rect which covers the cell area in world space.
225  *
226  * \param row the row
227  * \param col the col
228  *
229  * \return the rect covering the cell
230  */
231  virtual QRectF mapCellAreaToWorld( int row, int col );
232 
233  /**
234  * Find the position of the specified item.
235  *
236  * \param item item to search
237  *
238  * \return QPoint() if not found. Else, the position in grid coordinates.
239  */
240  virtual QPoint whereIs( QGraphicsItem* item );
241 
242  /**
243  * Check whether the item is managed in the grid.
244  *
245  * \param item the item
246  *
247  * \return true if managed
248  */
249  virtual bool isInGrid( QGraphicsItem* item );
250 
251  /**
252  * Find the nearest cell matching the specified world coordinates.
253  *
254  * \param worldSpace the coordinates to find the next cell for.
255  *
256  * \return cell coordinates
257  */
258  virtual QPoint findNearestCell( QPointF worldSpace );
259 
260  /**
261  * Move the item to the position physically. This does not modify the grid. It only moves the QGraphicsItem in the scene.
262  *
263  * \param row target row
264  * \param col target col
265  * \param animate if true, the item uses its build in animations
266  * \param item item to move
267  */
268  virtual void physicalMoveTo( QGraphicsItem* item, int col, int row, bool animate = true );
269 
270  /**
271  * Move the item to the position physically. This does not modify the grid. It only moves the QGraphicsItem in the scene.
272  *
273  * \param cell target cell
274  * \param animate if true, the item uses its build in animations
275  * \param item item to move
276  */
277  virtual void physicalMoveTo( QGraphicsItem* item, QPoint cell, bool animate );
278 
279  /**
280  * Highlights the specified cell. Note that only one cell can be highlighted. If you call this method with another cell, the old highlight
281  * fades out.
282  *
283  * \param cell the cell to highlight
284  * \param color the color of the highlight
285  */
286  void highlightCell( QPoint cell, QColor color );
287 
288  /**
289  * Turns off highlight
290  */
291  void highlightCell();
292 
293  /**
294  * Allows for temporarily disabling bounds update signal. This is needed sometimes, where bounds are updated during another Qt event, causing the
295  * update event again, causing the Qt event again, causing the update event again, segfault.
296  *
297  * \note Always remember to enable again.
298  *
299  * \param disable true to disable.
300  */
301  void disableBoundsUpdate( bool disable = true );
302 
303 public slots:
304  /**
305  * Allows blending in the underlaying layout structure.
306  */
307  void blendIn();
308 
309  /**
310  * Allows blending out the underlaying layout structure.
311  */
312  void blendOut();
313 signals:
314  /**
315  * emitted when the grid shrinks or grows to update scene bounds
316  */
318 
319 protected:
320  /**
321  * Return the element at the given position. If the position is invalid, NULL is returned.
322  *
323  * \param col the column ( x coordinate )
324  * \param row the row ( y coordinate )
325  *
326  * \return the item or NULL if not valid
327  */
328  virtual QGraphicsItem* at( int col, int row );
329 
330  /**
331  * Really sets the item to the grid position. Ignores previous items. You should manage any previous existing item at that grid position for
332  * yourself.
333  *
334  * \param item the item
335  * \param col the column ( x coordinate )
336  * \param row the row ( y coordinate )
337  * \param suppressUpdate if true, the call will not call updateDimensionsAdd. Useful when using this method in another, more complex operation.
338  *
339  * \return the previous item at this position, or NULL if there was none.
340  */
341  virtual QGraphicsItem* setItemImpl( QGraphicsItem* item, int col, int row, bool suppressUpdate = false );
342 
343  /**
344  * Remove the item from the grid if existing.
345  *
346  * \param item item to remove
347  * \param suppressUpdate if true, the call will not call updateDimensionsRemove. Useful when using this method in another, more complex operation.
348  *
349  * \return true if something was removed. False if the item is not in the grid.
350  */
351  virtual bool removeItemImpl( QGraphicsItem* item, bool suppressUpdate = false );
352 
353 private:
354  /**
355  * List of lists of QGraphicsItem
356  */
357  typedef std::map< QPoint, QGraphicsItem* > Grid;
358 
359  /**
360  * The virtual grid. Column-first. Means outer list is the list of x coordinates, containing a list of all items in this column.
361  */
363 
364  /**
365  * Maps between item and its grid coordinates
366  */
367  typedef std::map< QGraphicsItem*, QPoint > ItemCoordinateMap;
368 
369  /**
370  * Keeps track of the item coordinates.
371  */
373 
374  /**
375  * The largest number of entries in a column/row
376  */
378 
379  /**
380  * Bounding Rect of the Grid in world coordinates.
381  */
382  QRectF m_bb;
383 
384  /**
385  * Use to update bounding box when you modify the m_grid dimensions.
386  */
387  void updateBoundingRect();
388 
389  /**
390  * Current cell to highlight.
391  */
393 
394  /**
395  * Color of the highlight
396  */
398 
399  /**
400  * En/Dis-able highlughting
401  */
403 
404  /**
405  * Timer used for blend in effects of the grid.
406  */
407  QTimeLine* m_blendInTimer;
408 
409  /**
410  * Timer used for blend in effects of the grid.
411  */
412  QTimeLine* m_blendOutTimer;
413 
414  /**
415  * Disable updateBounds signal.
416  */
418 
419 private slots:
420  /**
421  * Called when the animation timers tick and progress in timeline. Used to blend the item in.
422  *
423  * \param value the value between 0 and 1
424  */
425  void animationBlendInTick( qreal value );
426 
427  /**
428  * Called when the animation timers tick and progress in timeline. Used to blend the item out.
429  *
430  * \param value the value between 0 and 1
431  */
432  void animationBlendOutTick( qreal value );
433 };
434 
435 #endif // WQTNETWORKITEMGRID_H
436 
Implement a virtual grid for placing QGraphicsItems.
std::map< QPoint, QGraphicsItem * > Grid
List of lists of QGraphicsItem.
QRectF m_bb
Bounding Rect of the Grid in world coordinates.
ItemCoordinateMap m_gridReverse
Keeps track of the item coordinates.
virtual QGraphicsItem * at(int col, int row)
Return the element at the given position.
bool setItem(QGraphicsItem *item, int col, int row)
Set the specified item to the specified position.
virtual QRectF boundingRect() const
The bounding area of the item.
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
Paint the item.
virtual QPoint whereIs(QGraphicsItem *item)
Find the position of the specified item.
QTimeLine * m_blendInTimer
Timer used for blend in effects of the grid.
bool m_disableUpdateBounds
Disable updateBounds signal.
bool moveItem(QGraphicsItem *item, int col, int row)
Move item from its current position to the specified one.
virtual QPoint findNearestCell(QPointF worldSpace)
Find the nearest cell matching the specified world coordinates.
virtual void physicalMoveTo(QGraphicsItem *item, int col, int row, bool animate=true)
Move the item to the position physically.
virtual ~WQtNetworkItemGrid()
Destructor.
void updateBoundingRect()
Use to update bounding box when you modify the m_grid dimensions.
virtual bool isInGrid(QGraphicsItem *item)
Check whether the item is managed in the grid.
virtual QRectF mapCellAreaToWorld(QPoint cell)
Build a rect which covers the cell area in world space.
void animationBlendInTick(qreal value)
Called when the animation timers tick and progress in timeline.
WQtNetworkItemGrid()
Default constructor.
virtual QGraphicsItem * setItemImpl(QGraphicsItem *item, int col, int row, bool suppressUpdate=false)
Really sets the item to the grid position.
std::shared_ptr< const WQtNetworkItemGrid > ConstSPtr
Convenience typedef for a std::shared_ptr< const WQtNetworkItemGrid >.
Grid m_grid
The virtual grid.
virtual QRect getGridBoundingRect() const
Returns the boundaries in grid coordinates.
QTimeLine * m_blendOutTimer
Timer used for blend in effects of the grid.
QRect m_dimensions
The largest number of entries in a column/row.
void blendOut()
Allows blending out the underlaying layout structure.
void updateDimensions()
Update the m_dimensions.
void highlightCell()
Turns off highlight.
virtual QPointF mapToWorld(int col, int row)
Map the grid coordinate to world coordinates.
void disableBoundsUpdate(bool disable=true)
Allows for temporarily disabling bounds update signal.
void blendIn()
Allows blending in the underlaying layout structure.
QColor m_highlightColor
Color of the highlight.
void removeItem(int col, int row)
Remove the item at the given position.
int getFirstFreeColumn() const
Return the index of the first empty column.
std::shared_ptr< WQtNetworkItemGrid > SPtr
Convenience typedef for a std::shared_ptr< WQtNetworkItemGrid >.
bool m_highlightCellEnabled
En/Dis-able highlughting.
bool isOccupied(int col, int row)
Is there an element at the given position?
void animationBlendOutTick(qreal value)
Called when the animation timers tick and progress in timeline.
void updatedBounds()
emitted when the grid shrinks or grows to update scene bounds
virtual bool removeItemImpl(QGraphicsItem *item, bool suppressUpdate=false)
Remove the item from the grid if existing.
QPoint m_highlightCell
Current cell to highlight.
std::map< QGraphicsItem *, QPoint > ItemCoordinateMap
Maps between item and its grid coordinates.