2016-06-26 18:56:40 +03:00
/************************************************************************
* file name : blocks_graphics_view . h
* - - - - - - - - - - - - - - - - - :
* creation time : 2016 / 06 / 26
* copyright : ( c ) 2016 Victor Zarubkin
* author : Victor Zarubkin
* email : v . s . zarubkin @ gmail . com
* - - - - - - - - - - - - - - - - - :
* description : The file contains declaration of GraphicsScene and GraphicsView and
* : it ' s auxiliary classes for displyaing easy_profiler blocks tree .
* - - - - - - - - - - - - - - - - - :
* change log : * 2016 / 06 / 26 Victor Zarubkin : moved sources from graphics_view . h
2016-06-26 19:06:53 +03:00
* : and renamed classes from My * to Prof * .
2016-06-30 02:57:57 +03:00
* :
* : * 2016 / 06 / 29 Victor Zarubkin : Highly optimized painting performance and memory consumption .
* :
2016-06-30 03:45:11 +03:00
* : * 2016 / 06 / 30 Victor Zarubkin : Replaced doubles with floats ( in ProfBlockItem ) for less memory consumption .
* :
2016-06-26 18:56:40 +03:00
* : *
* - - - - - - - - - - - - - - - - - :
* license : TODO : add license text
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-06-26 18:46:51 +03:00
# ifndef MY____GRAPHICS___VIEW_H
# define MY____GRAPHICS___VIEW_H
# include <QGraphicsView>
# include <QGraphicsScene>
2016-07-31 18:48:41 +03:00
# include <QGraphicsItem>
# include <QFont>
2016-06-26 20:54:16 +03:00
# include <QPoint>
2016-07-27 22:52:13 +03:00
# include <QTimer>
2016-06-26 18:46:51 +03:00
# include <stdlib.h>
2016-07-31 13:13:48 +03:00
# include "graphics_scrollbar.h"
2016-06-26 18:46:51 +03:00
# include "profiler/reader.h"
2016-07-31 18:48:41 +03:00
# include "common_types.h"
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
2016-06-26 18:46:51 +03:00
2016-07-31 13:13:48 +03:00
class ProfGraphicsView ;
2016-06-30 02:57:57 +03:00
class ProfGraphicsItem : public QGraphicsItem
{
2016-08-03 00:06:36 +03:00
typedef ProfItems Children ;
2016-07-31 13:13:48 +03:00
typedef : : std : : vector < unsigned int > DrawIndexes ;
typedef : : std : : vector < Children > Sublevels ;
2016-06-30 03:45:11 +03:00
2016-08-01 22:21:59 +03:00
DrawIndexes m_levelsIndexes ; ///< Indexes of first item on each level from which we must start painting
Sublevels m_levels ; ///< Arrays of items for each level
2016-07-10 01:24:31 +03:00
2016-08-01 22:21:59 +03:00
QRectF m_boundingRect ; ///< boundingRect (see QGraphicsItem)
const BlocksTree * m_pRoot ; ///< Pointer to the root profiler block (thread block). Used by ProfTreeWidget to restore hierarchy.
: : profiler : : thread_id_t m_thread_id ; ///< Thread id to which this item belongs
QRgb m_backgroundColor ; ///< Background color (to enable AlternateColors behavior like in QTreeWidget)
const bool m_bTest ; ///< If true then we are running test()
2016-06-26 18:46:51 +03:00
2016-06-30 02:57:57 +03:00
public :
2016-06-26 18:46:51 +03:00
2016-06-30 02:57:57 +03:00
ProfGraphicsItem ( ) ;
ProfGraphicsItem ( bool _test ) ;
2016-07-31 18:48:41 +03:00
ProfGraphicsItem ( : : profiler : : thread_id_t _thread_id , const BlocksTree * _root ) ;
2016-06-30 02:57:57 +03:00
virtual ~ ProfGraphicsItem ( ) ;
2016-06-26 20:54:16 +03:00
2016-08-01 22:21:59 +03:00
// Public virtual methods
2016-06-30 02:57:57 +03:00
QRectF boundingRect ( ) const override ;
void paint ( QPainter * _painter , const QStyleOptionGraphicsItem * _option , QWidget * _widget = nullptr ) override ;
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
public :
2016-07-31 13:13:48 +03:00
2016-08-01 22:21:59 +03:00
// Public non-virtual methods
2016-06-30 02:57:57 +03:00
void setBoundingRect ( qreal x , qreal y , qreal w , qreal h ) ;
void setBoundingRect ( const QRectF & _rect ) ;
2016-06-26 18:46:51 +03:00
2016-07-31 13:13:48 +03:00
void setBackgroundColor ( QRgb _color ) ;
2016-08-01 22:21:59 +03:00
///< Returns number of levels
2016-07-27 21:50:11 +03:00
unsigned short levels ( ) const ;
2016-08-01 22:21:59 +03:00
/** \brief Sets number of levels.
\ note Must be set before doing anything else .
\ param _levels Desired number of levels */
2016-07-10 01:24:31 +03:00
void setLevels ( unsigned short _levels ) ;
2016-08-01 22:21:59 +03:00
/** \brief Reserves memory for desired number of items on specified level.
\ param _level Index of the level
\ param _items Desired number of items on this level */
2016-07-10 01:24:31 +03:00
void reserve ( unsigned short _level , size_t _items ) ;
2016-08-01 22:21:59 +03:00
/**\brief Returns reference to the array of items of specified level.
\ param _level Index of the level */
2016-07-10 01:24:31 +03:00
const Children & items ( unsigned short _level ) const ;
2016-08-01 22:21:59 +03:00
/**\brief Returns reference to the item with required index on specified level.
\ param _level Index of the level
\ param _index Index of required item */
2016-07-10 01:24:31 +03:00
const ProfBlockItem & getItem ( unsigned short _level , size_t _index ) const ;
2016-08-01 22:21:59 +03:00
/**\brief Returns reference to the item with required index on specified level.
\ param _level Index of the level
\ param _index Index of required item */
2016-07-10 01:24:31 +03:00
ProfBlockItem & getItem ( unsigned short _level , size_t _index ) ;
2016-08-01 22:21:59 +03:00
/** \brief Adds new item to required level.
\ param _level Index of the level
\ retval Index of the new created item */
2016-07-10 01:24:31 +03:00
size_t addItem ( unsigned short _level ) ;
2016-08-01 22:21:59 +03:00
/** \brief Adds new item to required level.
Constructs new item using copy constructor .
\ param _level Index of the level
\ param _item Reference to the source item to copy from
\ retval Index of the new created item */
2016-07-10 01:24:31 +03:00
size_t addItem ( unsigned short _level , const ProfBlockItem & _item ) ;
2016-08-01 22:21:59 +03:00
/** \brief Adds new item to required level.
Constructs new item using move constructor .
\ param _level Index of the level
\ param _item Reference to the source item to move from
\ retval Index of the new created item */
2016-07-10 01:24:31 +03:00
size_t addItem ( unsigned short _level , ProfBlockItem & & _item ) ;
2016-07-31 13:13:48 +03:00
2016-08-01 22:21:59 +03:00
/** \brief Finds top-level blocks which are intersects with required selection zone.
\ note Found blocks will be added into the array of selected blocks .
\ param _left Left bound of the selection zone
\ param _right Right bound of the selection zone
\ param _blocks Reference to the array of selected blocks */
2016-07-31 18:48:41 +03:00
void getBlocks ( qreal _left , qreal _right , TreeBlocks & _blocks ) const ;
2016-07-31 13:13:48 +03:00
private :
2016-08-01 22:21:59 +03:00
///< Returns pointer to the ProfGraphicsView widget.
2016-07-31 13:13:48 +03:00
const ProfGraphicsView * view ( ) const ;
2016-06-30 03:45:11 +03:00
2016-06-30 02:57:57 +03:00
} ; // END of class ProfGraphicsItem.
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
//////////////////////////////////////////////////////////////////////////
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
class ProfChronometerItem : public QGraphicsItem
2016-06-26 18:46:51 +03:00
{
2016-08-01 22:21:59 +03:00
QFont m_font ; ///< Font which is used to draw text
QRectF m_boundingRect ; ///< boundingRect (see QGraphicsItem)
qreal m_left , m_right ; ///< Left and right bounds of the selection zone
2016-06-26 20:54:16 +03:00
2016-07-31 18:48:41 +03:00
public :
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
ProfChronometerItem ( ) ;
virtual ~ ProfChronometerItem ( ) ;
2016-06-30 02:57:57 +03:00
2016-08-01 22:21:59 +03:00
// Public virtual methods
2016-07-31 18:48:41 +03:00
QRectF boundingRect ( ) const override ;
void paint ( QPainter * _painter , const QStyleOptionGraphicsItem * _option , QWidget * _widget = nullptr ) override ;
2016-06-26 18:46:51 +03:00
public :
2016-08-01 22:21:59 +03:00
// Public non-virtual methods
2016-07-31 18:48:41 +03:00
void setBoundingRect ( qreal x , qreal y , qreal w , qreal h ) ;
void setBoundingRect ( const QRectF & _rect ) ;
void setLeftRight ( qreal _left , qreal _right ) ;
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
inline qreal left ( ) const
{
return m_left ;
}
2016-06-26 20:54:16 +03:00
2016-07-31 18:48:41 +03:00
inline qreal right ( ) const
{
return m_right ;
}
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
inline qreal width ( ) const
2016-06-26 18:46:51 +03:00
{
2016-07-31 18:48:41 +03:00
return m_right - m_left ;
2016-06-26 18:46:51 +03:00
}
2016-07-31 18:48:41 +03:00
private :
2016-06-26 18:46:51 +03:00
2016-08-01 22:21:59 +03:00
///< Returns pointer to the ProfGraphicsView widget.
2016-07-31 18:48:41 +03:00
const ProfGraphicsView * view ( ) const ;
} ; // END of class ProfChronometerItem.
//////////////////////////////////////////////////////////////////////////
2016-06-26 18:46:51 +03:00
2016-06-26 19:06:53 +03:00
class ProfGraphicsView : public QGraphicsView
2016-06-26 18:46:51 +03:00
{
Q_OBJECT
private :
2016-06-30 02:57:57 +03:00
typedef ProfGraphicsView This ;
2016-07-31 18:48:41 +03:00
typedef : : std : : vector < ProfGraphicsItem * > Items ;
2016-06-30 02:57:57 +03:00
2016-08-01 22:21:59 +03:00
Items m_items ; ///< Array of all ProfGraphicsItem items
TreeBlocks m_selectedBlocks ; ///< Array of items which were selected by selection zone (ProfChronometerItem)
QTimer m_flickerTimer ; ///< Timer for flicking behavior
QRectF m_visibleSceneRect ; ///< Visible scene rectangle
: : profiler : : timestamp_t m_beginTime ; ///< Begin time of profiler session. Used to reduce values of all begin and end times of profiler blocks.
qreal m_scale ; ///< Current scale
2016-07-31 13:13:48 +03:00
qreal m_offset ; ///< Have to use manual offset for all scene content instead of using scrollbars because QScrollBar::value is 32-bit integer :(
2016-08-01 22:21:59 +03:00
QPoint m_mousePressPos ; ///< Last mouse global position (used by mousePressEvent and mouseMoveEvent)
Qt : : MouseButtons m_mouseButtons ; ///< Pressed mouse buttons
GraphicsHorizontalScrollbar * m_pScrollbar ; ///< Pointer to the graphics scrollbar widget
ProfChronometerItem * m_chronometerItem ; ///< Pointer to the ProfChronometerItem which is displayed when you press right mouse button and move mouse left or right
int m_flickerSpeed ; ///< Current flicking speed
bool m_bUpdatingRect ; ///< Stub flag which is used to avoid excess calculations on some scene update (flicking, scaling and so on)
bool m_bTest ; ///< Testing flag (true when test() is called)
bool m_bEmpty ; ///< Indicates whether scene is empty and has no items
bool m_bStrictSelection ; ///< Strict selection flag used by ProfTreeWidget to interpret left and right bounds of selection zone in different ways
2016-06-26 18:46:51 +03:00
public :
2016-06-26 20:54:16 +03:00
ProfGraphicsView ( bool _test = false ) ;
2016-06-26 19:06:53 +03:00
ProfGraphicsView ( const thread_blocks_tree_t & _blocksTree ) ;
virtual ~ ProfGraphicsView ( ) ;
2016-06-26 18:46:51 +03:00
2016-08-01 22:21:59 +03:00
// Public virtual methods
2016-06-26 20:54:16 +03:00
void wheelEvent ( QWheelEvent * _event ) override ;
void mousePressEvent ( QMouseEvent * _event ) override ;
void mouseReleaseEvent ( QMouseEvent * _event ) override ;
void mouseMoveEvent ( QMouseEvent * _event ) override ;
2016-07-31 18:48:41 +03:00
void resizeEvent ( QResizeEvent * _event ) override ;
2016-06-26 20:54:16 +03:00
2016-08-01 22:21:59 +03:00
public :
2016-06-30 02:57:57 +03:00
2016-08-01 22:21:59 +03:00
// Public non-virtual methods
2016-07-31 18:48:41 +03:00
2016-07-31 13:13:48 +03:00
void setScrollbar ( GraphicsHorizontalScrollbar * _scrollbar ) ;
2016-06-30 02:57:57 +03:00
void clearSilent ( ) ;
2016-08-01 22:21:59 +03:00
void test ( size_t _frames_number , size_t _total_items_number_estimate , int _rows ) ;
2016-07-31 18:48:41 +03:00
void setTree ( const thread_blocks_tree_t & _blocksTree ) ;
signals :
2016-08-01 22:21:59 +03:00
// Signals
void intervalChanged ( const TreeBlocks & _blocks , : : profiler : : timestamp_t _session_begin_time , : : profiler : : timestamp_t _left , : : profiler : : timestamp_t _right , bool _strict ) ;
2016-06-30 02:57:57 +03:00
private :
2016-06-26 20:54:16 +03:00
2016-08-01 22:21:59 +03:00
// Private non-virtual methods
2016-06-26 20:54:16 +03:00
void initMode ( ) ;
2016-06-30 02:57:57 +03:00
void updateVisibleSceneRect ( ) ;
2016-07-31 13:13:48 +03:00
void updateScene ( ) ;
2016-08-01 22:21:59 +03:00
void scaleTo ( qreal _scale ) ;
2016-07-31 18:48:41 +03:00
qreal setTree ( ProfGraphicsItem * _item , const BlocksTree : : children_t & _children , qreal & _height , qreal _y , unsigned short _level ) ;
2016-08-01 22:21:59 +03:00
void fillTestChildren ( ProfGraphicsItem * _item , const int _maxlevel , int _level , qreal _x , qreal _y , size_t _childrenNumber , size_t & _total_items ) ;
2016-06-30 02:57:57 +03:00
private slots :
2016-08-01 22:21:59 +03:00
// Private Slots
2016-06-30 02:57:57 +03:00
void onScrollbarValueChange ( int ) ;
2016-07-31 13:13:48 +03:00
void onGraphicsScrollbarValueChange ( qreal ) ;
2016-07-27 22:52:13 +03:00
void onFlickerTimeout ( ) ;
2016-06-26 18:46:51 +03:00
2016-08-01 22:21:59 +03:00
public :
// Public inline methods
inline qreal scale ( ) const
{
return m_scale ;
}
inline qreal offset ( ) const
{
return m_offset ;
}
inline const QRectF & visibleSceneRect ( ) const
{
return m_visibleSceneRect ;
}
private :
// Private inline methods
inline qreal time2position ( const profiler : : timestamp_t & _time ) const
{
return PROF_MICROSECONDS ( qreal ( _time - m_beginTime ) ) ;
//return PROF_MILLISECONDS(qreal(_time - m_beginTime));
}
inline : : profiler : : timestamp_t position2time ( qreal _pos ) const
{
return PROF_FROM_MICROSECONDS ( _pos ) ;
//return PROF_FROM_MILLISECONDS(_pos);
}
inline qreal to_microseconds ( qreal _value ) const
{
return _value ;
//return _value * 1e-3;
}
inline qreal to_milliseconds ( qreal _value ) const
{
return _value * 1e3 ;
//return _value;
}
2016-06-26 19:06:53 +03:00
} ; // END of class ProfGraphicsView.
2016-06-26 18:46:51 +03:00
2016-07-31 18:48:41 +03:00
//////////////////////////////////////////////////////////////////////////
2016-06-26 18:46:51 +03:00
2016-07-31 13:13:48 +03:00
class ProfGraphicsViewWidget : public QWidget
{
Q_OBJECT
private :
ProfGraphicsView * m_view ;
GraphicsHorizontalScrollbar * m_scrollbar ;
public :
ProfGraphicsViewWidget ( bool _test = false ) ;
ProfGraphicsViewWidget ( const thread_blocks_tree_t & _blocksTree ) ;
virtual ~ ProfGraphicsViewWidget ( ) ;
ProfGraphicsView * view ( ) ;
private :
} ; // END of class ProfGraphicsViewWidget.
2016-07-31 18:48:41 +03:00
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
2016-07-31 13:13:48 +03:00
2016-06-26 18:46:51 +03:00
# endif // MY____GRAPHICS___VIEW_H