0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-27 00:31:02 +08:00

#0 [GUI] Styling and optimization

This commit is contained in:
Victor Zarubkin 2017-11-27 22:02:15 +03:00
parent 010ac07ce0
commit e4305bf10b
14 changed files with 462 additions and 164 deletions

View File

@ -88,7 +88,7 @@ const qreal MIN_SCALE = pow(::profiler_gui::SCALING_COEFFICIENT_INV, 70); // Up
const qreal MAX_SCALE = pow(::profiler_gui::SCALING_COEFFICIENT, 45); // ~23000 --- Up to 10 ns scale
const qreal BASE_SCALE = pow(::profiler_gui::SCALING_COEFFICIENT_INV, 25); // ~0.003
EASY_CONSTEXPR uint16_t TIMELINE_ROW_SIZE = 20;
EASY_CONSTEXPR uint16_t TIMELINE_ROW_SIZE = 24;
EASY_CONSTEXPR QRgb BACKGROUND_1 = 0xffe4e4ec;
EASY_CONSTEXPR QRgb BACKGROUND_2 = ::profiler::colors::White;
@ -150,6 +150,7 @@ void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsIte
const auto h = visibleSceneRect.height();
const auto visibleBottom = h - 1;
const auto borderColor = QColor::fromRgb(TIMELINE_BORDER);
const auto textShiftY = h + TIMELINE_ROW_SIZE - 5;
QRectF rect;
@ -241,7 +242,8 @@ void EasyBackgroundItem::paint(QPainter* _painter, const QStyleOptionGraphicsIte
{
next = n;
_painter->setPen(::profiler_gui::TEXT_COLOR);
_painter->drawText(QPointF(current + 1, h + 17), QString::number(static_cast<quint64>(0.5 + (current + left) * factor / currentScale)));
_painter->drawText(QPointF(current + 1, textShiftY),
QString::number(static_cast<quint64>(0.5 + (current + left) * factor / currentScale)));
_painter->setPen(borderColor);
}
@ -1515,7 +1517,7 @@ void EasyGraphicsView::onIdleTimeout()
{
::profiler::block_index_t i = ~0U;
auto block = item->intersect(pos, i);
if (block)
if (block != nullptr)
{
const auto& itemBlock = block->tree;
const auto& itemDesc = easyDescriptor(itemBlock.node->id());
@ -1736,7 +1738,7 @@ void EasyGraphicsView::onIdleTimeout()
}
auto cse = item->intersectEvent(pos);
if (cse)
if (cse != nullptr)
{
const auto& itemBlock = cse->tree;

View File

@ -233,14 +233,17 @@ EasyTreeWidget::EasyTreeWidget(QWidget* _parent)
loadSettings();
m_columnsHiddenStatus[0] = 0;
setColumnHidden(0, false);
if (m_mode == EasyTreeMode_Full)
{
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
for (int i = 1; i < COL_COLUMNS_NUMBER; ++i)
m_columnsHiddenStatus[i] = isColumnHidden(i) ? 1 : 0;
}
else
{
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
for (int i = 1; i < COL_COLUMNS_NUMBER; ++i)
{
if (SIMPLIFIED_REGIME_COLUMNS[i])
{
@ -254,24 +257,18 @@ EasyTreeWidget::EasyTreeWidget(QWidget* _parent)
}
}
m_progress = new QProgressDialog("Building blocks hierarchy...", "", 0, 100, this, Qt::FramelessWindowHint);
m_progress->setAttribute(Qt::WA_TranslucentBackground);
m_progress->setCancelButton(nullptr);
m_progress->setValue(100);
//m_progress->hide();
m_hintLabel = new QLabel("Use Right Mouse Button on the Diagram to build a hierarchy...\nPress and hold, move, release", this);
m_hintLabel->setAlignment(Qt::AlignCenter);
m_hintLabel->setStyleSheet("QLabel { color: gray; font: 12pt; }");
QTimer::singleShot(1500, this, &This::alignProgressBar);
setItemDelegateForColumn(0, new EasyItemDelegate(this));
}
EasyTreeWidget::~EasyTreeWidget()
{
saveSettings();
delete m_progress;
delete m_hintLabel;
}
//////////////////////////////////////////////////////////////////////////
@ -295,11 +292,7 @@ void EasyTreeWidget::onFillTimerTimeout()
}
}
if (m_progress)
{
m_progress->setValue(100);
//m_progress->hide();
}
destroyProgressDialog();
m_bLocked = false;
m_inputBlocks.clear();
@ -319,7 +312,7 @@ void EasyTreeWidget::onFillTimerTimeout()
onSelectedThreadChange(EASY_GLOBALS.selected_thread);
onSelectedBlockChange(EASY_GLOBALS.selected_block);
}
else
else if (m_progress != nullptr)
{
m_progress->setValue(m_hierarchyBuilder.progress());
}
@ -333,8 +326,7 @@ void EasyTreeWidget::setTree(const unsigned int _blocksNumber, const ::profiler:
{
m_bLocked = true;
m_hintLabel->hide();
m_progress->setValue(0);
m_progress->show();
createProgressDialog();
m_hierarchyBuilder.fillTree(m_beginTime, _blocksNumber, _blocksTree, m_bColorRows, m_mode);
m_fillTimer.start(HIERARCHY_BUILDER_TIMER_INTERVAL);
}
@ -367,8 +359,7 @@ void EasyTreeWidget::setTreeBlocks(const ::profiler_gui::TreeBlocks& _blocks, ::
{
m_bLocked = true;
m_hintLabel->hide();
m_progress->setValue(0);
m_progress->show();
createProgressDialog();
m_hierarchyBuilder.fillTreeBlocks(m_inputBlocks, _session_begin_time, _left, _right, _strict, m_bColorRows, m_mode);
m_fillTimer.start(HIERARCHY_BUILDER_TIMER_INTERVAL);
}
@ -403,13 +394,7 @@ void EasyTreeWidget::clearSilent(bool _global)
const QSignalBlocker b(this);
m_hierarchyBuilder.interrupt();
if (m_progress)
{
m_progress->setValue(100);
//m_progress->hide();
}
destroyProgressDialog();
m_hintLabel->show();
m_bLocked = false;
@ -451,7 +436,7 @@ void EasyTreeWidget::clearSilent(bool _global)
m_roots.clear();
::std::vector<QTreeWidgetItem*> topLevelItems;
topLevelItems.reserve(topLevelItemCount());
topLevelItems.reserve(static_cast<size_t>(topLevelItemCount()));
for (int i = topLevelItemCount() - 1; i >= 0; --i)
topLevelItems.push_back(takeTopLevelItem(i));
@ -723,13 +708,13 @@ void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
auto hidemenu = menu.addMenu("Select columns");
auto hdr = headerItem();
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
for (int i = 1; i < COL_COLUMNS_NUMBER; ++i)
{
auto columnAction = new QAction(hdr->text(i), nullptr);
columnAction->setData(i);
columnAction->setCheckable(true);
columnAction->setChecked(m_columnsHiddenStatus[i] == 0);// !isColumnHidden(i));
if (m_mode == EasyTreeMode_Full || SIMPLIFIED_REGIME_COLUMNS[i])
columnAction->setChecked(m_columnsHiddenStatus[i] == 0);
if ((m_mode == EasyTreeMode_Full || SIMPLIFIED_REGIME_COLUMNS[i]))
connect(columnAction, &QAction::triggered, this, &This::onHideShowColumn);
else
columnAction->setEnabled(false);
@ -759,10 +744,36 @@ void EasyTreeWidget::alignProgressBar()
{
auto center = rect().center();
auto pos = mapToGlobal(center);
if (m_progress != nullptr)
m_progress->move(pos.x() - (m_progress->width() >> 1), pos.y() - (m_progress->height() >> 1));
m_hintLabel->move(center.x() - (m_hintLabel->width() >> 1), std::max(center.y() - (m_hintLabel->height() >> 1), header()->height()));
}
void EasyTreeWidget::destroyProgressDialog()
{
if (m_progress != nullptr)
{
m_progress->setValue(100);
m_progress->deleteLater();
m_progress = nullptr;
}
}
void EasyTreeWidget::createProgressDialog()
{
destroyProgressDialog();
m_progress = new QProgressDialog("Building blocks hierarchy...", "", 0, 100, this, Qt::FramelessWindowHint);
m_progress->setAttribute(Qt::WA_TranslucentBackground);
m_progress->setCancelButton(nullptr);
m_progress->setValue(0);
m_progress->show();
alignProgressBar();
}
//////////////////////////////////////////////////////////////////////////
void EasyTreeWidget::onJumpToItemClicked(bool)
@ -976,8 +987,11 @@ void EasyTreeWidget::onSelectedThreadChange(::profiler::thread_id_t _id)
{
for (auto& it : m_roots)
{
it.second->colorize(it.first == _id);
auto item = it.second;
item->setMain(it.first == _id);
item->colorize(it.first == _id);
}
}
void EasyTreeWidget::onSelectedBlockChange(uint32_t _block_index)
@ -1078,12 +1092,12 @@ void EasyTreeWidget::onModeChange(bool)
if (m_mode == EasyTreeMode_Full)
{
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
for (int i = 1; i < COL_COLUMNS_NUMBER; ++i)
setColumnHidden(i, m_columnsHiddenStatus[i] != 0);
}
else
{
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
for (int i = 1; i < COL_COLUMNS_NUMBER; ++i)
setColumnHidden(i, m_columnsHiddenStatus[i] != 0 || !SIMPLIFIED_REGIME_COLUMNS[i]);
}

View File

@ -157,6 +157,11 @@ protected:
void saveSettings();
void alignProgressBar();
private:
void destroyProgressDialog();
void createProgressDialog();
}; // END of class EasyTreeWidget.
//////////////////////////////////////////////////////////////////////////

View File

@ -67,7 +67,9 @@
#include <QToolBar>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QVariant>
#include <QTimer>
#include <QPainter>
#include <thread>
#include "descriptors_tree_widget.h"
#include "globals.h"
@ -183,7 +185,10 @@ const char* statusText(::profiler::EasyBlockStatus _status)
//////////////////////////////////////////////////////////////////////////
EasyDescWidgetItem::EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent) : Parent(_parent), m_desc(_desc)
EasyDescWidgetItem::EasyDescWidgetItem(::profiler::block_id_t _desc, Parent* _parent)
: Parent(_parent)
, m_desc(_desc)
, m_type(EasyDescWidgetItem::Type::File)
{
}
@ -209,6 +214,33 @@ bool EasyDescWidgetItem::operator < (const Parent& _other) const
return Parent::operator < (_other);
}
QVariant EasyDescWidgetItem::data(int _column, int _role) const
{
if (_column == DESC_COL_TYPE)
{
if (_role == Qt::ToolTipRole)
{
switch (m_type)
{
case Type::File: return QStringLiteral("File");
case Type::Event: return QStringLiteral("Event");
case Type::Block: return QStringLiteral("Block");
}
}
else if (_role == Qt::DisplayRole)
{
switch (m_type)
{
case Type::File: return QStringLiteral("F");
case Type::Event: return QStringLiteral("E");
case Type::Block: return QStringLiteral("B");
}
}
}
return QTreeWidgetItem::data(_column, _role);
}
//////////////////////////////////////////////////////////////////////////
EasyDescTreeWidget::EasyDescTreeWidget(QWidget* _parent)
@ -224,6 +256,7 @@ EasyDescTreeWidget::EasyDescTreeWidget(QWidget* _parent)
setAnimated(true);
setSortingEnabled(false);
setColumnCount(DESC_COL_COLUMNS_NUMBER);
setSelectionBehavior(QAbstractItemView::SelectRows);
auto header_item = new QTreeWidgetItem();
header_item->setText(DESC_COL_FILE_LINE, "File/Line");
@ -239,6 +272,8 @@ EasyDescTreeWidget::EasyDescTreeWidget(QWidget* _parent)
connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange);
loadSettings();
setItemDelegateForColumn(0, new EasyDescItemDelegate(this));
}
EasyDescTreeWidget::~EasyDescTreeWidget()
@ -393,10 +428,10 @@ void EasyDescTreeWidget::build()
auto& p = fileItems[desc->file()];
if (p.item == nullptr)
{
p.item = new QTreeWidgetItem();
p.item->setText(DESC_COL_FILE_LINE, QString(desc->file()).remove(QRegExp("^(\\.{2}\\\\+|\\/+)+")));
p.item->setText(DESC_COL_TYPE, "F");
p.item->setToolTip(DESC_COL_TYPE, "File");
auto item = new EasyDescWidgetItem(0);
item->setText(DESC_COL_FILE_LINE, QString(desc->file()).remove(QRegExp("^(\\.{2}\\\\+|\\/+)+")));
item->setType(EasyDescWidgetItem::Type::File);
p.item = item;
}
auto it = p.children.find(desc->line());
@ -408,15 +443,9 @@ void EasyDescTreeWidget::build()
item->setText(DESC_COL_NAME, desc->name());
if (desc->type() == ::profiler::BlockType::Block)
{
item->setText(DESC_COL_TYPE, "B");
item->setToolTip(DESC_COL_TYPE, "Block");
}
item->setType(EasyDescWidgetItem::Type::Block);
else
{
item->setText(DESC_COL_TYPE, "E");
item->setToolTip(DESC_COL_TYPE, "Event");
}
item->setType(EasyDescWidgetItem::Type::Event);
item->setFont(DESC_COL_STATUS, f);
item->setText(DESC_COL_STATUS, statusText(desc->status()));
@ -751,7 +780,7 @@ EasyDescWidget::EasyDescWidget(QWidget* _parent) : Parent(_parent)
QMenu* menu = new QMenu(this);
auto menu = new QMenu(this);
m_searchButton = menu->menuAction();
m_searchButton->setText("Find next");
m_searchButton->setIcon(QIcon(imagePath("find-next")));
@ -917,3 +946,32 @@ void EasyDescWidget::findPrevFromMenu(bool _checked)
}
//////////////////////////////////////////////////////////////////////////
EasyDescItemDelegate::EasyDescItemDelegate(QObject* parent) : QStyledItemDelegate(parent)
{
}
EasyDescItemDelegate::~EasyDescItemDelegate()
{
}
void EasyDescItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
// Draw item as usual
QStyledItemDelegate::paint(painter, option, index);
// Draw line under tree indicator
const auto bottomLeft = option.rect.bottomLeft();
if (bottomLeft.x() > 0)
{
painter->save();
painter->setBrush(Qt::NoBrush);
painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR);
painter->drawLine(QPoint(0, bottomLeft.y()), bottomLeft);
painter->restore();
}
}
//////////////////////////////////////////////////////////////////////////

View File

@ -57,6 +57,7 @@
#define EASY_DESCRIPTORS_WIDGET_H
#include <QTreeWidget>
#include <QStyledItemDelegate>
#include <QString>
#include <vector>
@ -68,10 +69,22 @@
class EasyDescWidgetItem : public QTreeWidgetItem
{
typedef QTreeWidgetItem Parent;
typedef EasyDescWidgetItem This;
using Parent = QTreeWidgetItem;
using This = EasyDescWidgetItem;
public:
enum class Type : uint8_t
{
File,
Event,
Block
};
private:
::profiler::block_id_t m_desc;
Type m_type;
public:
@ -79,6 +92,7 @@ public:
virtual ~EasyDescWidgetItem();
bool operator < (const Parent& _other) const override;
QVariant data(int _column, int _role) const override;
public:
@ -89,10 +103,29 @@ public:
return m_desc;
}
inline void setType(Type _type)
{
m_type = _type;
}
}; // END of class EasyDescWidgetItem.
//////////////////////////////////////////////////////////////////////////
class EasyDescItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit EasyDescItemDelegate(QObject* parent = nullptr);
~EasyDescItemDelegate() override;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
}; // END of class EasyDescItemDelegate.
//////////////////////////////////////////////////////////////////////////
class EasyDescTreeWidget : public QTreeWidget
{
Q_OBJECT

View File

@ -222,7 +222,7 @@ void EasyGraphicsItem::paintChildren(const float _minWidth, const int _narrowSiz
const auto& itemDesc = easyDescriptor(itemBlock.tree.node->id());
int h = 0, flags = 0;
int h = 0;
bool do_paint_children = false;
if ((EASY_GLOBALS.hide_narrow_children && w < EASY_GLOBALS.blocks_narrow_size) || !itemBlock.expanded)
{
@ -304,11 +304,6 @@ void EasyGraphicsItem::paintChildren(const float _minWidth, const int _narrowSiz
if (wprev < EASY_GLOBALS.blocks_narrow_size)
continue;
if (totalHeight > ::profiler_gui::GRAPHICS_ROW_SIZE)
flags = Qt::AlignCenter;
else if (!(item.width() < 1))
flags = Qt::AlignHCenter;
if (dw > 1)
{
w -= dw;
@ -395,9 +390,6 @@ void EasyGraphicsItem::paintChildren(const float _minWidth, const int _narrowSiz
continue;
}
if (!(item.width() < 1))
flags = Qt::AlignHCenter;
if (dw > 1)
{
w -= dw;
@ -420,7 +412,7 @@ void EasyGraphicsItem::paintChildren(const float _minWidth, const int _narrowSiz
// drawing text
auto name = *itemBlock.tree.node->name() != 0 ? itemBlock.tree.node->name() : itemDesc.name();
_painter->drawText(p.rect, flags, ::profiler_gui::toUnicode(name));
_painter->drawText(p.rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name));
// restore previous pen color
if (p.previousPenStyle == Qt::NoPen)
@ -630,7 +622,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
#endif
const auto& itemDesc = easyDescriptor(itemBlock.tree.node->id());
int h = 0, flags = 0;
int h = 0;
#ifdef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
bool do_paint_children = false;
@ -716,11 +708,6 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
if (wprev < EASY_GLOBALS.blocks_narrow_size)
continue;
if (totalHeight > ::profiler_gui::GRAPHICS_ROW_SIZE)
flags = Qt::AlignCenter;
else if (!(item.width() < 1))
flags = Qt::AlignHCenter;
if (dw > 1) {
w -= dw;
x += 2;
@ -813,8 +800,6 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
#ifndef EASY_GRAPHICS_ITEM_RECURSIVE_PAINT
dont_skip_children(next_level, item.children_begin, BLOCK_ITEM_DO_PAINT);
#endif
if (!(item.width() < 1))
flags = Qt::AlignHCenter;
if (dw > 1) {
w -= dw;
@ -839,7 +824,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
// drawing text
auto name = *itemBlock.tree.node->name() != 0 ? itemBlock.tree.node->name() : itemDesc.name();
_painter->drawText(p.rect, flags, ::profiler_gui::toUnicode(name));
_painter->drawText(p.rect, Qt::AlignCenter, ::profiler_gui::toUnicode(name));
// restore previous pen color
if (p.previousPenStyle == Qt::NoPen)
@ -979,7 +964,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
//firstSync = m_pRoot->sync.begin();
p.previousColor = 0;
qreal prevRight = -1e100, top = y() - 4, h = 3;
qreal prevRight = -1e100, top = y() - 6, h = 3;
if (top + h < p.visibleBottom)
{
_painter->setPen(BORDERS_COLOR);
@ -1056,7 +1041,7 @@ void EasyGraphicsItem::paint(QPainter* _painter, const QStyleOptionGraphicsItem*
}
p.previousColor = 0;
qreal prevRight = -1e100, top = y() + boundingRect().height() - 1, h = 3;
qreal prevRight = -1e100, top = y() + boundingRect().height() + 1, h = 3;
if (top + h < p.visibleBottom)
{
_painter->setPen(BORDERS_COLOR);
@ -1190,7 +1175,7 @@ const ::profiler_gui::EasyBlock* EasyGraphicsItem::intersect(const QPointF& _pos
return nullptr;
}
static const auto OVERLAP = ::profiler_gui::THREADS_ROW_SPACING >> 1;
EASY_STATIC_CONSTEXPR auto OVERLAP = (::profiler_gui::THREADS_ROW_SPACING >> 1) + 2;
const auto bottom = top + m_levels.size() * ::profiler_gui::GRAPHICS_ROW_SIZE_FULL + OVERLAP;
if (bottom < _pos.y())
{

View File

@ -85,10 +85,10 @@ namespace profiler_gui {
EASY_CONSTEXPR uint32_t V130 = 0x01030000;
EASY_CONSTEXPR QSize ICONS_SIZE(28, 28);
EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SIZE = 18;
EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SIZE = 20;
EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SPACING = 0;
EASY_CONSTEXPR uint16_t GRAPHICS_ROW_SIZE_FULL = GRAPHICS_ROW_SIZE + GRAPHICS_ROW_SPACING;
EASY_CONSTEXPR uint16_t THREADS_ROW_SPACING = 8;
EASY_CONSTEXPR uint16_t THREADS_ROW_SPACING = 10;
#ifdef _WIN32
EASY_CONSTEXPR qreal FONT_METRICS_FACTOR = 1.05;

View File

@ -726,14 +726,6 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_theme("default"), m_lastAddress("
connect(&m_fpsRequestTimer, &QTimer::timeout, this, &This::onFrameTimeRequestTimeout);
m_progress = new QProgressDialog("Loading file...", "Cancel", 0, 100, this);
m_progress->setFixedWidth(300);
m_progress->setWindowTitle(EASY_DEFAULT_WINDOW_TITLE);
m_progress->setModal(true);
m_progress->setValue(100);
//m_progress->hide();
connect(m_progress, &QProgressDialog::canceled, this, &This::onFileReaderCancel);
loadGeometry();
if(QCoreApplication::arguments().size() > 1)
@ -748,7 +740,6 @@ EasyMainWindow::EasyMainWindow() : Parent(), m_theme("default"), m_lastAddress("
EasyMainWindow::~EasyMainWindow()
{
delete m_progress;
}
//////////////////////////////////////////////////////////////////////////
@ -802,8 +793,12 @@ void EasyMainWindow::onThemeChange(bool)
if (action == nullptr)
return;
m_theme = action->text();
auto newTheme = action->text();
if (m_theme != newTheme)
{
m_theme = std::move(newTheme);
QMessageBox::information(this, "Theme", "You should restart the application to apply the theme.");
}
}
//////////////////////////////////////////////////////////////////////////
@ -876,20 +871,16 @@ void EasyMainWindow::loadFile(const QString& filename)
{
const auto i = filename.lastIndexOf(QChar('/'));
const auto j = filename.lastIndexOf(QChar('\\'));
m_progress->setLabelText(QString("Loading %1...").arg(filename.mid(::std::max(i, j) + 1)));
m_progress->setValue(0);
m_progress->show();
createProgressDialog(QString("Loading %1...").arg(filename.mid(::std::max(i, j) + 1)));
m_readerTimer.start(LOADER_TIMER_INTERVAL);
m_reader.load(filename);
}
void EasyMainWindow::readStream(::std::stringstream& data)
{
m_progress->setLabelText(tr("Reading from stream..."));
m_progress->setValue(0);
m_progress->show();
createProgressDialog(tr("Reading from stream..."));
m_readerTimer.start(LOADER_TIMER_INTERVAL);
m_reader.load(data);
}
@ -1492,6 +1483,30 @@ void EasyMainWindow::saveSettingsAndGeometry()
settings.endGroup();
}
void EasyMainWindow::destroyProgressDialog()
{
if (m_progress != nullptr)
{
m_progress->setValue(100);
m_progress->deleteLater();
m_progress = nullptr;
}
}
void EasyMainWindow::createProgressDialog(const QString& text)
{
destroyProgressDialog();
m_progress = new QProgressDialog(text, QStringLiteral("Cancel"), 0, 100, this);
connect(m_progress, &QProgressDialog::canceled, this, &This::onFileReaderCancel);
m_progress->setFixedWidth(300);
m_progress->setWindowTitle(EASY_DEFAULT_WINDOW_TITLE);
m_progress->setModal(true);
m_progress->setValue(0);
m_progress->show();
}
void EasyMainWindow::setDisconnected(bool _showMessage)
{
if (m_fpsRequestTimer.isActive())
@ -1812,15 +1827,14 @@ void EasyMainWindow::onFileReaderTimeout()
m_reader.interrupt();
m_readerTimer.stop();
m_progress->setValue(100);
//m_progress->hide();
destroyProgressDialog();
if (EASY_GLOBALS.all_items_expanded_by_default)
{
onExpandAllClicked(true);
}
}
else
else if (m_progress != nullptr)
{
m_progress->setValue(m_reader.progress());
}
@ -1830,8 +1844,7 @@ void EasyMainWindow::onFileReaderCancel()
{
m_readerTimer.stop();
m_reader.interrupt();
m_progress->setValue(100);
//m_progress->hide();
destroyProgressDialog();
}
//////////////////////////////////////////////////////////////////////////

View File

@ -325,6 +325,9 @@ private:
void setDisconnected(bool _showMessage = true);
void destroyProgressDialog();
void createProgressDialog(const QString& text);
}; // END of class EasyMainWindow.
//////////////////////////////////////////////////////////////////////////

View File

@ -24,20 +24,24 @@ EasyMainWindow, QToolBar, QDialog {
background-color: #f8f2f2; }
QToolTip {
background-color: #ffeccc;
border: 1px solid #cccccc; }
QGraphicsView {
border-color: #cccccc; }
/* ****************************************************************************************************************** */
QLineEdit, QComboBox, QSpinBox {
height: 24px;
border: 1px solid #cccccc;
background-color: white;
selection-background-color: rgba(136, 189, 136, 0.4);
selection-background-color: rgba(152, 222, 152, 0.5);
selection-color: #504040; }
QLineEdit:disabled, QComboBox:disabled, QSpinBox:disabled {
background-color: #f0f0f0;
color: #a08888;
selection-background-color: rgba(136, 189, 136, 0.4);
selection-background-color: rgba(152, 222, 152, 0.5);
selection-color: #a08888; }
QLineEdit:focus {
@ -126,12 +130,19 @@ QPushButton:pressed {
/* ****************************************************************************************************************** */
QListView {
background-color: white;
border: 1px solid #cccccc;
selection-background-color: rgba(136, 189, 136, 0.4);
border: 1px solid #cccccc; }
QListView, QTableView, QTreeView {
alternate-background-color: #e4e4ec;
selection-background-color: rgba(152, 222, 152, 0.8);
selection-color: #504040; }
QListView::item, QListView::item, QTableView::item, QTreeView::item {
height: 24px; }
QListView::item, QTableView::item, QTreeView::item {
height: 26px;
border-bottom: 1px solid #cccccc; }
QListView::item:selected, QTableView::item:selected, QTreeView::item:selected {
background-color: rgba(152, 222, 152, 0.8); }
/* ****************************************************************************************************************** */
QMenu {
@ -147,8 +158,8 @@ QMenu::item {
/* reserve space for selection border */ }
QMenu::item:selected {
border: 1px solid rgba(136, 189, 136, 0.4);
background-color: rgba(136, 189, 136, 0.4); }
border: 1px solid rgba(152, 222, 152, 0.5);
background-color: rgba(152, 222, 152, 0.5); }
QMenu::icon {
width: 14px;
@ -243,6 +254,7 @@ EasyDockWidget QWidget#EasyDockWidgetTitle {
background: none;
border: none;
max-height: 12px;
min-width: 12px;
max-width: 12px;
margin-right: 4px;
padding: 0; }
@ -310,15 +322,14 @@ QScrollBar::handle:pressed {
background-color: rgba(0, 0, 0, 0.6); }
QScrollBar::handle:vertical {
min-height: 20px;
min-height: 30px;
margin-left: 4px; }
QScrollBar::handle:vertical:hover, QScrollBar::handle:vertical:pressed {
margin-left: 0; }
QScrollBar::handle:horizontal {
min-width: 20px;
max-width: 100px;
min-width: 30px;
margin-top: 4px; }
QScrollBar::handle:horizontal:hover, QScrollBar::handle:horizontal:pressed {

View File

@ -19,7 +19,7 @@ $TextColor: #504040;
$DisabledTextColor: #a08888;
$BorderColor: #cccccc;
$MainColor: #f44336;
$HoveredMenuRowColor: rgb_a(#88BD88, 0.4);
$HoveredMenuRowColor: rgb_a(#98DE98, 0.5);
$BackgroundColor: white;
$DisabledBackgroundColor: #f0f0f0;
$ButtonHoverColor: #922c2c;//#d77d7d;
@ -47,9 +47,14 @@ EasyMainWindow, QToolBar, QDialog {
}
QToolTip {
background-color: #ffeccc;
border: 1px solid $BorderColor;
}
QGraphicsView {
border-color: $BorderColor;
}
/* ****************************************************************************************************************** */
QLineEdit, QComboBox, QSpinBox {
height: $DefaultHeight;
@ -139,12 +144,21 @@ QPushButton:pressed {
QListView {
background-color: $BackgroundColor;
border: 1px solid $BorderColor;
selection-background-color: $HoveredMenuRowColor;
}
QListView, QTableView, QTreeView {
alternate-background-color: #e4e4ec;
selection-background-color: rgb_a(#98DE98, 0.8);
selection-color: $TextColor;
}
QListView::item, QListView::item, QTableView::item, QTreeView::item {
height: $DefaultHeight;
QListView::item, QTableView::item, QTreeView::item {
height: $DefaultHeight + 2px;
border-bottom: 1px solid $BorderColor;
}
QListView::item:selected, QTableView::item:selected, QTreeView::item:selected {
background-color: rgb_a(#98DE98, 0.8);
}
/* ****************************************************************************************************************** */
@ -274,6 +288,7 @@ EasyDockWidget
background: none;
border: none;
max-height: 12px;
min-width: 12px;
max-width: 12px;
margin-right: 4px;
padding: 0;
@ -346,10 +361,10 @@ QScrollBar::handle:pressed {
background-color: rgb_a(#000000, 0.6);
}
QScrollBar::handle:vertical { min-height: 20px; margin-left: 4px; }
QScrollBar::handle:vertical { min-height: 30px; margin-left: 4px; }
QScrollBar::handle:vertical:hover, QScrollBar::handle:vertical:pressed { margin-left: 0; }
QScrollBar::handle:horizontal { min-width: 20px; max-width: 100px; margin-top: 4px; }
QScrollBar::handle:horizontal { min-width: 30px; margin-top: 4px; }
QScrollBar::handle:horizontal:hover, QScrollBar::handle:horizontal:pressed { margin-top: 0; }
QScrollBar::add-line, QScrollBar::sub-line {

View File

@ -55,16 +55,66 @@
#include "tree_widget_item.h"
#include "globals.h"
#include <QPainter>
#include <QPoint>
#include <QBrush>
#include <QRect>
#include <QSize>
#include <QVariant>
//////////////////////////////////////////////////////////////////////////
EASY_CONSTEXPR QRgb TEXT_RGB = 0xff504040;
EASY_CONSTEXPR int BlockColorRole = Qt::UserRole + 1;
//////////////////////////////////////////////////////////////////////////
EASY_CONSTEXPR int ColumnBit[COL_COLUMNS_NUMBER] = {
-1 // COL_NAME = 0,
, 0 // COL_BEGIN,
, 1 // COL_DURATION,
, 2 // COL_SELF_DURATION,
, 3 // COL_DURATION_SUM_PER_PARENT,
, 4 // COL_DURATION_SUM_PER_FRAME,
, 5 // COL_DURATION_SUM_PER_THREAD,
, -1 // COL_SELF_DURATION_PERCENT,
, -1 // COL_PERCENT_PER_PARENT,
, -1 // COL_PERCENT_PER_FRAME,
, -1 // COL_PERCENT_SUM_PER_PARENT,
, -1 // COL_PERCENT_SUM_PER_FRAME,
, -1 // COL_PERCENT_SUM_PER_THREAD,
, 6 // COL_END,
, 7 // COL_MIN_PER_FRAME,
, 8 // COL_MAX_PER_FRAME,
, 9 // COL_AVERAGE_PER_FRAME,
, -1 // COL_NCALLS_PER_FRAME,
, 10 // COL_MIN_PER_THREAD,
, 11 // COL_MAX_PER_THREAD,
, 12 // COL_AVERAGE_PER_THREAD,
, -1 // COL_NCALLS_PER_THREAD,
, 13 // COL_MIN_PER_PARENT,
, 14 // COL_MAX_PER_PARENT,
, 15 // COL_AVERAGE_PER_PARENT,
, -1 // COL_NCALLS_PER_PARENT,
, 16 // COL_ACTIVE_TIME,
, -1 // COL_ACTIVE_PERCENT,
};
//////////////////////////////////////////////////////////////////////////
EasyTreeWidgetItem::EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock, Parent* _parent)
: Parent(_parent)
, m_block(_treeBlock)
, m_customBGColor(0)
, m_customTextColor(TEXT_RGB)
, m_bColorized(false)
, m_bMain(false)
{
}
@ -119,6 +169,55 @@ bool EasyTreeWidgetItem::operator < (const Parent& _other) const
return false;
}
bool EasyTreeWidgetItem::hasToolTip(int _column) const
{
const int bit = ColumnBit[_column];
return bit < 0 ? false : m_bHasToolTip.test(static_cast<size_t>(bit));
}
void EasyTreeWidgetItem::setHasToolTip(int _column)
{
const int bit = ColumnBit[_column];
if (bit >= 0)
m_bHasToolTip.set(static_cast<size_t>(bit), true);
}
QVariant EasyTreeWidgetItem::data(int _column, int _role) const
{
if (_column == COL_NAME)
{
if (_role == Qt::SizeHintRole)
{
const float k = m_font.bold() ? 1.15f : 1.f;
return QSize(static_cast<int>(QFontMetrics(m_font).width(text(COL_NAME)) * k) + 20, 26);
}
if (_role == BlockColorRole)
{
if (m_bColorized)
return QBrush(QColor::fromRgba(m_customBGColor));
return QVariant();
}
}
switch (_role)
{
case Qt::FontRole:
return m_font;
case Qt::ForegroundRole:
return m_bMain ? QVariant::fromValue(QColor::fromRgb(::profiler_gui::SELECTED_THREAD_FOREGROUND)) : QVariant();
case Qt::ToolTipRole:
return hasToolTip(_column) ?
QVariant::fromValue(QString("%1 ns").arg(QTreeWidgetItem::data(_column, Qt::UserRole).toULongLong())) :
QVariant();
default:
return QTreeWidgetItem::data(_column, _role);
}
}
::profiler::block_index_t EasyTreeWidgetItem::block_index() const
{
return m_block;
@ -151,7 +250,7 @@ void EasyTreeWidgetItem::setTimeSmart(int _column, ::profiler_gui::TimeUnits _un
const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time);
setData(_column, Qt::UserRole, (quint64)nanosecondsTime);
setToolTip(_column, QString("%1 ns").arg(nanosecondsTime));
setHasToolTip(_column);
setText(_column, QString("%1%2").arg(_prefix).arg(::profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3)));
// if (_time < 1e3)
@ -177,7 +276,7 @@ void EasyTreeWidgetItem::setTimeSmart(int _column, ::profiler_gui::TimeUnits _un
const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time);
setData(_column, Qt::UserRole, (quint64)nanosecondsTime);
setToolTip(_column, QString("%1 ns").arg(nanosecondsTime));
setHasToolTip(_column);
setText(_column, ::profiler_gui::timeStringRealNs(_units, nanosecondsTime, 3));
}
@ -185,7 +284,7 @@ void EasyTreeWidgetItem::setTimeMs(int _column, const ::profiler::timestamp_t& _
{
const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time);
setData(_column, Qt::UserRole, (quint64)nanosecondsTime);
setToolTip(_column, QString("%1 ns").arg(nanosecondsTime));
setHasToolTip(_column);
setText(_column, QString::number(double(nanosecondsTime) * 1e-6, 'g', 9));
}
@ -193,7 +292,7 @@ void EasyTreeWidgetItem::setTimeMs(int _column, const ::profiler::timestamp_t& _
{
const ::profiler::timestamp_t nanosecondsTime = PROF_NANOSECONDS(_time);
setData(_column, Qt::UserRole, (quint64)nanosecondsTime);
setToolTip(_column, QString("%1 ns").arg(nanosecondsTime));
setHasToolTip(_column);
setText(_column, QString("%1%2").arg(_prefix).arg(double(nanosecondsTime) * 1e-6, 0, 'g', 9));
}
@ -202,31 +301,14 @@ void EasyTreeWidgetItem::setBackgroundColor(QRgb _color)
m_customBGColor = _color;
}
void EasyTreeWidgetItem::setTextColor(QRgb _color)
void EasyTreeWidgetItem::setMain(bool _main)
{
m_customTextColor = _color;
m_bMain = _main;
}
void EasyTreeWidgetItem::colorize(bool _colorize)
{
if (_colorize)
{
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
{
setBackground(i, QColor::fromRgba(m_customBGColor));
setForeground(i, QColor::fromRgb(m_customTextColor));
}
}
else
{
const QBrush nobrush;
const QBrush textbrush(::profiler_gui::TEXT_COLOR);
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
{
setBackground(i, nobrush);
setForeground(i, textbrush);
}
}
m_bColorized = _colorize;
}
void EasyTreeWidgetItem::collapseAll()
@ -255,10 +337,74 @@ void EasyTreeWidgetItem::expandAll()
void EasyTreeWidgetItem::setBold(bool _bold)
{
auto f = font(0);
f.setBold(_bold);
for (int i = 0; i < COL_COLUMNS_NUMBER; ++i)
setFont(i, f);
m_font.setBold(_bold);
}
//////////////////////////////////////////////////////////////////////////
EasyItemDelegate::EasyItemDelegate(QTreeWidget* parent) : QStyledItemDelegate(parent), m_treeWidget(parent)
{
}
EasyItemDelegate::~EasyItemDelegate()
{
}
void EasyItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
auto brushData = m_treeWidget->model()->data(index, BlockColorRole);
if (brushData.isNull())
{
// Draw item as usual
QStyledItemDelegate::paint(painter, option, index);
// Draw line under tree indicator
const auto bottomLeft = option.rect.bottomLeft();
if (bottomLeft.x() > 0)
{
painter->save();
painter->setBrush(Qt::NoBrush);
painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR);
painter->drawLine(QPoint(0, bottomLeft.y()), bottomLeft);
painter->restore();
}
return;
}
// Adjust rect size for drawing color marker
QStyleOptionViewItem opt = option;
opt.rect.adjust(16, 0, 0, 0);
// Draw item as usual
QStyledItemDelegate::paint(painter, opt, index);
painter->save();
const auto currentTreeIndex = m_treeWidget->currentIndex();
if (index.parent() == currentTreeIndex.parent() && index.row() == currentTreeIndex.row())
{
// Draw selection background for selected row
painter->setBrush(QColor::fromRgba(0xCC98DE98));
painter->setPen(Qt::NoPen);
painter->drawRect(QRect(option.rect.left(), option.rect.top(), 16, option.rect.height()));
}
// Draw color marker with block color
const auto brush = m_treeWidget->model()->data(index, Qt::UserRole + 1).value<QBrush>();
painter->setBrush(brush);
painter->setPen(::profiler_gui::SYSTEM_BORDER_COLOR);
painter->drawRect(QRect(option.rect.left(), option.rect.top() + 5, 16, option.rect.height() - 10));
// Draw line under tree indicator
const auto bottomLeft = opt.rect.bottomLeft();
if (bottomLeft.x() > 0)
{
painter->setBrush(Qt::NoBrush);
painter->drawLine(QPoint(0, bottomLeft.y()), bottomLeft);
}
painter->restore();
}

View File

@ -59,7 +59,9 @@
#include <stdlib.h>
#include <QTreeWidget>
#include <QStyledItemDelegate>
#include <easy/reader.h>
#include <bitset>
#include "common_types.h"
@ -116,19 +118,20 @@ class EasyTreeWidgetItem : public QTreeWidgetItem
typedef QTreeWidgetItem Parent;
typedef EasyTreeWidgetItem This;
QFont m_font;
const ::profiler::block_index_t m_block;
QRgb m_customBGColor;
QRgb m_customTextColor;
std::bitset<17> m_bHasToolTip;
bool m_bColorized;
bool m_bMain;
public:
using Parent::setBackgroundColor;
using Parent::setTextColor;
explicit EasyTreeWidgetItem(const ::profiler::block_index_t _treeBlock = ::profiler_gui::numeric_max<decltype(m_block)>(), Parent* _parent = nullptr);
virtual ~EasyTreeWidgetItem();
bool operator < (const Parent& _other) const override;
QVariant data(int _column, int _role) const override;
public:
@ -147,7 +150,7 @@ public:
void setBackgroundColor(QRgb _color);
void setTextColor(QRgb _color);
void setMain(bool _main);
void colorize(bool _colorize);
@ -157,8 +160,28 @@ public:
void setBold(bool _bold);
private:
bool hasToolTip(int _column) const;
void setHasToolTip(int _column);
}; // END of class EasyTreeWidgetItem.
//////////////////////////////////////////////////////////////////////////
class EasyItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
QTreeWidget* m_treeWidget;
public:
explicit EasyItemDelegate(QTreeWidget* parent = nullptr);
~EasyItemDelegate() override;
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
}; // END of class EasyItemDelegate.
//////////////////////////////////////////////////////////////////////////
#endif // EASY_TREE_WIDGET_ITEM_H

View File

@ -227,7 +227,6 @@ void EasyTreeWidgetLoader::setTreeInternal1(::profiler::timestamp_t& _beginTime,
item->setTimeSmart(COL_DURATION, _units, duration);
item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND);
//_items.push_back(item);
@ -316,7 +315,6 @@ void EasyTreeWidgetLoader::setTreeInternal2(const ::profiler::timestamp_t& _begi
thread_item->setTimeSmart(COL_DURATION, _units, duration);
thread_item->setBackgroundColor(::profiler_gui::SELECTED_THREAD_BACKGROUND);
thread_item->setTextColor(::profiler_gui::SELECTED_THREAD_FOREGROUND);
// Sum of all children durations:
thread_item->setTimeSmart(COL_SELF_DURATION, _units, block.root->profiled_time);
@ -442,10 +440,7 @@ void EasyTreeWidgetLoader::setTreeInternal2(const ::profiler::timestamp_t& _begi
}
const auto color = easyDescriptor(gui_block.tree.node->id()).color();
//const auto bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
const auto fgColor = ::profiler_gui::textColorForRgb(color);//0x00ffffff - bgColor;
item->setBackgroundColor(color);
item->setTextColor(fgColor);
#ifdef EASY_TREE_WIDGET__USE_VECTOR
auto item_index = static_cast<unsigned int>(m_items.size());
@ -693,10 +688,7 @@ size_t EasyTreeWidgetLoader::setTreeInternal(const ::profiler::BlocksTreeRoot& _
}
const auto color = easyDescriptor(child.node->id()).color();
//const auto bgColor = ::profiler_gui::fromProfilerRgb(::profiler::colors::get_red(color), ::profiler::colors::get_green(color), ::profiler::colors::get_blue(color));
const auto fgColor = ::profiler_gui::textColorForRgb(color);// 0x00ffffff - bgColor;
item->setBackgroundColor(color);
item->setTextColor(fgColor);
#ifdef EASY_TREE_WIDGET__USE_VECTOR
auto item_index = static_cast<uint32_t>(m_items.size());
@ -931,9 +923,7 @@ size_t EasyTreeWidgetLoader::setTreeInternalPlain(const ::profiler::BlocksTreeRo
}
const auto color = easyDescriptor(child.node->id()).color();
const auto fgColor = ::profiler_gui::textColorForRgb(color);// 0x00ffffff - bgColor;
item->setBackgroundColor(color);
item->setTextColor(fgColor);
#ifdef EASY_TREE_WIDGET__USE_VECTOR
auto item_index = static_cast<uint32_t>(m_items.size());