diff --git a/profiler_gui/arbitrary_value_tooltip.cpp b/profiler_gui/arbitrary_value_tooltip.cpp index a78b586..1da8f9b 100644 --- a/profiler_gui/arbitrary_value_tooltip.cpp +++ b/profiler_gui/arbitrary_value_tooltip.cpp @@ -6,7 +6,7 @@ * email : v.s.zarubkin@gmail.com * ----------------- : * description : The file contains implementation of ArbitraryValueToolTip which is used -* : for displaying arbitrary value in Diagram and Hierarchy widgets. +* : for displaying arbitrary value in Diagram and StatsTree widgets. * ----------------- : * license : Lightweight profiler library for c++ * : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin diff --git a/profiler_gui/arbitrary_value_tooltip.h b/profiler_gui/arbitrary_value_tooltip.h index 99f8c0a..740857e 100644 --- a/profiler_gui/arbitrary_value_tooltip.h +++ b/profiler_gui/arbitrary_value_tooltip.h @@ -6,7 +6,7 @@ * email : v.s.zarubkin@gmail.com * ----------------- : * description : The file contains declaration of ArbitraryValueToolTip which is used -* : for displaying arbitrary value in Diagram and Hierarchy widgets. +* : for displaying arbitrary value in Diagram and StatsTree widgets. * ----------------- : * license : Lightweight profiler library for c++ * : Copyright(C) 2016-2019 Sergey Yagovtsev, Victor Zarubkin diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index 1a237a9..051dc86 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -1721,7 +1721,7 @@ void BlocksGraphicsView::mouseReleaseEvent(QMouseEvent* _event) ////////////////////////////////////////////////////////////////////////// -void BlocksGraphicsView::addSelectionToHierarchy() +void BlocksGraphicsView::addSelectionToStatsTree() { if (!m_selectionItem->isVisible()) return; @@ -1806,7 +1806,7 @@ void BlocksGraphicsView::onInspectCurrentView(bool strict) emit EASY_GLOBALS.events.rulerVisible(true); - addSelectionToHierarchy(); + addSelectionToStatsTree(); } else { diff --git a/profiler_gui/blocks_graphics_view.h b/profiler_gui/blocks_graphics_view.h index ac5c941..4201114 100644 --- a/profiler_gui/blocks_graphics_view.h +++ b/profiler_gui/blocks_graphics_view.h @@ -301,7 +301,7 @@ private: void revalidateOffset(); - void addSelectionToHierarchy(); + void addSelectionToStatsTree(); private slots: diff --git a/profiler_gui/blocks_tree_widget.cpp b/profiler_gui/blocks_tree_widget.cpp index e2c35ba..90c6023 100644 --- a/profiler_gui/blocks_tree_widget.cpp +++ b/profiler_gui/blocks_tree_widget.cpp @@ -97,7 +97,9 @@ ////////////////////////////////////////////////////////////////////////// -const int HIERARCHY_BUILDER_TIMER_INTERVAL = 40; +namespace { + +const int TREE_BUILDER_TIMER_INTERVAL = 40; const bool PLAIN_MODE_COLUMNS[COL_COLUMNS_NUMBER] = { true // COL_NAME = 0, @@ -183,6 +185,8 @@ const bool SELECTION_MODE_COLUMNS[COL_COLUMNS_NUMBER] = { , true // COL_NCALLS_PER_AREA, }; +} // end of namespace . + ////////////////////////////////////////////////////////////////////////// BlocksTreeWidget::BlocksTreeWidget(QWidget* _parent) @@ -366,7 +370,7 @@ BlocksTreeWidget::BlocksTreeWidget(QWidget* _parent) } } - m_hintLabel = new QLabel("Use Right Mouse Button on the Diagram to build a hierarchy...\n" + m_hintLabel = new QLabel("Use Right Mouse Button on the Diagram to build a tree...\n" "Way 1: Press the button >> Move mouse >> Release the button\n" "Way 2: Just click the right mouse button on any block", this); m_hintLabel->setObjectName(QStringLiteral("BlocksTreeWidget_HintLabel")); @@ -492,15 +496,15 @@ void BlocksTreeWidget::mousePressEvent(QMouseEvent* _event) void BlocksTreeWidget::onFillTimerTimeout() { - if (m_hierarchyBuilder.done()) + if (m_treeBuilder.done()) { m_fillTimer.stop(); ThreadedItems toplevelitems; - m_hierarchyBuilder.takeItems(m_items); - m_hierarchyBuilder.takeTopLevelItems(toplevelitems); - auto error = m_hierarchyBuilder.error(); - m_hierarchyBuilder.interrupt(); + m_treeBuilder.takeItems(m_items); + m_treeBuilder.takeTopLevelItems(toplevelitems); + auto error = m_treeBuilder.error(); + m_treeBuilder.interrupt(); { const QSignalBlocker b(this); for (auto& item : toplevelitems) @@ -557,7 +561,7 @@ void BlocksTreeWidget::onFillTimerTimeout() } else if (m_progress != nullptr) { - m_progress->setValue(m_hierarchyBuilder.progress()); + m_progress->setValue(m_treeBuilder.progress()); } } @@ -614,8 +618,8 @@ void BlocksTreeWidget::setTreeBlocks(const profiler_gui::TreeBlocks& _blocks, pr m_bLocked = true; m_hintLabel->hide(); createProgressDialog(); - m_hierarchyBuilder.fillTreeBlocks(m_inputBlocks, _session_begin_time, _left, _right, _strict, m_mode); - m_fillTimer.start(HIERARCHY_BUILDER_TIMER_INTERVAL); + m_treeBuilder.fillTreeBlocks(m_inputBlocks, _session_begin_time, _left, _right, _strict, m_mode); + m_fillTimer.start(TREE_BUILDER_TIMER_INTERVAL); } //StubLocker l; @@ -647,7 +651,7 @@ void BlocksTreeWidget::clearSilent(bool _global) { const QSignalBlocker b(this); - m_hierarchyBuilder.interrupt(); + m_treeBuilder.interrupt(); destroyProgressDialog(); m_hintLabel->show(); @@ -1545,7 +1549,7 @@ void BlocksTreeWidget::saveSettings() ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// -HierarchyWidget::HierarchyWidget(QWidget* _parent) : Parent(_parent) +StatsWidget::StatsWidget(QWidget* _parent) : Parent(_parent) , m_tree(new BlocksTreeWidget(this)) , m_searchBox(new QLineEdit(this)) , m_foundNumber(new QLabel(QStringLiteral("0 matches"), this)) @@ -1613,12 +1617,12 @@ HierarchyWidget::HierarchyWidget(QWidget* _parent) : Parent(_parent) m_foundNumber->hide(); } -HierarchyWidget::~HierarchyWidget() +StatsWidget::~StatsWidget() { saveSettings(); } -void HierarchyWidget::loadSettings() +void StatsWidget::loadSettings() { QSettings settings(profiler_gui::ORGANAZATION_NAME, profiler_gui::APPLICATION_NAME); settings.beginGroup("HierarchyWidget"); @@ -1630,7 +1634,7 @@ void HierarchyWidget::loadSettings() settings.endGroup(); } -void HierarchyWidget::saveSettings() +void StatsWidget::saveSettings() { QSettings settings(profiler_gui::ORGANAZATION_NAME, profiler_gui::APPLICATION_NAME); settings.beginGroup("HierarchyWidget"); @@ -1638,19 +1642,19 @@ void HierarchyWidget::saveSettings() settings.endGroup(); } -void HierarchyWidget::enterEvent(QEvent* event) +void StatsWidget::enterEvent(QEvent* event) { Parent::enterEvent(event); m_tree->updateHintLabelOnHover(true); } -void HierarchyWidget::leaveEvent(QEvent* event) +void StatsWidget::leaveEvent(QEvent* event) { Parent::leaveEvent(event); m_tree->updateHintLabelOnHover(false); } -void HierarchyWidget::keyPressEvent(QKeyEvent* _event) +void StatsWidget::keyPressEvent(QKeyEvent* _event) { switch (_event->key()) { @@ -1677,12 +1681,12 @@ void HierarchyWidget::keyPressEvent(QKeyEvent* _event) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void HierarchyWidget::contextMenuEvent(QContextMenuEvent* _event) +void StatsWidget::contextMenuEvent(QContextMenuEvent* _event) { m_tree->contextMenuEvent(_event); } -void HierarchyWidget::showEvent(QShowEvent* event) +void StatsWidget::showEvent(QShowEvent* event) { Parent::showEvent(event); m_searchBox->setFixedWidth(px(300)); @@ -1690,19 +1694,19 @@ void HierarchyWidget::showEvent(QShowEvent* event) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -BlocksTreeWidget* HierarchyWidget::tree() +BlocksTreeWidget* StatsWidget::tree() { return m_tree; } -void HierarchyWidget::clear(bool _global) +void StatsWidget::clear(bool _global) { m_tree->clearSilent(_global); m_foundNumber->setText(QStringLiteral("0 matches")); m_foundNumber->hide(); } -void HierarchyWidget::onSeachBoxReturnPressed() +void StatsWidget::onSeachBoxReturnPressed() { if (m_searchButton->data().toBool()) findNext(true); @@ -1710,7 +1714,7 @@ void HierarchyWidget::onSeachBoxReturnPressed() findPrev(true); } -void HierarchyWidget::onSearchBoxTextChanged(const QString& _text) +void StatsWidget::onSearchBoxTextChanged(const QString& _text) { if (_text.isEmpty()) { @@ -1719,7 +1723,7 @@ void HierarchyWidget::onSearchBoxTextChanged(const QString& _text) } } -void HierarchyWidget::findNext(bool) +void StatsWidget::findNext(bool) { auto text = m_searchBox->text(); if (text.isEmpty()) @@ -1752,7 +1756,7 @@ void HierarchyWidget::findNext(bool) m_foundNumber->show(); } -void HierarchyWidget::findPrev(bool) +void StatsWidget::findPrev(bool) { auto text = m_searchBox->text(); if (text.isEmpty()) @@ -1785,7 +1789,7 @@ void HierarchyWidget::findPrev(bool) m_foundNumber->show(); } -void HierarchyWidget::findNextFromMenu(bool _checked) +void StatsWidget::findNextFromMenu(bool _checked) { if (!_checked) return; @@ -1802,7 +1806,7 @@ void HierarchyWidget::findNextFromMenu(bool _checked) findNext(true); } -void HierarchyWidget::findPrevFromMenu(bool _checked) +void StatsWidget::findPrevFromMenu(bool _checked) { if (!_checked) return; diff --git a/profiler_gui/blocks_tree_widget.h b/profiler_gui/blocks_tree_widget.h index 20e9998..beac947 100644 --- a/profiler_gui/blocks_tree_widget.h +++ b/profiler_gui/blocks_tree_widget.h @@ -82,7 +82,7 @@ class BlocksTreeWidget : public QTreeWidget protected: - TreeWidgetLoader m_hierarchyBuilder; + TreeWidgetLoader m_treeBuilder; Items m_items; RootsMap m_roots; ::profiler_gui::TreeBlocks m_inputBlocks; @@ -189,12 +189,12 @@ private: ////////////////////////////////////////////////////////////////////////// -class HierarchyWidget : public QWidget +class StatsWidget : public QWidget { Q_OBJECT using Parent = QWidget; - using This = HierarchyWidget; + using This = StatsWidget; private: @@ -208,8 +208,8 @@ public: // Public virtual methods - explicit HierarchyWidget(QWidget* _parent = nullptr); - ~HierarchyWidget() override; + explicit StatsWidget(QWidget* _parent = nullptr); + ~StatsWidget() override; void enterEvent(QEvent* event) override; void leaveEvent(QEvent* event) override; diff --git a/profiler_gui/globals.cpp b/profiler_gui/globals.cpp index 0cd552e..3ad9767 100644 --- a/profiler_gui/globals.cpp +++ b/profiler_gui/globals.cpp @@ -89,6 +89,7 @@ Globals::Globals() , frame_time(16700) , blocks_spacing(0) , blocks_size_min(2) + , histogram_column_width_min(2) , blocks_narrow_size(20) , max_fps_history(90) , fps_timer_interval(500) @@ -111,7 +112,7 @@ Globals::Globals() , draw_histogram_borders(true) , hide_narrow_children(false) , hide_minsize_blocks(false) - , display_only_relevant_stats(false) + , hide_stats_for_single_blocks(false) , collapse_items_on_tree_close(false) , all_items_expanded_by_default(true) , only_current_thread_hierarchy(false) diff --git a/profiler_gui/globals.h b/profiler_gui/globals.h index 962d8cd..c2b0587 100644 --- a/profiler_gui/globals.h +++ b/profiler_gui/globals.h @@ -215,11 +215,12 @@ namespace profiler_gui { ::profiler::block_id_t selected_block_id; ///< Current selected profiler block id uint32_t version; ///< Opened file version (files may have different format) - uint32_t max_rows_count; ///< Maximum blocks count for the Hierarchy widget for the full call-stack mode + uint32_t max_rows_count; ///< Maximum blocks count for the StatsTree widget for the full call-stack mode float frame_time; ///< Expected frame time value in microseconds to be displayed at minimap on graphics scrollbar int blocks_spacing; ///< Minimum blocks spacing on diagram int blocks_size_min; ///< Minimum blocks size on diagram + int histogram_column_width_min; ///< Minimum column width on histogram when borders are enabled int blocks_narrow_size; ///< Width indicating narrow blocks int max_fps_history; ///< Max frames history displayed in FPS Monitor int fps_timer_interval; ///< Interval in milliseconds for sending network requests to the profiled application (used by FPS Monitor) @@ -245,7 +246,7 @@ namespace profiler_gui { bool draw_histogram_borders; ///< Draw borders for histogram columns or not bool hide_narrow_children; ///< Hide children for narrow graphics blocks (See blocks_narrow_size) bool hide_minsize_blocks; ///< Hide blocks which screen size is less than blocks_size_min - bool display_only_relevant_stats; ///< Display only relevant information in ProfTreeWidget (excludes min, max, average times if there are only 1 calls number) + bool hide_stats_for_single_blocks; ///< Hide min, max, avg, median durations in stats tree if there is only 1 call for a block bool collapse_items_on_tree_close; ///< Collapse all items which were displayed in the hierarchy tree after tree close/reset bool all_items_expanded_by_default; ///< Expand all items after file is opened bool only_current_thread_hierarchy; ///< Build hierarchy tree for current thread only diff --git a/profiler_gui/graphics_scrollbar.cpp b/profiler_gui/graphics_scrollbar.cpp index ff267e9..eb3e639 100644 --- a/profiler_gui/graphics_scrollbar.cpp +++ b/profiler_gui/graphics_scrollbar.cpp @@ -66,7 +66,6 @@ namespace { ////////////////////////////////////////////////////////////////////////// EASY_CONSTEXPR int HIST_COLUMN_MIN_HEIGHT = 2; -EASY_CONSTEXPR qreal HIST_COLUMN_MIN_WIDTH_WITH_BORDER = 3; ////////////////////////////////////////////////////////////////////////// @@ -251,24 +250,6 @@ void GraphicsHistogramItem::paintByPtr(QPainter* _painter) // MEDIAN & EXPECTED FRAME TIME if (!isEmpty()) { - const qreal mdn = m_medianDuration * 1e-3; - - if (m_bottomValue < mdn && mdn < m_topValue) - { - // Draw marker displaying expected frame_time step - const auto h = bottom - (mdn - m_bottomValue) * coeff; - _painter->setPen(Qt::DashDotDotLine); - - auto w = width; - const auto boundary = widget->margin() - font_h; - if (h < (m_boundingRect.top() - boundary)) - w = top_width; - else if (h > (bottom + boundary)) - w = bottom_width; - - _painter->drawLine(QLineF(0, h, w, h)); - } - if (m_bottomValue < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topValue) { // Draw marker displaying expected frame_time step @@ -406,24 +387,6 @@ void GraphicsHistogramItem::paintById(QPainter* _painter) // MEDIAN & EXPECTED FRAME TIME if (!isEmpty()) { - const qreal mdn = m_medianDuration * 1e-3; - - if (m_bottomValue < mdn && mdn < m_topValue) - { - // Draw marker displaying expected frame_time step - const auto h = bottom - (mdn - m_bottomValue) * coeff; - _painter->setPen(Qt::DashDotDotLine); - - auto w = width; - const auto boundary = widget->margin() - font_h; - if (h < (m_boundingRect.top() - boundary)) - w = top_width; - else if (h > (bottom + boundary)) - w = bottom_width; - - _painter->drawLine(QLineF(0, h, w, h)); - } - if (m_bottomValue < EASY_GLOBALS.frame_time && EASY_GLOBALS.frame_time < m_topValue) { // Draw marker displaying required frame_time step @@ -1057,9 +1020,10 @@ bool GraphicsHistogramItem::updateImage() const auto beginTime = EASY_GLOBALS.begin_time; const auto autoHeight = EASY_GLOBALS.auto_adjust_histogram_height; const auto drawBorders = EASY_GLOBALS.draw_histogram_borders; + const auto minColumnWidth = EASY_GLOBALS.histogram_column_width_min; m_worker.enqueue([=] { - updateImageAsync(rect, regime, scale, left, right, right - left, value, window, top, bottom, bindMode, - frameTime, beginTime, autoHeight, drawBorders); + updateImageAsync(rect, regime, scale, left, right, right - left, value, window, top, bottom, + minColumnWidth, bindMode, frameTime, beginTime, autoHeight, drawBorders); }, m_bReady); return true; @@ -1095,9 +1059,8 @@ void GraphicsHistogramItem::onImageUpdated() } 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, bool _drawBorders) + qreal _minimum, qreal _maximum, qreal _range, qreal _value, qreal _width, qreal _top_duration, qreal _bottom_duration, + int _min_column_width, bool _bindMode, float _frame_time, profiler::timestamp_t _begin_time, bool _autoAdjustHist, bool _drawBorders) { const auto bottom = _boundingRect.height();//_boundingRect.bottom(); const auto screenWidth = _boundingRect.width() * _current_scale; @@ -1225,7 +1188,7 @@ void GraphicsHistogramItem::updateImageAsync(QRectF _boundingRect, HistRegime _r const auto dtime = _top_duration - _bottom_duration; const auto coeff = _boundingRect.height() / (dtime > 1e-3 ? dtime : 1.); - const qreal minWidth = _drawBorders ? HIST_COLUMN_MIN_WIDTH_WITH_BORDER : 1.; + const qreal minWidth = _drawBorders ? _min_column_width : 1; if (_drawBorders) p.setPen(profiler_gui::BLOCK_BORDER_COLOR); @@ -1433,7 +1396,7 @@ void GraphicsHistogramItem::updateImageAsync(QRectF _boundingRect, HistRegime _r const auto dtime = _top_duration - _bottom_duration; const auto coeff = _boundingRect.height() / (dtime > 1e-3 ? dtime : 1.); - const qreal minWidth = _drawBorders ? HIST_COLUMN_MIN_WIDTH_WITH_BORDER : 1.; + const qreal minWidth = _drawBorders ? _min_column_width : 1; if (_drawBorders) p.setPen(profiler_gui::BLOCK_BORDER_COLOR); diff --git a/profiler_gui/graphics_scrollbar.h b/profiler_gui/graphics_scrollbar.h index baf4070..4f2d057 100644 --- a/profiler_gui/graphics_scrollbar.h +++ b/profiler_gui/graphics_scrollbar.h @@ -143,8 +143,8 @@ private: void paintById(QPainter* _painter); void 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, + qreal _minimum, qreal _maximum, qreal _range, qreal _value, qreal _width, + qreal _top_duration, qreal _bottom_duration, int _min_column_width, bool _bindMode, float _frame_time, profiler::timestamp_t _begin_time, bool _autoAdjustHist, bool _drawBorders); }; // END of class GraphicsHistogramItem. diff --git a/profiler_gui/main_window.cpp b/profiler_gui/main_window.cpp index 011910c..decf7b9 100644 --- a/profiler_gui/main_window.cpp +++ b/profiler_gui/main_window.cpp @@ -366,12 +366,12 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos connect(this, &MainWindow::activationChanged, graphicsView->threadsView(), &ThreadNamesWidget::onWindowActivationChanged, Qt::QueuedConnection); m_graphicsView->setWidget(graphicsView); - m_treeWidget = new DockWidget("Hierarchy", this); + m_treeWidget = new DockWidget("Stats", this); m_treeWidget->setObjectName("ProfilerGUI_Hierarchy"); m_treeWidget->setMinimumHeight(px(50)); m_treeWidget->setAllowedAreas(Qt::AllDockWidgetAreas); - auto treeWidget = new HierarchyWidget(this); + auto treeWidget = new StatsWidget(this); m_treeWidget->setWidget(treeWidget); m_fpsViewer = new DockWidget("FPS Monitor", this); @@ -464,8 +464,8 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos toolbar->addAction(QIcon(imagePath("expand")), "Expand all", this, SLOT(onExpandAllClicked(bool))); toolbar->addAction(QIcon(imagePath("collapse")), "Collapse all", this, SLOT(onCollapseAllClicked(bool))); - action = toolbar->addAction(QIcon(imagePath("binoculars")), "See blocks hierarchy"); - action->setToolTip("Build blocks hierarchy\nfor current visible area\nor zoom to current selected area."); + action = toolbar->addAction(QIcon(imagePath("binoculars")), "Build stats tree"); + action->setToolTip("Build stats tree\nfor current visible area\nor zoom to current selected area."); connect(action, &QAction::triggered, [this] (bool) { static_cast(m_graphicsView->widget())->view()->inspectCurrentView(true); }); @@ -486,40 +486,11 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos toolButton->setPopupMode(QToolButton::InstantPopup); toolbar->addWidget(toolButton); - action = menu->addAction("Statistics enabled"); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.enable_statistics); - connect(action, &QAction::triggered, this, &This::onEnableDisableStatistics); - if (EASY_GLOBALS.enable_statistics) - { - auto f = action->font(); - f.setBold(true); - action->setFont(f); - action->setIcon(QIcon(imagePath("stats"))); - } - else - { - action->setText("Statistics disabled"); - action->setIcon(QIcon(imagePath("stats-off"))); - } - - action = menu->addAction("Only frames on histogram"); - action->setToolTip("Display only top-level blocks on histogram."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.display_only_frames_on_histogram); - connect(action, &QAction::triggered, [this](bool _checked) - { - EASY_GLOBALS.display_only_frames_on_histogram = _checked; - emit EASY_GLOBALS.events.displayOnlyFramesOnHistogramChanged(); - }); - - - menu->addSeparator(); - auto submenu = menu->addMenu("View"); + auto submenu = menu->addMenu("Diagram"); submenu->setToolTipsVisible(true); - action = submenu->addAction("Diagram borders"); + action = submenu->addAction("Draw borders"); action->setToolTip("Draw borders for blocks on diagram.\nThis slightly reduces performance."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.draw_graphics_items_borders); @@ -528,57 +499,32 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos refreshDiagram(); }); - action = submenu->addAction("Histogram borders"); - action->setToolTip("Draw borders for histogram columns."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.draw_histogram_borders); - connect(action, &QAction::triggered, [this] (bool _checked) { - EASY_GLOBALS.draw_histogram_borders = _checked; - refreshHistogramImage(); - }); - action = submenu->addAction("Overlap narrow children"); action->setToolTip("Children blocks will be overlaped by narrow\nparent blocks. See also \'Blocks narrow size\'.\nThis improves performance."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.hide_narrow_children); - connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.hide_narrow_children = _checked; refreshDiagram(); }); + connect(action, &QAction::triggered, [this] (bool _checked) { EASY_GLOBALS.hide_narrow_children = _checked; refreshDiagram(); }); action = submenu->addAction("Hide min-size blocks"); action->setToolTip("Hides blocks which screen size\nis less than \'Min blocks size\'."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.hide_minsize_blocks); - connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.hide_minsize_blocks = _checked; refreshDiagram(); }); - - action = submenu->addAction("Build hierarchy only for current thread"); - action->setToolTip("Hierarchy tree will be built\nfor blocks from current thread only.\nThis improves performance\nand saves a lot of memory."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.only_current_thread_hierarchy); - connect(action, &QAction::triggered, this, &This::onHierarchyFlagChange); - - action = submenu->addAction("Add zero blocks to hierarchy"); - action->setToolTip("Zero duration blocks will be added into hierarchy tree.\nThis reduces performance and increases memory consumption."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.add_zero_blocks_to_hierarchy); - connect(action, &QAction::triggered, [this](bool _checked) - { - EASY_GLOBALS.add_zero_blocks_to_hierarchy = _checked; - emit EASY_GLOBALS.events.hierarchyFlagChanged(_checked); - }); + connect(action, &QAction::triggered, [this] (bool _checked) { EASY_GLOBALS.hide_minsize_blocks = _checked; refreshDiagram(); }); action = submenu->addAction("Enable zero duration blocks on diagram"); action->setToolTip("If checked then allows diagram to paint zero duration blocks\nwith 1px width on each scale. Otherwise, such blocks will be resized\nto 250ns duration."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.enable_zero_length); - connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.enable_zero_length = _checked; refreshDiagram(); }); + connect(action, &QAction::triggered, [this] (bool _checked) { EASY_GLOBALS.enable_zero_length = _checked; refreshDiagram(); }); action = submenu->addAction("Highlight similar blocks"); action->setToolTip("Highlight all visible blocks which are similar\nto the current selected block.\nThis reduces performance."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.highlight_blocks_with_same_id); - connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.highlight_blocks_with_same_id = _checked; refreshDiagram(); }); + connect(action, &QAction::triggered, [this] (bool _checked) { EASY_GLOBALS.highlight_blocks_with_same_id = _checked; refreshDiagram(); }); action = submenu->addAction("Collapse blocks on tree reset"); - action->setToolTip("This collapses all blocks on diagram\nafter hierarchy tree reset."); + action->setToolTip("This collapses all blocks on diagram\nafter stats tree reset."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.collapse_items_on_tree_close); connect(action, &QAction::triggered, this, &This::onCollapseItemsAfterCloseChanged); @@ -590,73 +536,27 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos connect(action, &QAction::triggered, this, &This::onAllItemsExpandedByDefaultChange); action = submenu->addAction("Bind diagram and tree expand"); - action->setToolTip("Expanding/collapsing blocks at diagram expands/collapses\nblocks at hierarchy tree and wise versa."); + action->setToolTip("Expanding/collapsing blocks at diagram expands/collapses\nblocks at stats tree and wise versa."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.bind_scene_and_tree_expand_status); connect(action, &QAction::triggered, this, &This::onBindExpandStatusChange); - action = submenu->addAction("Hide stats for single blocks in tree"); - action->setToolTip("If checked then such stats like Min,Max,Avg etc.\nwill not be displayed in stats tree for blocks\nwith number of calls == 1"); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.display_only_relevant_stats); - connect(action, &QAction::triggered, this, &This::onDisplayRelevantStatsChange); - action = submenu->addAction("Selecting block changes current thread"); action->setToolTip("Automatically select thread while selecting a block.\nIf not checked then you will have to select current thread\nmanually double clicking on thread name on a diagram."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.selecting_block_changes_thread); - connect(action, &QAction::triggered, [this](bool _checked){ EASY_GLOBALS.selecting_block_changes_thread = _checked; }); + connect(action, &QAction::triggered, [this] (bool _checked) { EASY_GLOBALS.selecting_block_changes_thread = _checked; }); action = submenu->addAction("Draw event markers"); action->setToolTip("Display event markers under the blocks\n(even if event-blocks are not visible).\nThis slightly reduces performance."); action->setCheckable(true); action->setChecked(EASY_GLOBALS.enable_event_markers); - connect(action, &QAction::triggered, [this](bool _checked) + connect(action, &QAction::triggered, [this] (bool _checked) { EASY_GLOBALS.enable_event_markers = _checked; refreshDiagram(); }); - action = submenu->addAction("Automatically adjust histogram height"); - action->setToolTip("You do not need to adjust boundaries manually,\nbut this restricts you from adjusting boundaries at all (zoom mode).\nYou can still adjust boundaries in overview mode though."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.auto_adjust_histogram_height); - connect(action, &QAction::triggered, [](bool _checked) - { - EASY_GLOBALS.auto_adjust_histogram_height = _checked; - emit EASY_GLOBALS.events.autoAdjustHistogramChanged(); - }); - - action = submenu->addAction("Automatically adjust chart height"); - action->setToolTip("Same as similar option for histogram\nbut used for arbitrary values charts."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.auto_adjust_chart_height); - connect(action, &QAction::triggered, [](bool _checked) - { - EASY_GLOBALS.auto_adjust_chart_height = _checked; - emit EASY_GLOBALS.events.autoAdjustChartChanged(); - }); - - action = submenu->addAction("Use decorated thread names"); - action->setToolTip("Add \'Thread\' word into thread name if there is no one already.\nExamples: \'Render\' will change to \'Render Thread\'\n\'WorkerThread\' will not change."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.use_decorated_thread_name); - connect(action, &QAction::triggered, [this](bool _checked) - { - EASY_GLOBALS.use_decorated_thread_name = _checked; - emit EASY_GLOBALS.events.threadNameDecorationChanged(); - }); - - action = submenu->addAction("Display hex thread id"); - action->setToolTip("Display hex thread id instead of decimal."); - action->setCheckable(true); - action->setChecked(EASY_GLOBALS.hex_thread_id); - connect(action, &QAction::triggered, [this](bool _checked) - { - EASY_GLOBALS.hex_thread_id = _checked; - emit EASY_GLOBALS.events.hexThreadIdChanged(); - }); - submenu->addSeparator(); auto actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); @@ -735,7 +635,100 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos submenu->addAction(waction); + submenu = menu->addMenu("Histogram"); + submenu->setToolTipsVisible(true); + + action = submenu->addAction("Draw borders"); + action->setToolTip("Draw borders for histogram columns."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.draw_histogram_borders); + connect(action, &QAction::triggered, [this] (bool _checked) { + EASY_GLOBALS.draw_histogram_borders = _checked; + refreshHistogramImage(); + }); + + action = submenu->addAction("Automatically adjust histogram height"); + action->setToolTip("You do not need to adjust boundaries manually,\n" + "but this restricts you from adjusting boundaries at all (zoom mode).\n" + "You can still adjust boundaries in overview mode though."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.auto_adjust_histogram_height); + connect(action, &QAction::triggered, [] (bool _checked) + { + EASY_GLOBALS.auto_adjust_histogram_height = _checked; + emit EASY_GLOBALS.events.autoAdjustHistogramChanged(); + }); + + action = submenu->addAction("Only frames on histogram"); + action->setToolTip("Display only top-level blocks on histogram."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.display_only_frames_on_histogram); + connect(action, &QAction::triggered, [this] (bool _checked) + { + EASY_GLOBALS.display_only_frames_on_histogram = _checked; + emit EASY_GLOBALS.events.displayOnlyFramesOnHistogramChanged(); + }); + submenu->addSeparator(); + w = new QWidget(submenu); + l = new QHBoxLayout(w); + l->setContentsMargins(26, 1, 16, 1); + l->addWidget(new QLabel("Min column width, px", w), 0, Qt::AlignLeft); + spinbox = new QSpinBox(w); + spinbox->setRange(1, 400); + spinbox->setValue(EASY_GLOBALS.histogram_column_width_min); + spinbox->setFixedWidth(px(70)); + connect(spinbox, Overload::of(&QSpinBox::valueChanged), this, &This::onHistogramMinSizeChange); + l->addWidget(spinbox); + w->setLayout(l); + waction = new QWidgetAction(submenu); + waction->setDefaultWidget(w); + waction->setToolTip("Minimum column width when borders are enabled."); + submenu->addAction(waction); + + + submenu = menu->addMenu("Stats"); + submenu->setToolTipsVisible(true); + + action = submenu->addAction("Statistics enabled"); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.enable_statistics); + connect(action, &QAction::triggered, this, &This::onEnableDisableStatistics); + if (EASY_GLOBALS.enable_statistics) + { + auto f = action->font(); + f.setBold(true); + action->setFont(f); + action->setIcon(QIcon(imagePath("stats"))); + } + else + { + action->setText("Statistics disabled"); + action->setIcon(QIcon(imagePath("stats-off"))); + } + + action = submenu->addAction("Build tree only for current thread"); + action->setToolTip("Stats tree will be built\nfor blocks from current thread only.\nThis improves performance\nand saves a lot of memory for Call-stack mode."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.only_current_thread_hierarchy); + connect(action, &QAction::triggered, this, &This::onHierarchyFlagChange); + + action = submenu->addAction("Add zero blocks to the tree"); + action->setToolTip("Zero duration blocks will be added into stats tree.\nThis reduces performance and increases memory consumption."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.add_zero_blocks_to_hierarchy); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.add_zero_blocks_to_hierarchy = _checked; + emit EASY_GLOBALS.events.hierarchyFlagChanged(_checked); + }); + + action = submenu->addAction("Hide stats for single blocks in tree"); + action->setToolTip("If checked then such stats like Min,Max,Avg etc.\nwill not be displayed in stats tree for blocks\nwith number of calls == 1"); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.hide_stats_for_single_blocks); + connect(action, &QAction::triggered, this, &This::onDisplayRelevantStatsChange); + w = new QWidget(submenu); l = new QHBoxLayout(w); l->setContentsMargins(26, 1, 16, 1); @@ -752,6 +745,39 @@ MainWindow::MainWindow() : Parent(), m_theme("default"), m_lastAddress("localhos submenu->addAction(waction); + submenu = menu->addMenu("General"); + submenu->setToolTipsVisible(true); + + action = submenu->addAction("Automatically adjust values chart height"); + action->setToolTip("Automatically adjusts arbitrary values chart height\nfor currently visible region."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.auto_adjust_chart_height); + connect(action, &QAction::triggered, [](bool _checked) + { + EASY_GLOBALS.auto_adjust_chart_height = _checked; + emit EASY_GLOBALS.events.autoAdjustChartChanged(); + }); + + action = submenu->addAction("Use decorated thread names"); + action->setToolTip("Add \'Thread\' word into thread name if there is no one already.\nExamples: \'Render\' will change to \'Render Thread\'\n\'WorkerThread\' will not change."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.use_decorated_thread_name); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.use_decorated_thread_name = _checked; + emit EASY_GLOBALS.events.threadNameDecorationChanged(); + }); + + action = submenu->addAction("Display hex thread id"); + action->setToolTip("Display hex thread id instead of decimal."); + action->setCheckable(true); + action->setChecked(EASY_GLOBALS.hex_thread_id); + connect(action, &QAction::triggered, [this](bool _checked) + { + EASY_GLOBALS.hex_thread_id = _checked; + emit EASY_GLOBALS.events.hexThreadIdChanged(); + }); + submenu = menu->addMenu("FPS Monitor"); w = new QWidget(submenu); @@ -1457,7 +1483,7 @@ void MainWindow::onBindExpandStatusChange(bool _checked) void MainWindow::onDisplayRelevantStatsChange(bool _checked) { - EASY_GLOBALS.display_only_relevant_stats = _checked; + EASY_GLOBALS.hide_stats_for_single_blocks = _checked; } void MainWindow::onHierarchyFlagChange(bool _checked) @@ -1475,7 +1501,7 @@ void MainWindow::onExpandAllClicked(bool) emit EASY_GLOBALS.events.itemsExpandStateChanged(); - auto tree = static_cast(m_treeWidget->widget())->tree(); + auto tree = static_cast(m_treeWidget->widget())->tree(); const QSignalBlocker b(tree); tree->expandAll(); } @@ -1487,7 +1513,7 @@ void MainWindow::onCollapseAllClicked(bool) emit EASY_GLOBALS.events.itemsExpandStateChanged(); - auto tree = static_cast(m_treeWidget->widget())->tree(); + auto tree = static_cast(m_treeWidget->widget())->tree(); const QSignalBlocker b(tree); tree->collapseAll(); } @@ -1527,6 +1553,12 @@ void MainWindow::onMinSizeChange(int _value) refreshDiagram(); } +void MainWindow::onHistogramMinSizeChange(int _value) +{ + EASY_GLOBALS.histogram_column_width_min = _value; + refreshHistogramImage(); +} + void MainWindow::onNarrowSizeChange(int _value) { EASY_GLOBALS.blocks_narrow_size = _value; @@ -1733,6 +1765,10 @@ void MainWindow::loadSettings() if (!val.isNull()) EASY_GLOBALS.blocks_size_min = val.toInt(); + val = settings.value("histogram_column_width_min"); + if (!val.isNull()) + EASY_GLOBALS.histogram_column_width_min = val.toInt(); + val = settings.value("blocks_narrow_size"); if (!val.isNull()) EASY_GLOBALS.blocks_narrow_size = val.toInt(); @@ -1783,9 +1819,9 @@ void MainWindow::loadSettings() if (!flag.isNull()) EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool(); - flag = settings.value("display_only_relevant_stats"); + flag = settings.value("hide_stats_for_single_blocks"); if (!flag.isNull()) - EASY_GLOBALS.display_only_relevant_stats = flag.toBool(); + EASY_GLOBALS.hide_stats_for_single_blocks = flag.toBool(); flag = settings.value("selecting_block_changes_thread"); if (!flag.isNull()) @@ -1909,6 +1945,7 @@ void MainWindow::saveSettingsAndGeometry() settings.setValue("max_rows_count", EASY_GLOBALS.max_rows_count); settings.setValue("blocks_spacing", EASY_GLOBALS.blocks_spacing); settings.setValue("blocks_size_min", EASY_GLOBALS.blocks_size_min); + settings.setValue("histogram_column_width_min", EASY_GLOBALS.histogram_column_width_min); settings.setValue("blocks_narrow_size", EASY_GLOBALS.blocks_narrow_size); settings.setValue("draw_graphics_items_borders", EASY_GLOBALS.draw_graphics_items_borders); settings.setValue("draw_histogram_borders", EASY_GLOBALS.draw_histogram_borders); @@ -1921,7 +1958,7 @@ void MainWindow::saveSettingsAndGeometry() settings.setValue("add_zero_blocks_to_hierarchy", EASY_GLOBALS.add_zero_blocks_to_hierarchy); settings.setValue("highlight_blocks_with_same_id", EASY_GLOBALS.highlight_blocks_with_same_id); settings.setValue("bind_scene_and_tree_expand_status", EASY_GLOBALS.bind_scene_and_tree_expand_status); - settings.setValue("display_only_relevant_stats", EASY_GLOBALS.display_only_relevant_stats); + settings.setValue("hide_stats_for_single_blocks", EASY_GLOBALS.hide_stats_for_single_blocks); settings.setValue("selecting_block_changes_thread", EASY_GLOBALS.selecting_block_changes_thread); settings.setValue("enable_event_indicators", EASY_GLOBALS.enable_event_markers); settings.setValue("auto_adjust_histogram_height", EASY_GLOBALS.auto_adjust_histogram_height); diff --git a/profiler_gui/main_window.h b/profiler_gui/main_window.h index cc12d27..f302a60 100644 --- a/profiler_gui/main_window.h +++ b/profiler_gui/main_window.h @@ -347,6 +347,7 @@ protected slots: void onMaxBlocksCountChange(int _value); void onSpacingChange(int _value); void onMinSizeChange(int _value); + void onHistogramMinSizeChange(int _value); void onNarrowSizeChange(int _value); void onFpsIntervalChange(int _value); void onFpsHistoryChange(int _value); diff --git a/profiler_gui/themes/default.css b/profiler_gui/themes/default.css index f46e92b..dc5c132 100644 --- a/profiler_gui/themes/default.css +++ b/profiler_gui/themes/default.css @@ -310,7 +310,7 @@ QMenu { QMenu::item { height: 15ex; padding-left: 17ex; - padding-right: 5ex; + padding-right: 10ex; border: 1px solid transparent; /* reserve space for selection border */ } diff --git a/profiler_gui/themes/default.scss b/profiler_gui/themes/default.scss index 5e3f9bb..28c9123 100644 --- a/profiler_gui/themes/default.scss +++ b/profiler_gui/themes/default.scss @@ -425,7 +425,7 @@ QMenu { QMenu::item { height: $InputHeight; padding-left: 17ex; - padding-right: 5ex; + padding-right: 10ex; border: 1px solid transparent; /* reserve space for selection border */ } diff --git a/profiler_gui/tree_widget_item.cpp b/profiler_gui/tree_widget_item.cpp index 187c645..02cf606 100644 --- a/profiler_gui/tree_widget_item.cpp +++ b/profiler_gui/tree_widget_item.cpp @@ -272,7 +272,7 @@ QVariant TreeWidgetItem::relevantData(int _column, int _role) const } } - if (EASY_GLOBALS.display_only_relevant_stats && _role == Qt::DisplayRole) + if (EASY_GLOBALS.hide_stats_for_single_blocks && _role == Qt::DisplayRole) { return QVariant(); } diff --git a/profiler_gui/tree_widget_loader.cpp b/profiler_gui/tree_widget_loader.cpp index b422cda..f658fa8 100644 --- a/profiler_gui/tree_widget_loader.cpp +++ b/profiler_gui/tree_widget_loader.cpp @@ -128,7 +128,7 @@ static void fillStatsColumns( item->setData(max_column, MinMaxBlockIndexRole, stats->max_duration_block); } - if (stats->calls_number < 2)// && EASY_GLOBALS.display_only_relevant_stats) + if (stats->calls_number < 2) { return; }