2016-07-10 01:29:09 +03:00
/************************************************************************
2016-09-15 22:30:32 +03:00
* file name : easy_graphics_scrollbar . cpp
2016-07-10 01:29:09 +03:00
* - - - - - - - - - - - - - - - - - :
* creation time : 2016 / 07 / 04
* author : Victor Zarubkin
* email : v . s . zarubkin @ gmail . com
* - - - - - - - - - - - - - - - - - :
* description : .
* - - - - - - - - - - - - - - - - - :
* change log : * 2016 / 07 / 04 Victor Zarubkin : Initial commit .
* :
* : *
* - - - - - - - - - - - - - - - - - :
2016-09-06 21:49:32 +03:00
* license : Lightweight profiler library for c + +
2017-03-30 06:55:15 +03:00
* : Copyright ( C ) 2016 - 2017 Sergey Yagovtsev , Victor Zarubkin
2016-09-06 21:49:32 +03:00
* :
2017-03-30 06:55:15 +03:00
* : Licensed under either of
* : * MIT license ( LICENSE . MIT or http : //opensource.org/licenses/MIT)
* : * Apache License , Version 2.0 , ( LICENSE . APACHE or http : //www.apache.org/licenses/LICENSE-2.0)
* : at your option .
2016-11-13 16:39:59 +03:00
* :
2017-03-30 06:55:15 +03:00
* : The MIT License
* :
* : Permission is hereby granted , free of charge , to any person obtaining a copy
* : of this software and associated documentation files ( the " Software " ) , to deal
* : in the Software without restriction , including without limitation the rights
* : to use , copy , modify , merge , publish , distribute , sublicense , and / or sell copies
* : of the Software , and to permit persons to whom the Software is furnished
* : to do so , subject to the following conditions :
* :
* : The above copyright notice and this permission notice shall be included in all
* : copies or substantial portions of the Software .
* :
* : THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR IMPLIED ,
* : INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY , FITNESS FOR A PARTICULAR
* : PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* : LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION OF CONTRACT ,
* : TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* : USE OR OTHER DEALINGS IN THE SOFTWARE .
* :
* : The Apache License , Version 2.0 ( the " License " )
* :
* : You may not use this file except in compliance with the License .
2016-11-13 16:39:59 +03:00
* : You may obtain a copy of the License at
* :
* : http : //www.apache.org/licenses/LICENSE-2.0
* :
* : Unless required by applicable law or agreed to in writing , software
* : distributed under the License is distributed on an " AS IS " BASIS ,
* : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* : See the License for the specific language governing permissions and
* : limitations under the License .
2016-07-10 01:29:09 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-07-31 13:13:48 +03:00
# include <algorithm>
2016-08-18 23:26:41 +03:00
# include <QGraphicsScene>
2016-07-31 13:13:48 +03:00
# include <QWheelEvent>
# include <QMouseEvent>
# include <QResizeEvent>
2017-12-28 00:23:14 +03:00
# include <easy/utility.h>
2016-09-15 22:30:32 +03:00
# include "easy_graphics_scrollbar.h"
2016-08-08 22:45:57 +03:00
# include "globals.h"
2016-07-10 01:29:09 +03:00
//////////////////////////////////////////////////////////////////////////
2017-11-23 22:01:44 +03:00
EASY_CONSTEXPR int HIST_COLUMN_MIN_HEIGHT = 2 ;
2016-07-31 13:13:48 +03:00
//////////////////////////////////////////////////////////////////////////
2016-12-07 22:29:16 +03:00
inline qreal calculate_color1 ( qreal h , qreal , qreal k )
2016-11-16 22:17:39 +03:00
{
2017-12-28 00:23:14 +03:00
return std : : min ( h * k , 0.9999999 ) ;
2016-11-16 22:17:39 +03:00
}
2016-12-07 22:29:16 +03:00
inline qreal calculate_color2 ( qreal , qreal duration , qreal k )
2016-11-16 22:17:39 +03:00
{
2018-01-20 15:23:28 +03:00
using estd : : sqr ;
2017-12-28 00:23:14 +03:00
return std : : min ( sqr ( sqr ( duration ) ) * k , 0.9999999 ) ;
2016-11-16 22:17:39 +03:00
}
2016-07-10 01:29:09 +03:00
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
GraphicsHistogramItem : : GraphicsHistogramItem ( ) : Parent ( )
2016-12-04 16:51:27 +03:00
, m_threadDuration ( 0 )
2016-12-14 22:16:14 +03:00
, m_threadProfiledTime ( 0 )
, m_threadWaitTime ( 0 )
2016-12-04 16:51:27 +03:00
, m_pSource ( nullptr )
2017-03-13 20:30:57 +03:00
, m_workerTopDuration ( 0 )
, m_workerBottomDuration ( 0 )
2017-06-05 21:26:10 +03:00
, m_blockTotalDuraion ( 0 )
2016-12-12 22:28:54 +03:00
, m_pProfilerThread ( nullptr )
2016-12-04 16:51:27 +03:00
, m_threadId ( 0 )
2018-01-20 15:23:28 +03:00
, m_blockId ( profiler_gui : : numeric_max < decltype ( m_blockId ) > ( ) )
, m_timeUnits ( profiler_gui : : TimeUnits_auto )
2017-03-07 19:59:57 +03:00
, m_regime ( Hist_Pointer )
2016-08-03 00:06:36 +03:00
{
}
2018-01-20 15:23:28 +03:00
GraphicsHistogramItem : : ~ GraphicsHistogramItem ( )
2016-08-03 00:06:36 +03:00
{
2018-01-20 15:23:28 +03:00
2016-08-03 00:06:36 +03:00
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : paint ( QPainter * _painter , const QStyleOptionGraphicsItem * /* _option */ , QWidget * /* _widget */ )
2016-08-03 00:06:36 +03:00
{
2018-01-20 15:23:28 +03:00
if ( ! isImageUpdatePermitted ( ) | | ( m_regime = = Hist_Pointer & & m_pSource = = nullptr ) | | ( m_regime = = Hist_Id & & ( m_threadId = = 0 | | profiler_gui : : is_max ( m_blockId ) ) ) )
2016-12-04 16:51:27 +03:00
return ;
2017-03-07 19:59:57 +03:00
if ( m_regime = = Hist_Pointer )
2017-03-07 00:29:34 +03:00
paintByPtr ( _painter ) ;
else
paintById ( _painter ) ;
}
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : paintMouseIndicator ( QPainter * _painter , qreal _top , qreal _bottom , qreal _width , qreal _height , qreal _top_width , qreal _mouse_y , qreal _delta_time , int _font_h )
2017-03-07 00:29:34 +03:00
{
if ( _font_h ! = 0 & & _top < _mouse_y & & _mouse_y < _bottom )
{
const int half_font_h = _font_h > > 1 ;
2016-12-04 16:51:27 +03:00
2017-03-07 00:29:34 +03:00
_painter - > setPen ( Qt : : blue ) ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
const auto mouseStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue + _delta_time * ( _bottom - _mouse_y ) / _height , 3 ) ;
2017-03-07 00:29:34 +03:00
qreal mouseIndicatorRight = _width ;
if ( _mouse_y < _top + half_font_h )
mouseIndicatorRight = _top_width ;
2016-12-04 16:51:27 +03:00
2017-03-07 00:29:34 +03:00
qreal mouseIndicatorLeft = 0 ;
2018-01-20 15:23:28 +03:00
const QRectF rect ( 0 , _mouse_y - _font_h - 2 , _width , 4 + ( _font_h < < 1 ) ) ;
2017-03-07 00:29:34 +03:00
if ( _mouse_y > _bottom - half_font_h )
{
_painter - > drawText ( rect , Qt : : AlignLeft | Qt : : AlignTop , mouseStr ) ;
}
else if ( _mouse_y < _top + half_font_h )
{
_painter - > drawText ( rect , Qt : : AlignLeft | Qt : : AlignBottom , mouseStr ) ;
}
else
{
_painter - > drawText ( rect , Qt : : AlignLeft | Qt : : AlignVCenter , mouseStr ) ;
mouseIndicatorLeft = _painter - > fontMetrics ( ) . width ( mouseStr ) + 3 ;
}
2016-08-03 00:06:36 +03:00
2017-03-07 00:29:34 +03:00
_painter - > drawLine ( QLineF ( mouseIndicatorLeft , _mouse_y , mouseIndicatorRight , _mouse_y ) ) ;
}
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : paintByPtr ( QPainter * _painter )
2016-12-04 16:51:27 +03:00
{
2016-11-30 22:37:11 +03:00
const auto widget = static_cast < const EasyGraphicsScrollbar * > ( scene ( ) - > parent ( ) ) ;
const bool bindMode = widget - > bindMode ( ) ;
const auto currentScale = widget - > getWindowScale ( ) ;
2016-08-03 00:06:36 +03:00
const auto bottom = m_boundingRect . bottom ( ) ;
2016-12-01 21:55:11 +03:00
const auto width = m_boundingRect . width ( ) * currentScale ;
2018-01-20 15:23:28 +03:00
const auto dtime = m_topValue - m_bottomValue ;
const auto coeff = m_boundingRect . height ( ) / ( dtime > 1e-3 ? dtime : 1. ) ;
2016-08-03 00:06:36 +03:00
QRectF rect ;
QBrush brush ( Qt : : SolidPattern ) ;
2017-04-10 22:04:09 +03:00
//QRgb previousColor = 0;
2016-08-03 00:06:36 +03:00
2016-12-04 16:51:27 +03:00
_painter - > save ( ) ;
_painter - > setTransform ( QTransform : : fromScale ( 1.0 / currentScale , 1 ) , true ) ;
2017-03-13 00:43:15 +03:00
if ( ! m_pSource - > empty ( ) )
2016-12-04 16:51:27 +03:00
{
if ( ! bindMode )
2018-01-20 15:23:28 +03:00
paintImage ( _painter ) ;
2016-12-04 16:51:27 +03:00
else
2018-01-20 15:23:28 +03:00
paintImage ( _painter , currentScale , widget - > minimum ( ) , widget - > maximum ( ) , widget - > value ( ) , widget - > sliderWidth ( ) ) ;
2016-12-04 16:51:27 +03:00
}
qreal top_width = width , bottom_width = width ;
2018-01-20 15:23:28 +03:00
const auto font_h = widget - > fontHeight ( ) ;
rect . setRect ( 0 , m_boundingRect . top ( ) - widget - > margin ( ) , width - 3 , m_boundingRect . height ( ) + widget - > margins ( ) ) ;
_painter - > setPen ( profiler_gui : : TEXT_COLOR ) ;
_painter - > drawText ( rect , Qt : : AlignLeft | Qt : : AlignTop , bindMode ? " Mode: Zoom " : " Mode: Overview " ) ;
2017-03-07 00:29:34 +03:00
if ( ! m_topDurationStr . isEmpty ( ) )
2016-12-04 16:51:27 +03:00
{
if ( m_timeUnits ! = EASY_GLOBALS . time_units )
{
m_timeUnits = EASY_GLOBALS . time_units ;
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
//auto fm = _painter->fontMetrics();
//top_width -= fm.width(m_topDurationStr) + 7;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
_painter - > setPen ( m_topValue < m_maxValue ? QColor ( Qt : : darkRed ) : profiler_gui : : TEXT_COLOR ) ;
2017-03-07 00:29:34 +03:00
_painter - > drawText ( rect , Qt : : AlignRight | Qt : : AlignTop , m_topDurationStr ) ;
2016-12-04 16:51:27 +03:00
rect . setRect ( 0 , bottom , width - 3 , font_h ) ;
2018-01-20 15:23:28 +03:00
_painter - > setPen ( m_bottomValue > m_minValue ? QColor ( Qt : : darkRed ) : profiler_gui : : TEXT_COLOR ) ;
2017-03-07 00:29:34 +03:00
_painter - > drawText ( rect , Qt : : AlignRight | Qt : : AlignTop , m_bottomDurationStr ) ;
2016-12-04 16:51:27 +03:00
}
_painter - > setPen ( Qt : : darkGray ) ;
_painter - > drawLine ( QLineF ( 0 , bottom , bottom_width , bottom ) ) ;
_painter - > drawLine ( QLineF ( 0 , m_boundingRect . top ( ) , top_width , m_boundingRect . top ( ) ) ) ;
2018-01-20 15:23:28 +03:00
paintMouseIndicator ( _painter , m_boundingRect . top ( ) , bottom , width , m_boundingRect . height ( ) , top_width , m_mousePos . y ( ) , dtime , font_h ) ;
2017-03-07 00:29:34 +03:00
2018-01-20 15:23:28 +03:00
if ( m_bottomValue < EASY_GLOBALS . frame_time & & EASY_GLOBALS . frame_time < m_topValue )
2016-12-04 16:51:27 +03:00
{
2017-03-07 00:29:34 +03:00
// Draw marker displaying expected frame_time step
2018-01-20 15:23:28 +03:00
const auto h = bottom - ( EASY_GLOBALS . frame_time - m_bottomValue ) * coeff ;
2016-12-04 16:51:27 +03:00
_painter - > setPen ( Qt : : DashLine ) ;
auto w = width ;
2018-01-20 15:23:28 +03:00
const auto boundary = widget - > margin ( ) - font_h ;
2016-12-04 16:51:27 +03:00
if ( h < ( m_boundingRect . top ( ) - boundary ) )
w = top_width ;
else if ( h > ( bottom + boundary ) )
w = bottom_width ;
_painter - > drawLine ( QLineF ( 0 , h , w , h ) ) ;
}
2018-01-20 15:23:28 +03:00
_painter - > setPen ( profiler_gui : : TEXT_COLOR ) ;
rect . setRect ( 0 , bottom + 2 , width , font_h ) ;
2017-03-07 00:29:34 +03:00
const auto eventsSize = m_pProfilerThread - > events . size ( ) ;
2018-01-20 15:23:28 +03:00
_painter - > drawText ( rect , Qt : : AlignCenter | Qt : : TextDontClip , QString ( " %1 | duration: %2 | profiled: %3 (%4%) | wait: %5 (%6%) | %7 frames | %8 blocks | %9 markers " )
2017-03-07 00:29:34 +03:00
. arg ( m_threadName )
2018-01-20 15:23:28 +03:00
. arg ( profiler_gui : : timeStringRealNs ( EASY_GLOBALS . time_units , m_threadDuration ) )
. arg ( profiler_gui : : timeStringRealNs ( EASY_GLOBALS . time_units , m_threadProfiledTime ) )
2016-12-14 22:16:14 +03:00
. arg ( m_threadDuration ? QString : : number ( 100. * ( double ) m_threadProfiledTime / ( double ) m_threadDuration , ' f ' , 2 ) : QString ( " 0 " ) )
2018-01-20 15:23:28 +03:00
. arg ( profiler_gui : : timeStringRealNs ( EASY_GLOBALS . time_units , m_threadWaitTime ) )
2016-12-14 22:16:14 +03:00
. arg ( m_threadDuration ? QString : : number ( 100. * ( double ) m_threadWaitTime / ( double ) m_threadDuration , ' f ' , 2 ) : QString ( " 0 " ) )
2017-06-06 20:46:06 +03:00
. arg ( m_pProfilerThread - > frames_number )
2017-03-07 00:29:34 +03:00
. arg ( m_pProfilerThread - > blocks_number - eventsSize )
. arg ( eventsSize ) ) ;
2016-12-04 16:51:27 +03:00
_painter - > restore ( ) ;
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : paintById ( QPainter * _painter )
2016-12-04 16:51:27 +03:00
{
const auto widget = static_cast < const EasyGraphicsScrollbar * > ( scene ( ) - > parent ( ) ) ;
const bool bindMode = widget - > bindMode ( ) ;
const auto currentScale = widget - > getWindowScale ( ) ;
const auto bottom = m_boundingRect . bottom ( ) ;
const auto width = m_boundingRect . width ( ) * currentScale ;
2018-01-20 15:23:28 +03:00
const auto dtime = m_topValue - m_bottomValue ;
const auto coeff = m_boundingRect . height ( ) / ( dtime > 1e-3 ? dtime : 1. ) ;
2016-12-04 16:51:27 +03:00
QRectF rect ;
QBrush brush ( Qt : : SolidPattern ) ;
2017-04-10 22:04:09 +03:00
//QRgb previousColor = 0;
2016-08-03 00:06:36 +03:00
_painter - > save ( ) ;
_painter - > setTransform ( QTransform : : fromScale ( 1.0 / currentScale , 1 ) , true ) ;
2017-03-13 00:43:15 +03:00
const auto & items = m_selectedBlocks ;
if ( ! items . empty ( ) )
2016-08-03 00:06:36 +03:00
{
2017-03-13 00:43:15 +03:00
if ( ! bindMode )
2018-01-20 15:23:28 +03:00
paintImage ( _painter ) ;
2017-03-13 00:43:15 +03:00
else
2018-01-20 15:23:28 +03:00
paintImage ( _painter , currentScale , widget - > minimum ( ) , widget - > maximum ( ) , widget - > value ( ) , widget - > sliderWidth ( ) ) ;
2016-08-03 00:06:36 +03:00
}
2016-12-01 21:55:11 +03:00
qreal top_width = width , bottom_width = width ;
2018-01-20 15:23:28 +03:00
const auto font_h = widget - > fontHeight ( ) ;
rect . setRect ( 0 , m_boundingRect . top ( ) - widget - > margin ( ) , width - 3 , m_boundingRect . height ( ) + widget - > margins ( ) ) ;
_painter - > setPen ( profiler_gui : : TEXT_COLOR ) ;
_painter - > drawText ( rect , Qt : : AlignLeft | Qt : : AlignTop , bindMode ? " Mode: Zoom " : " Mode: Overview " ) ;
2017-03-07 00:29:34 +03:00
if ( ! m_topDurationStr . isEmpty ( ) )
2016-12-01 21:55:11 +03:00
{
if ( m_timeUnits ! = EASY_GLOBALS . time_units )
{
m_timeUnits = EASY_GLOBALS . time_units ;
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
2016-12-01 21:55:11 +03:00
}
2018-01-20 15:23:28 +03:00
//auto fm = _painter->fontMetrics();
//top_width -= fm.width(m_topDurationStr) + 7;
2016-12-01 21:55:11 +03:00
2018-01-20 15:23:28 +03:00
_painter - > setPen ( m_topValue < m_maxValue ? QColor ( Qt : : darkRed ) : profiler_gui : : TEXT_COLOR ) ;
2017-03-07 00:29:34 +03:00
_painter - > drawText ( rect , Qt : : AlignRight | Qt : : AlignTop , m_topDurationStr ) ;
2016-12-04 16:51:27 +03:00
rect . setRect ( 0 , bottom , width - 3 , font_h ) ;
2018-01-20 15:23:28 +03:00
_painter - > setPen ( m_bottomValue > m_minValue ? QColor ( Qt : : darkRed ) : profiler_gui : : TEXT_COLOR ) ;
2017-03-07 00:29:34 +03:00
_painter - > drawText ( rect , Qt : : AlignRight | Qt : : AlignTop , m_bottomDurationStr ) ;
2016-12-01 21:55:11 +03:00
}
2016-08-23 22:44:59 +03:00
_painter - > setPen ( Qt : : darkGray ) ;
2016-12-01 21:55:11 +03:00
_painter - > drawLine ( QLineF ( 0 , bottom , bottom_width , bottom ) ) ;
_painter - > drawLine ( QLineF ( 0 , m_boundingRect . top ( ) , top_width , m_boundingRect . top ( ) ) ) ;
2016-11-13 22:02:47 +03:00
2018-01-20 15:23:28 +03:00
paintMouseIndicator ( _painter , m_boundingRect . top ( ) , bottom , width , m_boundingRect . height ( ) , top_width , m_mousePos . y ( ) , dtime , font_h ) ;
2017-03-07 00:29:34 +03:00
2018-01-20 15:23:28 +03:00
if ( m_bottomValue < EASY_GLOBALS . frame_time & & EASY_GLOBALS . frame_time < m_topValue )
2016-11-13 22:02:47 +03:00
{
// Draw marker displaying required frame_time step
2018-01-20 15:23:28 +03:00
const auto h = bottom - ( EASY_GLOBALS . frame_time - m_bottomValue ) * coeff ;
2016-11-16 23:13:43 +03:00
_painter - > setPen ( Qt : : DashLine ) ;
2016-12-01 21:55:11 +03:00
auto w = width ;
2018-01-20 15:23:28 +03:00
const auto boundary = widget - > margin ( ) - font_h ;
2016-12-01 21:55:11 +03:00
if ( h < ( m_boundingRect . top ( ) - boundary ) )
w = top_width ;
2016-12-04 16:51:27 +03:00
else if ( h > ( bottom + boundary ) )
2016-12-01 21:55:11 +03:00
w = bottom_width ;
_painter - > drawLine ( QLineF ( 0 , h , w , h ) ) ;
2016-11-13 22:02:47 +03:00
}
2016-08-23 22:44:59 +03:00
2018-01-20 15:23:28 +03:00
_painter - > setPen ( profiler_gui : : TEXT_COLOR ) ;
rect . setRect ( 0 , bottom + 2 , width , font_h ) ;
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
if ( ! m_selectedBlocks . empty ( ) )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
if ( m_threadProfiledTime ! = 0 )
{
_painter - > drawText ( rect , Qt : : AlignCenter | Qt : : TextDontClip ,
QString ( " %1 | %2 | %3 calls | %4% of thread profiled time " )
. arg ( m_threadName ) . arg ( m_blockName ) . arg ( m_selectedBlocks . size ( ) )
. arg ( QString : : number ( 100. * ( double ) m_blockTotalDuraion / ( double ) m_threadProfiledTime , ' f ' , 2 ) ) ) ;
}
else
{
_painter - > drawText ( rect , Qt : : AlignCenter | Qt : : TextDontClip ,
QString ( " %1 | %2 | %3 calls | 100% of thread profiled time " )
. arg ( m_threadName ) . arg ( m_blockName ) . arg ( m_selectedBlocks . size ( ) ) ) ;
}
2016-12-04 16:51:27 +03:00
}
else
{
2018-01-20 15:23:28 +03:00
_painter - > drawText ( rect , Qt : : AlignCenter | Qt : : TextDontClip , QString ( " %1 | %2 | 0 calls " ) . arg ( m_threadName ) . arg ( m_blockName ) ) ;
2016-12-04 16:51:27 +03:00
}
2016-08-03 00:06:36 +03:00
_painter - > restore ( ) ;
}
2018-01-20 15:23:28 +03:00
profiler : : thread_id_t GraphicsHistogramItem : : threadId ( ) const
2016-08-03 23:00:04 +03:00
{
return m_threadId ;
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : rebuildSource ( HistRegime _regime )
2017-06-07 02:08:53 +03:00
{
if ( m_regime = = _regime )
rebuildSource ( ) ;
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : rebuildSource ( )
2017-06-07 02:08:53 +03:00
{
if ( m_regime = = Hist_Id )
{
m_regime = Hist_Pointer ;
setSource ( m_threadId , m_blockId ) ;
}
else
{
m_regime = Hist_Id ;
setSource ( m_threadId , m_pSource ) ;
}
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : setSource ( profiler : : thread_id_t _thread_id , const profiler_gui : : EasyItems * _items )
2016-08-03 00:06:36 +03:00
{
2017-03-07 19:59:57 +03:00
if ( m_regime = = Hist_Pointer & & m_threadId = = _thread_id & & m_pSource = = _items )
2016-12-04 16:51:27 +03:00
return ;
2018-01-20 15:23:28 +03:00
cancelAnyJob ( ) ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
m_boundaryTimer . stop ( ) ;
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
m_blockName . clear ( ) ;
m_blockTotalDuraion = 0 ;
2017-03-13 00:43:15 +03:00
m_imageOriginUpdate = m_imageOrigin = 0 ;
m_imageScaleUpdate = m_imageScale = 1 ;
2016-12-04 16:51:27 +03:00
m_selectedBlocks . clear ( ) ;
2018-01-20 15:23:28 +03:00
{ profiler : : BlocksTree : : children_t ( ) . swap ( m_selectedBlocks ) ; }
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
setImageUpdatePermitted ( false ) ;
2017-03-07 19:59:57 +03:00
m_regime = Hist_Pointer ;
2016-08-03 00:06:36 +03:00
m_pSource = _items ;
2016-08-03 23:00:04 +03:00
m_threadId = _thread_id ;
2018-01-20 15:23:28 +03:00
profiler_gui : : set_max ( m_blockId ) ;
2016-08-03 00:06:36 +03:00
2016-12-01 21:55:11 +03:00
if ( m_pSource ! = nullptr )
2016-08-03 00:06:36 +03:00
{
if ( m_pSource - > empty ( ) )
{
m_pSource = nullptr ;
}
2016-08-08 22:17:56 +03:00
else
2016-08-03 00:06:36 +03:00
{
2017-03-13 00:43:15 +03:00
const auto & root = EASY_GLOBALS . profiler_blocks [ _thread_id ] ;
2018-01-20 15:23:28 +03:00
m_threadName = profiler_gui : : decoratedThreadName ( EASY_GLOBALS . use_decorated_thread_name , root , EASY_GLOBALS . hex_thread_id ) ;
2017-03-13 00:43:15 +03:00
if ( root . children . empty ( ) )
m_threadDuration = 0 ;
else
m_threadDuration = easyBlock ( root . children . back ( ) ) . tree . node - > end ( ) - easyBlock ( root . children . front ( ) ) . tree . node - > begin ( ) ;
m_threadProfiledTime = root . profiled_time ;
m_threadWaitTime = root . wait_time ;
m_pProfilerThread = & root ;
m_timeUnits = EASY_GLOBALS . time_units ;
2018-01-20 15:23:28 +03:00
setReady ( false ) ;
m_workerThread = std : : thread ( [ this ] ( const profiler_gui : : EasyItems * _source )
2016-08-03 00:06:36 +03:00
{
2018-01-20 15:23:28 +03:00
m_maxValue = 0 ;
m_minValue = 1e30 ;
2017-03-13 00:43:15 +03:00
2017-03-13 20:30:57 +03:00
bool empty = true ;
2017-03-13 00:43:15 +03:00
for ( const auto & item : * _source )
{
2018-01-20 15:23:28 +03:00
if ( isReady ( ) )
2017-03-13 00:43:15 +03:00
return ;
2018-01-20 15:23:28 +03:00
if ( easyDescriptor ( easyBlock ( item . block ) . tree . node - > id ( ) ) . type ( ) = = profiler : : BlockType : : Event )
2017-03-13 00:43:15 +03:00
continue ;
const auto w = item . width ( ) ;
2018-01-20 15:23:28 +03:00
if ( w > m_maxValue )
m_maxValue = w ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
if ( w < m_minValue )
m_minValue = w ;
2017-03-13 00:43:15 +03:00
2017-03-13 20:30:57 +03:00
empty = false ;
}
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
if ( ( m_maxValue - m_minValue ) < 1e-3 )
2017-03-13 20:30:57 +03:00
{
2018-01-20 15:23:28 +03:00
if ( m_minValue > 0.1 )
2017-03-13 20:30:57 +03:00
{
2018-01-20 15:23:28 +03:00
m_minValue - = 0.1 ;
2017-03-13 00:43:15 +03:00
}
2017-03-13 20:30:57 +03:00
else
2017-03-13 00:43:15 +03:00
{
2018-01-20 15:23:28 +03:00
m_maxValue = 0.1 ;
m_minValue = 0 ;
2017-03-13 00:43:15 +03:00
}
}
2018-01-20 15:23:28 +03:00
m_topValue = m_maxValue ;
m_bottomValue = m_minValue ;
2017-03-13 00:43:15 +03:00
2017-03-13 20:30:57 +03:00
if ( ! empty )
{
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
2017-03-13 20:30:57 +03:00
}
else
{
m_topDurationStr . clear ( ) ;
m_bottomDurationStr . clear ( ) ;
}
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
setReady ( true ) ;
2017-03-13 00:43:15 +03:00
} , m_pSource ) ;
2018-01-20 15:23:28 +03:00
startTimer ( ) ;
2017-03-13 00:43:15 +03:00
show ( ) ;
2016-08-03 00:06:36 +03:00
}
}
if ( m_pSource = = nullptr )
{
2016-12-12 22:28:54 +03:00
m_pProfilerThread = nullptr ;
2017-03-07 00:29:34 +03:00
m_topDurationStr . clear ( ) ;
m_bottomDurationStr . clear ( ) ;
2016-12-04 16:51:27 +03:00
m_threadName . clear ( ) ;
2016-08-03 00:06:36 +03:00
hide ( ) ;
}
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : setSource ( profiler : : thread_id_t _thread_id , profiler : : block_id_t _block_id )
2016-12-04 16:51:27 +03:00
{
2017-03-07 19:59:57 +03:00
if ( m_regime = = Hist_Id & & m_threadId = = _thread_id & & m_blockId = = _block_id )
2016-12-04 16:51:27 +03:00
return ;
2018-01-20 15:23:28 +03:00
cancelAnyJob ( ) ;
setImageUpdatePermitted ( false ) ; // Set to false because m_workerThread have to parse input data first. This will be set to true when m_workerThread finish - see onTimeout()
2017-03-07 19:59:57 +03:00
m_regime = Hist_Id ;
2016-12-04 16:51:27 +03:00
2017-03-13 00:43:15 +03:00
m_boundaryTimer . stop ( ) ;
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
m_pSource = nullptr ;
m_topDurationStr . clear ( ) ;
m_bottomDurationStr . clear ( ) ;
m_blockName . clear ( ) ;
m_blockTotalDuraion = 0 ;
2017-03-13 00:43:15 +03:00
m_imageOriginUpdate = m_imageOrigin = 0 ;
m_imageScaleUpdate = m_imageScale = 1 ;
2016-12-04 16:51:27 +03:00
m_selectedBlocks . clear ( ) ;
2018-01-20 15:23:28 +03:00
{ profiler : : BlocksTree : : children_t ( ) . swap ( m_selectedBlocks ) ; }
2016-12-04 16:51:27 +03:00
m_threadId = _thread_id ;
m_blockId = _block_id ;
2018-01-20 15:23:28 +03:00
if ( m_threadId ! = 0 & & ! profiler_gui : : is_max ( m_blockId ) )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
m_blockName = profiler_gui : : toUnicode ( easyDescriptor ( m_blockId ) . name ( ) ) ;
2017-06-05 21:26:10 +03:00
2016-12-04 16:51:27 +03:00
const auto & root = EASY_GLOBALS . profiler_blocks [ _thread_id ] ;
2018-01-20 15:23:28 +03:00
m_threadName = profiler_gui : : decoratedThreadName ( EASY_GLOBALS . use_decorated_thread_name , root , EASY_GLOBALS . hex_thread_id ) ;
2017-06-05 21:26:10 +03:00
m_pProfilerThread = & root ;
m_timeUnits = EASY_GLOBALS . time_units ;
2016-12-04 16:51:27 +03:00
if ( root . children . empty ( ) )
2017-06-05 21:26:10 +03:00
{
2016-12-04 16:51:27 +03:00
m_threadDuration = 0 ;
2017-06-05 21:26:10 +03:00
m_threadProfiledTime = 0 ;
m_threadWaitTime = 0 ;
2018-01-20 15:23:28 +03:00
m_topValue = m_maxValue = 0 ;
m_bottomValue = m_minValue = 1e30 ;
2017-06-05 21:26:10 +03:00
2018-01-20 15:23:28 +03:00
setImageUpdatePermitted ( true ) ;
setReady ( true ) ;
2017-06-05 21:26:10 +03:00
}
2016-12-04 16:51:27 +03:00
else
2017-06-05 21:26:10 +03:00
{
2016-12-04 16:51:27 +03:00
m_threadDuration = easyBlock ( root . children . back ( ) ) . tree . node - > end ( ) - easyBlock ( root . children . front ( ) ) . tree . node - > begin ( ) ;
2017-06-05 21:26:10 +03:00
m_threadProfiledTime = root . profiled_time ;
m_threadWaitTime = root . wait_time ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
setReady ( false ) ;
m_workerThread = std : : thread ( [ this ] ( decltype ( root ) profiler_thread , profiler : : block_index_t selected_block , bool _showOnlyTopLevelBlocks )
2017-06-05 21:26:10 +03:00
{
2018-01-20 15:23:28 +03:00
using Stack = std : : vector < std : : pair < profiler : : block_index_t , profiler : : block_index_t > > ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
m_maxValue = 0 ;
m_minValue = 1e30 ;
2017-06-05 21:26:10 +03:00
//const auto& profiler_thread = EASY_GLOBALS.profiler_blocks[m_threadId];
Stack stack ;
stack . reserve ( profiler_thread . depth ) ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
const bool has_selected_block = ! profiler_gui : : is_max ( selected_block ) ;
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
for ( auto frame : profiler_thread . children )
2016-12-04 16:51:27 +03:00
{
2017-06-05 21:26:10 +03:00
const auto & frame_block = easyBlock ( frame ) . tree ;
if ( frame_block . node - > id ( ) = = m_blockId | | ( ! has_selected_block & & m_blockId = = easyDescriptor ( frame_block . node - > id ( ) ) . id ( ) ) )
{
m_selectedBlocks . push_back ( frame ) ;
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
const auto w = frame_block . node - > duration ( ) ;
2018-01-20 15:23:28 +03:00
if ( w > m_maxValue )
m_maxValue = w ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
if ( w < m_minValue )
m_minValue = w ;
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
m_blockTotalDuraion + = w ;
}
2017-03-13 00:43:15 +03:00
2017-06-07 02:08:53 +03:00
if ( _showOnlyTopLevelBlocks )
continue ;
2018-01-20 15:23:28 +03:00
stack . emplace_back ( frame , 0U ) ;
2017-06-05 21:26:10 +03:00
while ( ! stack . empty ( ) )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
if ( isReady ( ) )
2017-03-13 00:43:15 +03:00
return ;
2017-06-05 21:26:10 +03:00
auto & top = stack . back ( ) ;
const auto & top_children = easyBlock ( top . first ) . tree . children ;
const auto stack_size = stack . size ( ) ;
for ( auto end = top_children . size ( ) ; top . second < end ; + + top . second )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
if ( isReady ( ) )
2017-06-05 21:26:10 +03:00
return ;
const auto child_index = top_children [ top . second ] ;
const auto & child = easyBlock ( child_index ) . tree ;
if ( child . node - > id ( ) = = m_blockId | | ( ! has_selected_block & & m_blockId = = easyDescriptor ( child . node - > id ( ) ) . id ( ) ) )
{
m_selectedBlocks . push_back ( child_index ) ;
const auto w = child . node - > duration ( ) ;
2018-01-20 15:23:28 +03:00
if ( w > m_maxValue )
m_maxValue = w ;
2017-06-05 21:26:10 +03:00
2018-01-20 15:23:28 +03:00
if ( w < m_minValue )
m_minValue = w ;
2017-06-05 21:26:10 +03:00
m_blockTotalDuraion + = w ;
}
2016-12-04 16:51:27 +03:00
2017-06-05 21:26:10 +03:00
if ( ! child . children . empty ( ) )
{
+ + top . second ;
2018-01-20 15:23:28 +03:00
stack . emplace_back ( child_index , 0U ) ;
2017-06-05 21:26:10 +03:00
break ;
}
2016-12-04 16:51:27 +03:00
}
2017-06-05 21:26:10 +03:00
if ( stack_size = = stack . size ( ) )
2016-12-04 16:51:27 +03:00
{
2017-06-05 21:26:10 +03:00
stack . pop_back ( ) ;
2016-12-04 16:51:27 +03:00
}
}
}
2017-03-13 20:30:57 +03:00
2017-06-05 21:26:10 +03:00
if ( m_selectedBlocks . empty ( ) )
2017-03-13 20:30:57 +03:00
{
2017-06-05 21:26:10 +03:00
m_topDurationStr . clear ( ) ;
m_bottomDurationStr . clear ( ) ;
}
else
{
if ( has_selected_block )
2017-03-13 20:30:57 +03:00
{
2017-06-05 21:26:10 +03:00
const auto & item = easyBlock ( selected_block ) . tree ;
if ( * item . node - > name ( ) ! = 0 )
2018-01-20 15:23:28 +03:00
m_blockName = profiler_gui : : toUnicode ( item . node - > name ( ) ) ;
2017-03-13 20:30:57 +03:00
}
2017-06-05 21:26:10 +03:00
2018-01-20 15:23:28 +03:00
m_maxValue * = 1e-3 ;
m_minValue * = 1e-3 ;
2017-06-05 21:26:10 +03:00
2018-01-20 15:23:28 +03:00
if ( ( m_maxValue - m_minValue ) < 1e-3 )
2017-03-13 20:30:57 +03:00
{
2018-01-20 15:23:28 +03:00
if ( m_minValue > 0.1 )
2017-06-05 21:26:10 +03:00
{
2018-01-20 15:23:28 +03:00
m_minValue - = 0.1 ;
2017-06-05 21:26:10 +03:00
}
else
{
2018-01-20 15:23:28 +03:00
m_maxValue = 0.1 ;
m_minValue = 0 ;
2017-06-05 21:26:10 +03:00
}
2017-03-13 20:30:57 +03:00
}
2017-06-05 21:26:10 +03:00
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_maxValue , 3 ) ;
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_minValue , 3 ) ;
2017-03-13 20:30:57 +03:00
}
2018-01-20 15:23:28 +03:00
m_topValue = m_maxValue ;
m_bottomValue = m_minValue ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
setReady ( true ) ;
2017-03-07 00:29:34 +03:00
2017-06-07 02:08:53 +03:00
} , std : : ref ( root ) , EASY_GLOBALS . selected_block , EASY_GLOBALS . display_only_frames_on_histogram ) ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
startTimer ( ) ;
2017-06-05 21:26:10 +03:00
}
2016-12-04 16:51:27 +03:00
2017-03-13 00:43:15 +03:00
show ( ) ;
2016-12-04 16:51:27 +03:00
}
else
{
2016-12-12 22:28:54 +03:00
m_pProfilerThread = nullptr ;
2016-12-04 16:51:27 +03:00
m_threadName . clear ( ) ;
hide ( ) ;
}
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : validateName ( )
2016-12-14 21:47:33 +03:00
{
if ( m_threadName . isEmpty ( ) )
return ;
2018-01-20 15:23:28 +03:00
m_threadName = profiler_gui : : decoratedThreadName ( EASY_GLOBALS . use_decorated_thread_name , EASY_GLOBALS . profiler_blocks [ m_threadId ] , EASY_GLOBALS . hex_thread_id ) ;
2016-12-14 21:47:33 +03:00
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : pickTopValue ( )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
const bool result = Parent : : pickTopValue ( ) ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
if ( result & & ! m_topDurationStr . isEmpty ( ) )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
scene ( ) - > update ( ) ; // to update top-boundary text right now
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
return result ;
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : increaseTopValue ( )
2017-03-07 00:29:34 +03:00
{
2018-01-20 15:23:28 +03:00
const bool result = Parent : : increaseTopValue ( ) ;
if ( result & & ! m_topDurationStr . isEmpty ( ) )
2017-03-13 00:43:15 +03:00
{
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
2017-03-13 00:43:15 +03:00
scene ( ) - > update ( ) ; // to update top-boundary text right now
}
2018-01-20 15:23:28 +03:00
return result ;
2017-03-13 00:43:15 +03:00
}
2017-03-07 00:29:34 +03:00
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : decreaseTopValue ( )
2017-03-13 00:43:15 +03:00
{
2018-01-20 15:23:28 +03:00
const bool result = Parent : : decreaseTopValue ( ) ;
2017-03-07 00:29:34 +03:00
2018-01-20 15:23:28 +03:00
if ( result & & ! m_topDurationStr . isEmpty ( ) )
{
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
2017-03-07 00:29:34 +03:00
scene ( ) - > update ( ) ; // to update top-boundary text right now
}
2018-01-20 15:23:28 +03:00
return result ;
2017-03-07 00:29:34 +03:00
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : pickBottomValue ( )
2017-03-07 00:29:34 +03:00
{
2018-01-20 15:23:28 +03:00
const bool result = Parent : : pickBottomValue ( ) ;
if ( result & & ! m_bottomDurationStr . isEmpty ( ) )
2017-03-13 00:43:15 +03:00
{
2018-01-20 15:23:28 +03:00
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
2017-03-13 00:43:15 +03:00
scene ( ) - > update ( ) ; // to update top-boundary text right now
}
2018-01-20 15:23:28 +03:00
return result ;
2017-03-13 00:43:15 +03:00
}
2017-03-07 00:29:34 +03:00
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : increaseBottomValue ( )
2017-03-13 00:43:15 +03:00
{
2018-01-20 15:23:28 +03:00
const bool result = Parent : : increaseBottomValue ( ) ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
if ( result & & ! m_bottomDurationStr . isEmpty ( ) )
{
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
scene ( ) - > update ( ) ; // to update top-boundary text right now
2017-03-07 00:29:34 +03:00
}
2018-01-20 15:23:28 +03:00
return result ;
2017-03-07 00:29:34 +03:00
}
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : decreaseBottomValue ( )
2017-03-07 00:29:34 +03:00
{
2018-01-20 15:23:28 +03:00
const bool result = Parent : : decreaseBottomValue ( ) ;
2017-03-07 00:29:34 +03:00
2018-01-20 15:23:28 +03:00
if ( result & & ! m_bottomDurationStr . isEmpty ( ) )
{
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
2017-03-07 00:29:34 +03:00
scene ( ) - > update ( ) ; // to update top-boundary text right now
}
2018-01-20 15:23:28 +03:00
return result ;
2017-03-07 00:29:34 +03:00
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : pickFrameTime ( qreal _y ) const
2017-03-07 00:29:34 +03:00
{
2018-01-20 15:23:28 +03:00
if ( isImageUpdatePermitted ( ) & & m_boundingRect . top ( ) < _y & & _y < m_boundingRect . bottom ( ) & & ! m_topDurationStr . isEmpty ( ) )
2017-03-07 01:09:27 +03:00
{
2018-01-20 15:23:28 +03:00
const auto frame_time = m_bottomValue + ( m_topValue - m_bottomValue ) * ( m_boundingRect . bottom ( ) - _y ) / m_boundingRect . height ( ) ;
EASY_GLOBALS . frame_time = static_cast < decltype ( EASY_GLOBALS . frame_time ) > ( frame_time ) ;
2017-03-13 20:30:57 +03:00
emit EASY_GLOBALS . events . expectedFrameTimeChanged ( ) ;
2017-03-07 01:09:27 +03:00
}
}
2017-03-07 00:29:34 +03:00
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : onValueChanged ( )
2017-03-13 00:43:15 +03:00
{
const auto widget = static_cast < const EasyGraphicsScrollbar * > ( scene ( ) - > parent ( ) ) ;
if ( ! widget - > bindMode ( ) )
return ;
m_boundaryTimer . stop ( ) ;
const auto sliderWidth_inv = 1.0 / widget - > sliderWidth ( ) ;
const auto k = widget - > range ( ) * sliderWidth_inv ;
const auto deltaScale = m_imageScaleUpdate < k ? ( k / m_imageScaleUpdate ) : ( m_imageScaleUpdate / k ) ;
2018-01-20 15:23:28 +03:00
if ( deltaScale > 4 )
{
2017-03-13 00:43:15 +03:00
updateImage ( ) ;
return ;
}
const auto deltaOffset = ( widget - > value ( ) - m_imageOriginUpdate ) * sliderWidth_inv ;
2018-01-20 15:23:28 +03:00
if ( deltaOffset < 1.5 | | deltaOffset > 4.5 )
{
2017-03-13 00:43:15 +03:00
updateImage ( ) ;
return ;
}
2018-01-20 15:23:28 +03:00
m_boundaryTimer . start ( ) ;
2017-03-13 00:43:15 +03:00
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : onModeChanged ( )
2017-03-13 20:30:57 +03:00
{
2018-01-20 15:23:28 +03:00
if ( ! isImageUpdatePermitted ( ) )
2017-03-13 20:30:57 +03:00
return ;
const auto widget = static_cast < const EasyGraphicsScrollbar * > ( scene ( ) - > parent ( ) ) ;
if ( ! widget - > bindMode ( ) & & EASY_GLOBALS . auto_adjust_histogram_height )
{
2018-01-20 15:23:28 +03:00
m_topValue = m_maxValue ;
m_bottomValue = m_minValue ;
2017-03-13 20:30:57 +03:00
}
m_boundaryTimer . stop ( ) ;
updateImage ( ) ;
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
bool GraphicsHistogramItem : : updateImage ( )
2017-03-13 00:43:15 +03:00
{
2018-01-20 15:23:28 +03:00
if ( ! Parent : : updateImage ( ) )
return false ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
const auto widget = static_cast < const EasyGraphicsScrollbar * > ( scene ( ) - > parent ( ) ) ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
m_imageScaleUpdate = widget - > range ( ) / widget - > sliderWidth ( ) ;
m_imageOriginUpdate = widget - > bindMode ( ) ? ( widget - > value ( ) - widget - > sliderWidth ( ) * 3 ) : widget - > minimum ( ) ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
m_workerThread = std : : thread ( & This : : updateImageAsync , this , m_boundingRect , m_regime , widget - > getWindowScale ( ) ,
widget - > minimum ( ) , widget - > maximum ( ) , widget - > range ( ) , widget - > value ( ) , widget - > sliderWidth ( ) ,
m_topValue , m_bottomValue , widget - > bindMode ( ) , EASY_GLOBALS . frame_time , EASY_GLOBALS . begin_time ,
EASY_GLOBALS . auto_adjust_histogram_height ) ;
2017-03-13 00:43:15 +03:00
2018-01-20 15:23:28 +03:00
return true ;
2017-03-13 00:43:15 +03:00
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : onImageUpdated ( )
2017-03-07 00:29:34 +03:00
{
2018-01-20 15:23:28 +03:00
if ( EASY_GLOBALS . auto_adjust_histogram_height & & ! m_topDurationStr . isEmpty ( ) )
2016-12-04 16:51:27 +03:00
{
2018-01-20 15:23:28 +03:00
m_topValue = m_workerTopDuration ;
m_bottomValue = m_workerBottomDuration ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
m_topDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_topValue , 3 ) ;
m_bottomDurationStr = profiler_gui : : timeStringReal ( m_timeUnits , m_bottomValue , 3 ) ;
}
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
void GraphicsHistogramItem : : updateImageAsync ( QRectF _boundingRect , HistRegime _regime , qreal _current_scale ,
qreal _minimum , qreal _maximum , qreal _range ,
qreal _value , qreal _width , qreal _top_duration , qreal _bottom_duration ,
bool _bindMode , float _frame_time , profiler : : timestamp_t _begin_time , bool _autoAdjustHist )
2017-03-13 00:43:15 +03:00
{
const auto bottom = _boundingRect . height ( ) ; //_boundingRect.bottom();
const auto screenWidth = _boundingRect . width ( ) * _current_scale ;
const auto maxColumnHeight = _boundingRect . height ( ) ;
const auto viewScale = _range / _width ;
if ( _bindMode )
{
2017-03-13 20:30:57 +03:00
m_workerImageScale = viewScale ;
m_workerImageOrigin = _value - _width * 3 ;
m_workerImage = new QImage ( screenWidth * 7 + 0.5 , _boundingRect . height ( ) , QImage : : Format_ARGB32 ) ;
2017-03-13 00:43:15 +03:00
}
else
{
2017-03-13 20:30:57 +03:00
m_workerImageScale = 1 ;
m_workerImageOrigin = _minimum ;
m_workerImage = new QImage ( screenWidth + 0.5 , _boundingRect . height ( ) , QImage : : Format_ARGB32 ) ;
2017-03-13 00:43:15 +03:00
}
2017-03-13 20:30:57 +03:00
m_workerImage - > fill ( 0 ) ;
QPainter p ( m_workerImage ) ;
2016-12-04 16:51:27 +03:00
p . setPen ( Qt : : NoPen ) ;
QRectF rect ;
QBrush brush ( Qt : : SolidPattern ) ;
QRgb previousColor = 0 ;
qreal previous_x = - 1e30 , previous_h = - 1e30 , offset = 0. ;
auto realScale = _current_scale ;
const bool gotFrame = _frame_time > 1e-6 f ;
qreal frameCoeff = 1 ;
if ( gotFrame )
{
2017-03-13 00:43:15 +03:00
if ( _frame_time < = _bottom_duration )
frameCoeff = _boundingRect . height ( ) ;
2016-12-04 16:51:27 +03:00
else
2016-12-07 22:29:16 +03:00
frameCoeff = 0.9 / _frame_time ;
2016-12-04 16:51:27 +03:00
}
2018-01-20 15:23:28 +03:00
using estd : : sqr ;
2016-12-04 16:51:27 +03:00
auto const calculate_color = gotFrame ? calculate_color2 : calculate_color1 ;
2017-03-13 00:43:15 +03:00
auto const k = gotFrame ? sqr ( sqr ( frameCoeff ) ) : 1.0 / _boundingRect . height ( ) ;
2016-12-04 16:51:27 +03:00
2017-03-07 19:59:57 +03:00
if ( _regime = = Hist_Pointer )
2016-12-04 16:51:27 +03:00
{
const auto & items = * m_pSource ;
if ( items . empty ( ) )
return ;
2017-03-07 19:59:57 +03:00
auto first = items . begin ( ) ;
2017-03-13 00:43:15 +03:00
if ( _bindMode )
{
2017-03-13 20:30:57 +03:00
_minimum = m_workerImageOrigin ;
_maximum = m_workerImageOrigin + _width * 7 ;
2017-03-13 00:43:15 +03:00
realScale * = viewScale ;
offset = _minimum * realScale ;
2018-01-20 15:23:28 +03:00
first = std : : lower_bound ( items . begin ( ) , items . end ( ) , _minimum , [ ] ( const profiler_gui : : EasyBlockItem & _item , qreal _value )
2017-03-13 00:43:15 +03:00
{
return _item . left ( ) < _value ;
} ) ;
if ( first ! = items . end ( ) )
{
if ( first ! = items . begin ( ) )
- - first ;
}
else
{
first = items . begin ( ) + items . size ( ) - 1 ;
}
2017-03-13 20:30:57 +03:00
if ( _autoAdjustHist )
{
const auto maxVal = _value + _width ;
decltype ( _top_duration ) maxDuration = 0 ;
decltype ( _bottom_duration ) minDuration = 1e30 ;
size_t iterations = 0 ;
for ( auto it = first , end = items . end ( ) ; it ! = end ; + + it )
{
// Draw rectangle
if ( it - > left ( ) > maxVal )
break ;
if ( it - > right ( ) < _value )
continue ;
if ( maxDuration < it - > width ( ) )
maxDuration = it - > width ( ) ;
if ( minDuration > it - > width ( ) )
minDuration = it - > width ( ) ;
+ + iterations ;
}
2018-01-20 15:23:28 +03:00
if ( iterations ! = 0 )
2017-03-13 20:30:57 +03:00
{
_top_duration = maxDuration ;
_bottom_duration = minDuration ;
if ( ( _top_duration - _bottom_duration ) < 1e-3 )
{
if ( _bottom_duration > 0.1 )
{
_bottom_duration - = 0.1 ;
}
else
{
_top_duration = 0.1 ;
_bottom_duration = 0 ;
}
}
}
}
2017-03-13 00:43:15 +03:00
}
2016-12-04 16:51:27 +03:00
2017-03-13 20:30:57 +03:00
const auto dtime = _top_duration - _bottom_duration ;
2018-01-20 15:23:28 +03:00
const auto coeff = _boundingRect . height ( ) / ( dtime > 1e-3 ? dtime : 1. ) ;
2017-03-13 20:30:57 +03:00
2017-03-07 19:59:57 +03:00
for ( auto it = first , end = items . end ( ) ; it ! = end ; + + it )
2016-12-04 16:51:27 +03:00
{
// Draw rectangle
2017-03-07 19:59:57 +03:00
if ( it - > left ( ) > _maximum )
2016-12-04 16:51:27 +03:00
break ;
2017-03-07 19:59:57 +03:00
if ( it - > right ( ) < _minimum )
2016-12-04 16:51:27 +03:00
continue ;
const qreal item_x = it - > left ( ) * realScale - offset ;
2018-01-20 15:23:28 +03:00
const qreal item_w = std : : max ( it - > width ( ) * realScale , 1.0 ) ;
2016-12-04 16:51:27 +03:00
const qreal item_r = item_x + item_w ;
2017-03-13 00:43:15 +03:00
const qreal h = it - > width ( ) < = _bottom_duration ? HIST_COLUMN_MIN_HEIGHT :
2018-01-20 15:23:28 +03:00
( it - > width ( ) > _top_duration ? maxColumnHeight : ( it - > width ( ) - _bottom_duration ) * coeff ) ;
2016-12-04 16:51:27 +03:00
if ( h < previous_h & & item_r < previous_x )
continue ;
2016-12-07 22:29:16 +03:00
const auto col = calculate_color ( h , it - > width ( ) , k ) ;
2016-12-04 16:51:27 +03:00
const auto color = 0x00ffffff & QColor : : fromHsvF ( ( 1.0 - col ) * 0.375 , 0.85 , 0.85 ) . rgb ( ) ;
if ( previousColor ! = color )
{
// Set background color brush for rectangle
previousColor = color ;
brush . setColor ( QColor : : fromRgba ( 0xc0000000 | color ) ) ;
p . setBrush ( brush ) ;
}
rect . setRect ( item_x , bottom - h , item_w , h ) ;
p . drawRect ( rect ) ;
previous_x = item_r ;
previous_h = h ;
}
}
else
{
2017-03-13 00:43:15 +03:00
auto first = m_selectedBlocks . begin ( ) ;
if ( _bindMode )
{
2017-03-13 20:30:57 +03:00
_minimum = m_workerImageOrigin ;
_maximum = m_workerImageOrigin + _width * 7 ;
2017-03-13 00:43:15 +03:00
realScale * = viewScale ;
offset = _minimum * 1e3 * realScale ;
2018-01-20 15:23:28 +03:00
first = std : : lower_bound ( m_selectedBlocks . begin ( ) , m_selectedBlocks . end ( ) , _minimum * 1e3 + _begin_time , [ ] ( profiler : : block_index_t _item , qreal _value )
2017-03-13 00:43:15 +03:00
{
return easyBlock ( _item ) . tree . node - > begin ( ) < _value ;
} ) ;
if ( first ! = m_selectedBlocks . end ( ) )
{
if ( first ! = m_selectedBlocks . begin ( ) )
- - first ;
}
else
{
first = m_selectedBlocks . begin ( ) + m_selectedBlocks . size ( ) - 1 ;
}
2017-03-13 20:30:57 +03:00
_minimum * = 1e3 ;
_maximum * = 1e3 ;
if ( _autoAdjustHist )
{
const auto minVal = _value * 1e3 , maxVal = ( _value + _width ) * 1e3 ;
decltype ( _top_duration ) maxDuration = 0 ;
decltype ( _bottom_duration ) minDuration = 1e30 ;
size_t iterations = 0 ;
for ( auto it = first , end = m_selectedBlocks . end ( ) ; it ! = end ; + + it )
{
const auto item = easyBlock ( * it ) . tree . node ;
const auto beginTime = item - > begin ( ) - _begin_time ;
if ( beginTime > maxVal )
break ;
const auto endTime = item - > end ( ) - _begin_time ;
if ( endTime < minVal )
continue ;
const qreal duration = item - > duration ( ) * 1e-3 ;
if ( maxDuration < duration )
maxDuration = duration ;
if ( minDuration > duration )
minDuration = duration ;
+ + iterations ;
}
2018-01-20 15:23:28 +03:00
if ( iterations ! = 0 )
2017-03-13 20:30:57 +03:00
{
_top_duration = maxDuration ;
_bottom_duration = minDuration ;
if ( ( _top_duration - _bottom_duration ) < 1e-3 )
{
if ( _bottom_duration > 0.1 )
{
_bottom_duration - = 0.1 ;
}
else
{
_top_duration = 0.1 ;
_bottom_duration = 0 ;
}
}
}
}
}
else
{
_minimum * = 1e3 ;
_maximum * = 1e3 ;
2017-03-13 00:43:15 +03:00
}
2017-03-13 20:30:57 +03:00
const auto dtime = _top_duration - _bottom_duration ;
2018-01-20 15:23:28 +03:00
const auto coeff = _boundingRect . height ( ) / ( dtime > 1e-3 ? dtime : 1. ) ;
2016-12-04 16:51:27 +03:00
2017-03-13 00:43:15 +03:00
for ( auto it = first , end = m_selectedBlocks . end ( ) ; it ! = end ; + + it )
2016-12-04 16:51:27 +03:00
{
// Draw rectangle
const auto item = easyBlock ( * it ) . tree . node ;
const auto beginTime = item - > begin ( ) - _begin_time ;
2017-03-07 19:59:57 +03:00
if ( beginTime > _maximum )
2016-12-04 16:51:27 +03:00
break ;
const auto endTime = item - > end ( ) - _begin_time ;
2017-03-07 19:59:57 +03:00
if ( endTime < _minimum )
2016-12-04 16:51:27 +03:00
continue ;
const qreal duration = item - > duration ( ) * 1e-3 ;
const qreal item_x = ( beginTime * realScale - offset ) * 1e-3 ;
2018-01-20 15:23:28 +03:00
const qreal item_w = std : : max ( duration * realScale , 1.0 ) ;
2016-12-04 16:51:27 +03:00
const qreal item_r = item_x + item_w ;
2017-03-13 00:43:15 +03:00
const auto h = duration < = _bottom_duration ? HIST_COLUMN_MIN_HEIGHT :
2018-01-20 15:23:28 +03:00
( duration > _top_duration ? maxColumnHeight : ( duration - _bottom_duration ) * coeff ) ;
2016-12-04 16:51:27 +03:00
if ( h < previous_h & & item_r < previous_x )
continue ;
2016-12-07 22:29:16 +03:00
const auto col = calculate_color ( h , duration , k ) ;
2016-12-04 16:51:27 +03:00
const auto color = 0x00ffffff & QColor : : fromHsvF ( ( 1.0 - col ) * 0.375 , 0.85 , 0.85 ) . rgb ( ) ;
if ( previousColor ! = color )
{
// Set background color brush for rectangle
previousColor = color ;
brush . setColor ( QColor : : fromRgba ( 0xc0000000 | color ) ) ;
p . setBrush ( brush ) ;
}
rect . setRect ( item_x , bottom - h , item_w , h ) ;
p . drawRect ( rect ) ;
previous_x = item_r ;
previous_h = h ;
}
2016-08-03 00:06:36 +03:00
}
2017-03-13 20:30:57 +03:00
m_workerTopDuration = _top_duration ;
m_workerBottomDuration = _bottom_duration ;
2018-01-20 15:23:28 +03:00
setReady ( true ) ;
2016-08-03 00:06:36 +03:00
}
//////////////////////////////////////////////////////////////////////////
2018-01-20 15:23:28 +03:00
EasyGraphicsScrollbar : : EasyGraphicsScrollbar ( bool _fixedHeight , int _height , QWidget * _parent )
2016-07-10 01:29:09 +03:00
: Parent ( _parent )
, m_minimumValue ( 0 )
, m_maximumValue ( 500 )
, m_value ( 10 )
2016-07-31 13:13:48 +03:00
, m_windowScale ( 1 )
, m_mouseButtons ( Qt : : NoButton )
2016-07-10 01:29:09 +03:00
, m_slider ( nullptr )
2018-01-20 15:23:28 +03:00
, m_selectionIndicator ( nullptr )
2017-03-07 00:29:34 +03:00
, m_histogramItem ( nullptr )
2018-01-20 15:23:28 +03:00
, m_fontHeight ( 0 )
2016-07-31 13:13:48 +03:00
, m_bScrolling ( false )
2016-11-30 22:37:11 +03:00
, m_bBindMode ( false )
2016-12-04 16:51:27 +03:00
, m_bLocked ( false )
2016-07-10 01:29:09 +03:00
{
setCacheMode ( QGraphicsView : : CacheNone ) ;
setTransformationAnchor ( QGraphicsView : : AnchorUnderMouse ) ;
2016-08-08 23:39:37 +03:00
//setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
setViewportUpdateMode ( QGraphicsView : : FullViewportUpdate ) ;
2016-07-10 01:29:09 +03:00
setOptimizationFlag ( QGraphicsView : : DontSavePainterState , true ) ;
setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
setVerticalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
2016-08-03 00:06:36 +03:00
setContentsMargins ( 0 , 0 , 0 , 0 ) ;
2016-07-10 01:29:09 +03:00
2018-01-20 15:23:28 +03:00
setScene ( new QGraphicsScene ( this ) ) ;
2016-12-04 16:51:27 +03:00
2018-01-20 15:23:28 +03:00
m_fontHeight = QFontMetrics ( font ( ) ) . height ( ) ;
const int sceneHeight = _height - 2 ;
scene ( ) - > setSceneRect ( 0 , - ( sceneHeight > > 1 ) , 500 , sceneHeight ) ;
if ( _fixedHeight )
setFixedHeight ( _height ) ;
m_histogramItem = new GraphicsHistogramItem ( ) ;
scene ( ) - > addItem ( m_histogramItem ) ;
2016-07-10 01:29:09 +03:00
2017-03-07 00:29:34 +03:00
m_histogramItem - > setPos ( 0 , 0 ) ;
2018-01-20 15:23:28 +03:00
m_histogramItem - > setBoundingRect ( 0 , scene ( ) - > sceneRect ( ) . top ( ) + margin ( ) , scene ( ) - > width ( ) , sceneHeight - margins ( ) - 1 ) ;
2017-03-07 00:29:34 +03:00
m_histogramItem - > hide ( ) ;
2016-07-10 01:29:09 +03:00
2018-01-20 15:23:28 +03:00
m_selectionIndicator = new GraphicsSliderItem ( 6 , false ) ;
scene ( ) - > addItem ( m_selectionIndicator ) ;
m_selectionIndicator - > setPos ( 0 , 0 ) ;
m_selectionIndicator - > setColor ( 0x40000000 | profiler_gui : : CHRONOMETER_COLOR . rgba ( ) ) ;
m_selectionIndicator - > hide ( ) ;
m_slider = new GraphicsSliderItem ( 6 , true ) ;
scene ( ) - > addItem ( m_slider ) ;
2016-08-03 00:06:36 +03:00
2016-08-23 22:44:59 +03:00
m_slider - > setPos ( 0 , 0 ) ;
m_slider - > setColor ( 0x40c0c0c0 ) ;
2016-08-24 01:00:24 +03:00
m_slider - > hide ( ) ;
2016-08-03 00:06:36 +03:00
2018-01-20 15:23:28 +03:00
connect ( & EASY_GLOBALS . events , & profiler_gui : : EasyGlobalSignals : : expectedFrameTimeChanged , [ this ] ( )
2016-12-04 16:51:27 +03:00
{
2017-03-07 00:29:34 +03:00
if ( m_histogramItem - > isVisible ( ) )
2017-03-13 20:30:57 +03:00
{
2017-03-07 00:29:34 +03:00
m_histogramItem - > updateImage ( ) ;
2017-03-13 20:30:57 +03:00
scene ( ) - > update ( ) ;
}
} ) ;
2018-01-20 15:23:28 +03:00
connect ( & EASY_GLOBALS . events , & profiler_gui : : EasyGlobalSignals : : autoAdjustHistogramChanged , [ this ] ( )
2017-03-13 20:30:57 +03:00
{
if ( m_histogramItem - > isVisible ( ) )
m_histogramItem - > onModeChanged ( ) ;
2016-12-04 16:51:27 +03:00
} ) ;
2016-11-13 22:02:47 +03:00
2018-01-20 15:23:28 +03:00
connect ( & EASY_GLOBALS . events , & profiler_gui : : EasyGlobalSignals : : displayOnlyFramesOnHistogramChanged , [ this ] ( )
2017-06-07 02:08:53 +03:00
{
if ( m_histogramItem - > isVisible ( ) )
2018-01-20 15:23:28 +03:00
m_histogramItem - > rebuildSource ( GraphicsHistogramItem : : Hist_Id ) ;
2017-06-07 02:08:53 +03:00
} ) ;
2018-01-20 15:23:28 +03:00
connect ( & EASY_GLOBALS . events , & profiler_gui : : EasyGlobalSignals : : threadNameDecorationChanged , this , & This : : onThreadViewChanged ) ;
connect ( & EASY_GLOBALS . events , & profiler_gui : : EasyGlobalSignals : : hexThreadIdChanged , this , & This : : onThreadViewChanged ) ;
2016-12-14 21:47:33 +03:00
2016-07-31 13:13:48 +03:00
centerOn ( 0 , 0 ) ;
2016-07-10 01:29:09 +03:00
}
2016-08-18 23:26:41 +03:00
EasyGraphicsScrollbar : : ~ EasyGraphicsScrollbar ( )
2016-07-10 01:29:09 +03:00
{
}
//////////////////////////////////////////////////////////////////////////
2017-06-05 21:26:10 +03:00
void EasyGraphicsScrollbar : : onThreadViewChanged ( )
{
if ( m_histogramItem - > isVisible ( ) )
{
m_histogramItem - > validateName ( ) ;
scene ( ) - > update ( ) ;
}
}
//////////////////////////////////////////////////////////////////////////
2016-09-21 22:09:04 +03:00
void EasyGraphicsScrollbar : : clear ( )
{
2017-03-07 19:59:57 +03:00
setHistogramSource ( 0 , nullptr ) ;
2018-01-20 15:23:28 +03:00
Parent : : clear ( ) ;
2016-09-21 22:09:04 +03:00
}
2018-01-20 15:23:28 +03:00
profiler : : thread_id_t EasyGraphicsScrollbar : : hystThread ( ) const
2016-08-03 23:00:04 +03:00
{
2017-03-07 00:29:34 +03:00
return m_histogramItem - > threadId ( ) ;
2016-08-03 23:00:04 +03:00
}
2018-01-20 15:23:28 +03:00
void EasyGraphicsScrollbar : : setHistogramSource ( profiler : : thread_id_t _thread_id , const profiler_gui : : EasyItems * _items )
2016-08-03 00:06:36 +03:00
{
2016-12-04 16:51:27 +03:00
if ( m_bLocked )
return ;
2017-03-07 00:29:34 +03:00
m_histogramItem - > setSource ( _thread_id , _items ) ;
2016-12-04 16:51:27 +03:00
scene ( ) - > update ( ) ;
}
2018-01-20 15:23:28 +03:00
void EasyGraphicsScrollbar : : setHistogramSource ( profiler : : thread_id_t _thread_id , profiler : : block_id_t _block_id )
2016-12-04 16:51:27 +03:00
{
if ( m_bLocked )
return ;
2017-03-07 00:29:34 +03:00
m_histogramItem - > setSource ( _thread_id , _block_id ) ;
2016-08-03 23:00:04 +03:00
scene ( ) - > update ( ) ;
2016-08-03 00:06:36 +03:00
}
2016-08-18 23:26:41 +03:00
void EasyGraphicsScrollbar : : mousePressEvent ( QMouseEvent * _event )
2016-07-31 13:13:48 +03:00
{
2018-01-20 15:23:28 +03:00
Parent : : mousePressEvent ( _event ) ;
if ( ( m_mouseButtons & Qt : : RightButton ) & & _event - > modifiers ( ) )
m_histogramItem - > pickFrameTime ( mapToScene ( _event - > pos ( ) ) . y ( ) ) ;
2016-07-31 13:13:48 +03:00
}
//////////////////////////////////////////////////////////////////////////