0
0
mirror of https://github.com/yse/easy_profiler.git synced 2025-01-14 00:27:55 +08:00

(profiler_gui) First version of displaying and controlling blocks enable status

This commit is contained in:
Victor Zarubkin 2016-09-17 15:39:31 +03:00
parent 9ccb0499a5
commit ef7469a880
9 changed files with 508 additions and 17 deletions

View File

@ -69,6 +69,11 @@ namespace profiler {
return name() + m_nameLength;
}
inline void setEnabled(bool _enabled)
{
m_enabled = _enabled;
}
private:
SerializedBlockDescriptor(const SerializedBlockDescriptor&) = delete;

View File

@ -16,6 +16,8 @@ add_executable(${PROJECT_NAME}
blocks_graphics_view.cpp
blocks_tree_widget.h
blocks_tree_widget.cpp
descriptors_tree_widget.h
descriptors_tree_widget.cpp
easy_chronometer_item.h
easy_chronometer_item.cpp
easy_graphics_item.h

View File

@ -50,12 +50,16 @@
#include "tree_widget_item.h"
#include "globals.h"
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#ifdef _WIN32
#include <Windows.h>
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
//////////////////////////////////////////////////////////////////////////
@ -332,6 +336,11 @@ void EasyTreeWidget::clearSilent(bool _global)
for (auto item : _items)
delete item;
}, ::std::move(topLevelItems));
#ifdef _WIN32
SetThreadPriority(deleter_thread.native_handle(), THREAD_PRIORITY_LOWEST);
#endif
deleter_thread.detach();
//clear();
@ -395,11 +404,6 @@ void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
if (item != nullptr && item->parent() != nullptr)
{
//auto itemAction = new EasyItemAction("Show this item on scene", item->block()->block_index);
//itemAction->setToolTip("Scroll graphics scene to current item in the tree");
//connect(itemAction, &EasyItemAction::clicked, this, &This::onJumpToItemClicked);
//menu.addAction(itemAction);
if (col >= 0)
{
switch (col)
@ -437,6 +441,19 @@ void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
}
}
}
auto id = item->block().node->id();
action = menu.addAction("Block enabled");
action->setCheckable(true);
action->setChecked(easyDescriptor(id).enabled());
action->setData(id);
connect(action, &QAction::triggered, this, &This::onBlockEnableDisable);
if (action->isChecked()) {
auto f = action->font();
f.setBold(true);
action->setFont(f);
}
}
menu.addSeparator();
@ -562,6 +579,19 @@ void EasyTreeWidget::onExpandAllChildrenClicked(bool)
//////////////////////////////////////////////////////////////////////////
void EasyTreeWidget::onBlockEnableDisable(bool _checked)
{
auto action = qobject_cast<QAction*>(sender());
if (action != nullptr)
{
auto id = action->data().toUInt();
easyDescriptor(id).setEnabled(_checked);
emit EASY_GLOBALS.events.enableStatusChanged(id, _checked);
}
}
//////////////////////////////////////////////////////////////////////////
void EasyTreeWidget::onItemExpand(QTreeWidgetItem* _item)
{
if (!EASY_GLOBALS.bind_scene_and_tree_expand_status)
@ -640,7 +670,7 @@ void EasyTreeWidget::onSelectedThreadChange(::profiler::thread_id_t _id)
}
}
void EasyTreeWidget::onSelectedBlockChange(unsigned int _block_index)
void EasyTreeWidget::onSelectedBlockChange(uint32_t _block_index)
{
disconnect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange);

View File

@ -106,7 +106,9 @@ private slots:
void onSelectedThreadChange(::profiler::thread_id_t _id);
void onSelectedBlockChange(unsigned int _block_index);
void onSelectedBlockChange(uint32_t _block_index);
void onBlockEnableDisable(bool _checked);
void resizeColumnsToContents();

View File

@ -0,0 +1,309 @@
/************************************************************************
* file name : descriptors_tree_widget.cpp
* ----------------- :
* creation time : 2016/09/17
* author : Victor Zarubkin
* email : v.s.zarubkin@gmail.com
* ----------------- :
* description : The file contains implementation of EasyDescWidget and it's auxiliary classes
* : for displyaing EasyProfiler blocks descriptors tree.
* ----------------- :
* change log : * 2016/09/17 Victor Zarubkin: initial commit.
* :
* : *
* ----------------- :
* license : Lightweight profiler library for c++
* : Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
* :
* : This program is free software : you can redistribute it and / or modify
* : it under the terms of the GNU General Public License as published by
* : the Free Software Foundation, either version 3 of the License, or
* : (at your option) any later version.
* :
* : This program is distributed in the hope that it will be useful,
* : but WITHOUT ANY WARRANTY; without even the implied warranty of
* : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* : GNU General Public License for more details.
* :
* : You should have received a copy of the GNU General Public License
* : along with this program.If not, see <http://www.gnu.org/licenses/>.
************************************************************************/
#include <QMenu>
#include <QAction>
#include <QHeaderView>
#include <QString>
#include <QContextMenuEvent>
#include <QSignalBlocker>
#include <QSettings>
#include <QDebug>
#include <thread>
#include "descriptors_tree_widget.h"
#include "globals.h"
#include "../src/hashed_cstr.h"
#ifdef _WIN32
#include <Windows.h>
#endif
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
//////////////////////////////////////////////////////////////////////////
enum DescColumns
{
DESC_COL_FILE_LINE = 0,
DESC_COL_NAME,
DESC_COL_STATUS,
DESC_COL_COLUMNS_NUMBER
};
const auto ENABLED_COLOR = ::profiler::colors::LightGreen900;
const auto DISABLED_COLOR = ::profiler::colors::DarkRed;
//////////////////////////////////////////////////////////////////////////
EasyDescWidgetItem::EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent) : Parent(_parent), m_desc(_desc)
{
}
EasyDescWidgetItem::~EasyDescWidgetItem()
{
}
bool EasyDescWidgetItem::operator < (const Parent& _other) const
{
const auto col = treeWidget()->sortColumn();
switch (col)
{
case DESC_COL_FILE_LINE:
{
if (parent() != nullptr)
return data(col, Qt::UserRole).toInt() < _other.data(col, Qt::UserRole).toInt();
}
}
return Parent::operator < (_other);
}
//////////////////////////////////////////////////////////////////////////
EasyDescWidget::EasyDescWidget(QWidget* _parent)
: Parent(_parent)
{
setAutoFillBackground(false);
setAlternatingRowColors(true);
setItemsExpandable(true);
setAnimated(true);
setSortingEnabled(false);
setColumnCount(DESC_COL_COLUMNS_NUMBER);
auto header_item = new QTreeWidgetItem();
header_item->setText(DESC_COL_FILE_LINE, "File/Line");
header_item->setText(DESC_COL_NAME, "Name");
header_item->setText(DESC_COL_STATUS, "Status");
setHeaderItem(header_item);
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
connect(this, &Parent::itemDoubleClicked, this, &This::onDoubleClick);
loadSettings();
}
EasyDescWidget::~EasyDescWidget()
{
saveSettings();
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::clearSilent(bool)
{
const QSignalBlocker b(this);
setSortingEnabled(false);
::std::vector<QTreeWidgetItem*> topLevelItems;
topLevelItems.reserve(topLevelItemCount());
for (int i = topLevelItemCount() - 1; i >= 0; --i)
topLevelItems.push_back(takeTopLevelItem(i));
auto deleter_thread = ::std::thread([](decltype(topLevelItems) _items) {
for (auto item : _items)
delete item;
}, ::std::move(topLevelItems));
#ifdef _WIN32
SetThreadPriority(deleter_thread.native_handle(), THREAD_PRIORITY_LOWEST);
#endif
deleter_thread.detach();
//clear();
}
//////////////////////////////////////////////////////////////////////////
struct FileItems
{
typedef ::std::unordered_map<int, QTreeWidgetItem*, ::profiler_gui::do_no_hash<int>::hasher_t> Items;
Items children;
QTreeWidgetItem* item = nullptr;
};
void EasyDescWidget::build()
{
clearSilent(false);
auto f = header()->font();
f.setBold(true);
typedef ::std::unordered_map<::std::string, FileItems> Files;
Files m_files;
const QSignalBlocker b(this);
::profiler::block_id_t id = 0;
for (auto desc : EASY_GLOBALS.descriptors)
{
if (desc != nullptr)
{
auto& p = m_files[desc->file()];
if (p.item == nullptr)
{
p.item = new QTreeWidgetItem();
p.item->setText(DESC_COL_FILE_LINE, desc->file());
}
auto it = p.children.find(desc->line());
if (it == p.children.end())
{
auto item = new EasyDescWidgetItem(id, p.item);
item->setText(DESC_COL_FILE_LINE, QString::number(desc->line()));
item->setData(DESC_COL_FILE_LINE, Qt::UserRole, desc->line());
if (*desc->name() != 0)
item->setText(DESC_COL_NAME, desc->name());
item->setFont(DESC_COL_STATUS, f);
QBrush brush;
if (desc->enabled())
{
item->setText(DESC_COL_STATUS, "ON");
brush.setColor(QColor::fromRgba(ENABLED_COLOR));
}
else
{
item->setText(DESC_COL_STATUS, "OFF");
brush.setColor(QColor::fromRgba(DISABLED_COLOR));
}
item->setForeground(DESC_COL_STATUS, brush);
}
}
++id;
}
for (auto& p : m_files)
{
addTopLevelItem(p.second.item);
}
setSortingEnabled(true);
sortByColumn(DESC_COL_FILE_LINE, Qt::AscendingOrder);
resizeColumnsToContents();
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::onItemExpand(QTreeWidgetItem*)
{
resizeColumnsToContents();
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::onDoubleClick(QTreeWidgetItem* _item, int _column)
{
if (_column >= DESC_COL_NAME && _item->parent() != nullptr)
{
auto item = static_cast<EasyDescWidgetItem*>(_item);
auto& desc = easyDescriptor(item->desc());
QBrush brush;
if (desc.enabled())
{
desc.setEnabled(false);
item->setText(DESC_COL_STATUS, "OFF");
brush.setColor(QColor::fromRgba(DISABLED_COLOR));
}
else
{
desc.setEnabled(true);
item->setText(DESC_COL_STATUS, "ON");
brush.setColor(QColor::fromRgba(ENABLED_COLOR));
}
item->setForeground(DESC_COL_STATUS, brush);
emit EASY_GLOBALS.events.enableStatusChanged(item->desc(), desc.enabled());
}
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::resizeColumnsToContents()
{
for (int i = 0; i < DESC_COL_COLUMNS_NUMBER; ++i)
{
resizeColumnToContents(i);
}
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::contextMenuEvent(QContextMenuEvent* _event)
{
_event->accept();
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::onSelectedBlockChange(uint32_t _block_index)
{
}
//////////////////////////////////////////////////////////////////////////
void EasyDescWidget::loadSettings()
{
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
settings.beginGroup("desc_tree_widget");
// ...
settings.endGroup();
}
void EasyDescWidget::saveSettings()
{
QSettings settings(::profiler_gui::ORGANAZATION_NAME, ::profiler_gui::APPLICATION_NAME);
settings.beginGroup("desc_tree_widget");
// ...
settings.endGroup();
}
//////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,108 @@
/************************************************************************
* file name : descriptors_tree_widget.h
* ----------------- :
* creation time : 2016/09/17
* author : Victor Zarubkin
* email : v.s.zarubkin@gmail.com
* ----------------- :
* description : The file contains declaration of EasyDescWidget and it's auxiliary classes
* : for displyaing EasyProfiler blocks descriptors tree.
* ----------------- :
* change log : * 2016/09/17 Victor Zarubkin: initial commit.
* :
* : *
* ----------------- :
* license : Lightweight profiler library for c++
* : Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
* :
* : This program is free software : you can redistribute it and / or modify
* : it under the terms of the GNU General Public License as published by
* : the Free Software Foundation, either version 3 of the License, or
* : (at your option) any later version.
* :
* : This program is distributed in the hope that it will be useful,
* : but WITHOUT ANY WARRANTY; without even the implied warranty of
* : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* : GNU General Public License for more details.
* :
* : You should have received a copy of the GNU General Public License
* : along with this program.If not, see <http://www.gnu.org/licenses/>.
************************************************************************/
#ifndef EASY__DESCRIPTORS__WIDGET__H_
#define EASY__DESCRIPTORS__WIDGET__H_
#include <QTreeWidget>
#include "profiler/reader.h"
//////////////////////////////////////////////////////////////////////////
class EasyDescWidgetItem : public QTreeWidgetItem
{
typedef QTreeWidgetItem Parent;
typedef EasyDescWidgetItem This;
::profiler::block_id_t m_desc;
public:
explicit EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent = nullptr);
virtual ~EasyDescWidgetItem();
bool operator < (const Parent& _other) const override;
public:
// Public inline methods
inline ::profiler::block_id_t desc() const
{
return m_desc;
}
}; // END of class EasyDescWidgetItem.
//////////////////////////////////////////////////////////////////////////
class EasyDescWidget : public QTreeWidget
{
Q_OBJECT
typedef QTreeWidget Parent;
typedef EasyDescWidget This;
protected:
public:
explicit EasyDescWidget(QWidget* _parent = nullptr);
virtual ~EasyDescWidget();
public slots:
void clearSilent(bool _global = false);
void build();
protected:
void contextMenuEvent(QContextMenuEvent* _event) override;
private slots:
void onItemExpand(QTreeWidgetItem* _item);
void onDoubleClick(QTreeWidgetItem* _item, int _column);
void onSelectedBlockChange(uint32_t _block_index);
void resizeColumnsToContents();
protected:
void loadSettings();
void saveSettings();
}; // END of class EasyDescWidget.
//////////////////////////////////////////////////////////////////////////
#endif // EASY__DESCRIPTORS__WIDGET__H_

View File

@ -48,10 +48,11 @@ namespace profiler_gui {
signals:
void selectedThreadChanged(::profiler::thread_id_t _id);
void selectedBlockChanged(unsigned int _block_index);
void selectedBlockChanged(uint32_t _block_index);
void itemsExpandStateChanged();
void drawBordersChanged();
void chronoPositionChanged();
void enableStatusChanged(::profiler::block_id_t _id, bool _enabled);
}; // END of class EasyGlobalSignals.

View File

@ -49,9 +49,12 @@
#include <QProgressDialog>
#include <QSignalBlocker>
#include <QDebug>
#include <QDialog>
#include <QVBoxLayout>
#include "main_window.h"
#include "blocks_tree_widget.h"
#include "blocks_graphics_view.h"
#include "descriptors_tree_widget.h"
#include "globals.h"
//////////////////////////////////////////////////////////////////////////
@ -60,7 +63,7 @@ const int LOADER_TIMER_INTERVAL = 40;
//////////////////////////////////////////////////////////////////////////
EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsView(nullptr), m_progress(nullptr)
EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsView(nullptr), m_progress(nullptr), m_editBlocksAction(nullptr)
{
{ QIcon icon(":/logo"); if (!icon.isNull()) QApplication::setWindowIcon(icon); }
@ -173,8 +176,17 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_treeWidget(nullptr), m_graphicsVi
menu = new QMenu("&Edit");
action = menu->addAction("Edit blocks");
action->setEnabled(false);
connect(action, &QAction::triggered, this, &This::onEditBlocksClicked);
m_editBlocksAction = action;
menuBar()->addMenu(menu);
menu = new QMenu("&Settings");
action = new QAction("Statistics enabled", nullptr);
action = menu->addAction("Statistics enabled");
action->setCheckable(true);
action->setChecked(EASY_GLOBALS.enable_statistics);
connect(action, &QAction::triggered, this, &This::onEnableDisableStatistics);
@ -368,6 +380,24 @@ void EasyMainWindow::onCollapseAllClicked(bool)
//////////////////////////////////////////////////////////////////////////
void EasyMainWindow::onEditBlocksClicked(bool)
{
QDialog d(this);
d.setWindowTitle("EasyProfiler");
d.resize(800, 600);
auto descTree = new EasyDescWidget();
descTree->build();
auto l = new QVBoxLayout(&d);
l->addWidget(descTree);
d.setLayout(l);
d.exec();
}
//////////////////////////////////////////////////////////////////////////
void EasyMainWindow::closeEvent(QCloseEvent* close_event)
{
saveSettingsAndGeometry();
@ -503,6 +533,8 @@ void EasyMainWindow::onFileReaderTimeout()
}
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->view()->setTree(EASY_GLOBALS.profiler_blocks);
m_editBlocksAction->setEnabled(true);
}
else
{

View File

@ -89,6 +89,7 @@ protected:
QDockWidget* m_treeWidget;
QDockWidget* m_graphicsView;
class QProgressDialog* m_progress;
class QAction* m_editBlocksAction;
QTimer m_readerTimer;
::profiler::SerializedData m_serializedBlocks;
::profiler::SerializedData m_serializedDescriptors;
@ -96,7 +97,7 @@ protected:
public:
EasyMainWindow();
explicit EasyMainWindow();
virtual ~EasyMainWindow();
// Public virtual methods
@ -119,6 +120,7 @@ protected slots:
void onCollapseAllClicked(bool);
void onFileReaderTimeout();
void onFileReaderCancel();
void onEditBlocksClicked(bool);
private: