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

#0 [Gui] Saving dialog geometry; Added refresh button to arbitrary values widget; Fixed zoom-in algorithm

This commit is contained in:
Victor Zarubkin 2018-01-25 23:21:56 +03:00
parent a7a58acd1d
commit 230f7d1463
10 changed files with 161 additions and 68 deletions

View File

@ -61,6 +61,8 @@
#include <QResizeEvent>
#include <QVariant>
#include <QSettings>
#include <QToolBar>
#include <QAction>
#include <list>
#include "arbitrary_value_inspector.h"
#include "treeview_first_column_delegate.h"
@ -859,6 +861,7 @@ GraphicsChart::GraphicsChart(QWidget* _parent)
if (!EASY_GLOBALS.scene.empty)
{
const profiler_gui::BoolFlagGuard guard(m_bEmitChange, false);
setRange(EASY_GLOBALS.scene.left, EASY_GLOBALS.scene.right);
setSliderWidth(EASY_GLOBALS.scene.window);
setValue(EASY_GLOBALS.scene.offset);
@ -930,7 +933,9 @@ ArbitraryTreeWidgetItem::~ArbitraryTreeWidgetItem()
QVariant ArbitraryTreeWidgetItem::data(int _column, int _role) const
{
if (_column == CheckColumn && _role == Qt::SizeHintRole)
return QSize(m_widthHint, 26);
return QSize(static_cast<int>(m_widthHint * m_font.bold() ? 1.2f : 1.f), 26);
if (_role == Qt::FontRole)
return m_font;
return Parent::data(_column, _role);
}
@ -939,6 +944,11 @@ void ArbitraryTreeWidgetItem::setWidthHint(int _width)
m_widthHint = _width;
}
void ArbitraryTreeWidgetItem::setBold(bool _isBold)
{
m_font.setBold(_isBold);
}
const ArbitraryValuesCollection* ArbitraryTreeWidgetItem::collection() const
{
return m_collection.get();
@ -975,6 +985,7 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
, m_splitter(new QSplitter(Qt::Horizontal, this))
, m_treeWidget(new QTreeWidget(this))
, m_chart(new GraphicsChart(this))
, m_boldItem(nullptr)
{
m_splitter->setHandleWidth(1);
m_splitter->setContentsMargins(0, 0, 0, 0);
@ -983,8 +994,15 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
m_splitter->setStretchFactor(0, 1);
m_splitter->setStretchFactor(1, 1);
auto tb = new QToolBar(this);
tb->setIconSize(::profiler_gui::ICONS_SIZE);
auto refreshButton = tb->addAction(QIcon(imagePath("reload")), tr("Refresh values list"));
refreshButton->setToolTip(tr("Refresh arbitrary values list."));
connect(refreshButton, &QAction::triggered, this, &This::rebuild);
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(tb);
layout->addWidget(m_splitter);
m_treeWidget->setAutoFillBackground(false);
@ -1003,18 +1021,20 @@ ArbitraryValuesWidget::ArbitraryValuesWidget(QWidget* _parent)
headerItem->setText(int_cast(ArbitraryColumns::Vin), "ID");
m_treeWidget->setHeaderItem(headerItem);
connect(&m_timer, &QTimer::timeout, this, &This::rebuild);
connect(&m_collectionsTimer, &QTimer::timeout, this, &This::onCollectionsTimeout);
connect(m_treeWidget, &QTreeWidget::itemDoubleClicked, this, &This::onItemDoubleClicked);
connect(m_treeWidget, &QTreeWidget::itemChanged, this, &This::onItemChanged);
connect(m_treeWidget, &QTreeWidget::currentItemChanged, this, &This::onCurrentItemChanged);
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedThreadChanged, this, &This::onSelectedThreadChanged);
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChanged);
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged);
auto globalEvents = &EASY_GLOBALS.events;
connect(globalEvents, &profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChanged);
connect(globalEvents, &profiler_gui::EasyGlobalSignals::selectedBlockIdChanged, this, &This::onSelectedBlockIdChanged);
connect(globalEvents, &profiler_gui::EasyGlobalSignals::fileOpened, this, &This::rebuild);
loadSettings();
rebuild();
}
ArbitraryValuesWidget::~ArbitraryValuesWidget()
@ -1026,28 +1046,42 @@ void ArbitraryValuesWidget::clear()
{
if (m_collectionsTimer.isActive())
m_collectionsTimer.stop();
if (m_timer.isActive())
m_timer.stop();
m_checkedItems.clear();
m_treeWidget->clear();
}
void ArbitraryValuesWidget::onSelectedThreadChanged(::profiler::thread_id_t)
{
if (!m_timer.isActive())
m_timer.start(100);
m_boldItem = nullptr;
}
void ArbitraryValuesWidget::onSelectedBlockChanged(uint32_t)
{
if (!m_timer.isActive())
m_timer.start(100);
if (profiler_gui::is_max(EASY_GLOBALS.selected_block))
{
onSelectedBlockIdChanged(EASY_GLOBALS.selected_block_id);
return;
}
if (!profiler_gui::is_max(EASY_GLOBALS.selected_block))
return;
// TODO: find item corresponding to selected_block and make it bold
}
void ArbitraryValuesWidget::onSelectedBlockIdChanged(::profiler::block_id_t)
{
if (!m_timer.isActive())
m_timer.start(100);
if (!profiler_gui::is_max(EASY_GLOBALS.selected_block))
return;
if (profiler_gui::is_max(EASY_GLOBALS.selected_block_id))
{
if (m_boldItem != nullptr)
{
m_boldItem->setBold(false);
m_boldItem = nullptr;
}
return;
}
// TODO: find item corresponding to selected_block_id and make it bold
}
void ArbitraryValuesWidget::onItemDoubleClicked(QTreeWidgetItem* _item, int)

View File

@ -224,6 +224,7 @@ class ArbitraryTreeWidgetItem : public QTreeWidgetItem
using This = ArbitraryTreeWidgetItem;
using CollectionPtr = std::unique_ptr<ArbitraryValuesCollection>;
QFont m_font;
CollectionPtr m_collection;
profiler::vin_t m_vin;
profiler::color_t m_color;
@ -237,6 +238,7 @@ public:
QVariant data(int _column, int _role) const override;
void setWidthHint(int _width);
void setBold(bool _isBold);
const ArbitraryValuesCollection* collection() const;
void collectValues(profiler::thread_id_t _threadId);
@ -255,27 +257,27 @@ class ArbitraryValuesWidget : public QWidget
using Parent = QWidget;
using This = ArbitraryValuesWidget;
QTimer m_timer;
QTimer m_collectionsTimer;
QList<ArbitraryTreeWidgetItem*> m_checkedItems;
class QSplitter* m_splitter;
QTreeWidget* m_treeWidget;
GraphicsChart* m_chart;
ArbitraryTreeWidgetItem* m_boldItem;
public:
explicit ArbitraryValuesWidget(QWidget* _parent = nullptr);
~ArbitraryValuesWidget() override;
void clear();
void contextMenuEvent(QContextMenuEvent*) override {}
public slots:
void clear();
void rebuild();
private slots:
void onSelectedThreadChanged(profiler::thread_id_t _id);
void onSelectedBlockChanged(uint32_t _block_index);
void onSelectedBlockIdChanged(profiler::block_id_t _id);
void onItemDoubleClicked(QTreeWidgetItem* _item, int _column);

View File

@ -816,13 +816,12 @@ void EasyGraphicsView::scaleTo(qreal _scale)
void EasyGraphicsView::wheelEvent(QWheelEvent* _event)
{
m_idleTime = 0;
if (!m_bEmpty)
onWheel(mapToScene(_event->pos()).x(), _event->delta());
onWheel(mapToDiagram(mapToScene(_event->pos()).x()), _event->delta());
_event->accept();
}
void EasyGraphicsView::onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta)
void EasyGraphicsView::onGraphicsScrollbarWheel(qreal _scenePos, int _wheelDelta)
{
m_idleTime = 0;
@ -835,7 +834,7 @@ void EasyGraphicsView::onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta)
}
}
onWheel(_mouseX, _wheelDelta);
onWheel(_scenePos, _wheelDelta);
}
void EasyGraphicsView::scrollTo(const EasyGraphicsItem* _item)
@ -846,16 +845,23 @@ void EasyGraphicsView::scrollTo(const EasyGraphicsItem* _item)
m_bUpdatingRect = false;
}
void EasyGraphicsView::onWheel(qreal _mouseX, int _wheelDelta)
qreal EasyGraphicsView::mapToDiagram(qreal x) const
{
return m_offset + x / m_scale;
}
void EasyGraphicsView::onWheel(qreal _scenePos, int _wheelDelta)
{
const decltype(m_scale) scaleCoeff = _wheelDelta > 0 ? ::profiler_gui::SCALING_COEFFICIENT : ::profiler_gui::SCALING_COEFFICIENT_INV;
// Remember current mouse position
_mouseX = clamp(0., _mouseX, m_sceneWidth);
const auto mousePosition = m_offset + _mouseX / m_scale;
_scenePos = clamp(0., _scenePos, m_sceneWidth);
const auto initialPosition = _scenePos;
// have to limit scale because of Qt's QPainter feature: it doesn't draw text
// with very big coordinates (but it draw rectangles with the same coordinates good).
_scenePos -= m_offset;
_scenePos *= m_scale;
m_scale = clamp(MIN_SCALE, m_scale * scaleCoeff, MAX_SCALE);
//updateVisibleSceneRect(); // Update scene rect
@ -864,7 +870,7 @@ void EasyGraphicsView::onWheel(qreal _mouseX, int _wheelDelta)
notifyVisibleRegionSizeChange();
// Calculate new offset to simulate QGraphicsView::AnchorUnderMouse scaling behavior
m_offset = clamp(0., mousePosition - _mouseX / m_scale, m_sceneWidth - m_visibleRegionWidth);
m_offset = clamp(0., initialPosition - _scenePos / m_scale, m_sceneWidth - m_visibleRegionWidth);
// Update slider position
profiler_gui::BoolFlagGuard guard(m_bUpdatingRect, true); // To be sure that updateVisibleSceneRect will not be called by scrollbar change
@ -1312,13 +1318,13 @@ void EasyGraphicsView::keyPressEvent(QKeyEvent* _event)
case Qt::Key_Plus:
case Qt::Key_Equal:
{
onWheel(mapToScene(mapFromGlobal(QCursor::pos())).x(), KeyStep);
onWheel(mapToDiagram(mapToScene(mapFromGlobal(QCursor::pos())).x()), KeyStep);
break;
}
case Qt::Key_Minus:
{
onWheel(mapToScene(mapFromGlobal(QCursor::pos())).x(), -KeyStep);
onWheel(mapToDiagram(mapToScene(mapFromGlobal(QCursor::pos())).x()), -KeyStep);
break;
}
}

View File

@ -214,7 +214,8 @@ private:
void updateTimelineStep(qreal _windowWidth);
void scaleTo(qreal _scale);
void scrollTo(const EasyGraphicsItem* _item);
void onWheel(qreal _mouseX, int _wheelDelta);
qreal mapToDiagram(qreal x) const;
void onWheel(qreal _scenePos, int _wheelDelta);
qreal setTree(EasyGraphicsItem* _item, const ::profiler::BlocksTree::children_t& _children, qreal& _height, uint32_t& _maxDepthChild, qreal _y, short _level);
private slots:
@ -222,7 +223,7 @@ private slots:
// Private Slots
void repaintScene();
void onGraphicsScrollbarWheel(qreal _mouseX, int _wheelDelta);
void onGraphicsScrollbarWheel(qreal _scenePos, int _wheelDelta);
void onScrollbarValueChange(int);
void onGraphicsScrollbarValueChange(qreal);
void onFlickerTimeout();

View File

@ -1160,6 +1160,7 @@ EasyGraphicsScrollbar::EasyGraphicsScrollbar(int _initialHeight, QWidget* _paren
if (!EASY_GLOBALS.scene.empty)
{
const profiler_gui::BoolFlagGuard guard(m_bEmitChange, false);
setRange(EASY_GLOBALS.scene.left, EASY_GLOBALS.scene.right);
setSliderWidth(EASY_GLOBALS.scene.window);
setValue(EASY_GLOBALS.scene.offset);

View File

@ -107,7 +107,7 @@ namespace profiler_gui {
, highlight_blocks_with_same_id(true)
, selecting_block_changes_thread(true)
, auto_adjust_histogram_height(true)
, auto_adjust_chart_height(true)
, auto_adjust_chart_height(false)
, display_only_frames_on_histogram(false)
, bind_scene_and_tree_expand_status(true)
{

View File

@ -71,6 +71,8 @@ namespace profiler_gui {
signals:
void fileOpened();
void selectedThreadChanged(::profiler::thread_id_t _id);
void selectedBlockChanged(uint32_t _block_index);
void selectedBlockIdChanged(::profiler::block_id_t _id);

View File

@ -225,14 +225,14 @@ GraphicsSliderArea::GraphicsSliderArea(QWidget* _parent)
{
if (!m_bUpdatingPos)
{
m_bEmitChange = false;
const profiler_gui::BoolFlagGuard guard(m_bEmitChange, false);
setValue(pos);
m_bEmitChange = true;
}
});
connect(globalEvents, &profiler_gui::EasyGlobalSignals::sceneSizeChanged, [this] (qreal left, qreal right)
{
const profiler_gui::BoolFlagGuard guard(m_bEmitChange, false);
setRange(left, right);
m_slider->show();
});
@ -250,6 +250,7 @@ GraphicsSliderArea::~GraphicsSliderArea()
void GraphicsSliderArea::clear()
{
const profiler_gui::BoolFlagGuard guard(m_bEmitChange, false);
setRange(0, 100);
setSliderWidth(2);
setValue(0);
@ -504,8 +505,10 @@ void GraphicsSliderArea::wheelEvent(QWheelEvent* _event)
}
else
{
const auto x = (mapToScene(_event->pos()).x() - m_minimumValue) * m_windowScale;
emit EASY_GLOBALS.events.chartWheeled(x, _event->delta());
auto x = static_cast<qreal>(_event->pos().x()) / m_windowScale;
if (m_bBindMode)
x *= sliderWidth() / range();
emit EASY_GLOBALS.events.chartWheeled(m_value + x, _event->delta());
}
}

View File

@ -1238,31 +1238,32 @@ void EasyMainWindow::onFpsMonitorLineWidthChange(int _value)
void EasyMainWindow::onEditBlocksClicked(bool)
{
if (m_descTreeDialog != nullptr)
if (m_descTreeDialog.ptr != nullptr)
{
m_descTreeDialog->raise();
m_descTreeDialog.ptr->raise();
return;
}
m_descTreeDialog = new QDialog();
m_descTreeDialog->setAttribute(Qt::WA_DeleteOnClose, true);
m_descTreeDialog->setWindowTitle(EASY_DEFAULT_WINDOW_TITLE);
connect(m_descTreeDialog, &QDialog::finished, this, &This::onDescTreeDialogClose);
m_descTreeDialog.create();
connect(m_descTreeDialog.ptr, &QDialog::finished, this, &This::onDescTreeDialogClose);
auto l = new QVBoxLayout(m_descTreeDialog);
m_dialogDescTree = new EasyDescWidget(m_descTreeDialog);
l->addWidget(m_dialogDescTree);
m_descTreeDialog->setLayout(l);
m_dialogDescTree = new EasyDescWidget(m_descTreeDialog.ptr);
auto lay = new QVBoxLayout(m_descTreeDialog.ptr);
lay->addWidget(m_dialogDescTree);
m_dialogDescTree->build();
m_descTreeDialog->show();
m_descTreeDialog.restoreGeometry();
m_descTreeDialog.ptr->show();
}
void EasyMainWindow::onDescTreeDialogClose(int)
{
disconnect(m_descTreeDialog, &QDialog::finished, this, &This::onDescTreeDialogClose);
disconnect(m_descTreeDialog.ptr, &QDialog::finished, this, &This::onDescTreeDialogClose);
m_descTreeDialog.saveGeometry();
m_dialogDescTree = nullptr;
m_descTreeDialog = nullptr;
m_descTreeDialog.ptr = nullptr;
}
//////////////////////////////////////////////////////////////////////////
@ -1278,15 +1279,15 @@ void EasyMainWindow::closeEvent(QCloseEvent* close_event)
}
}
saveSettingsAndGeometry();
if (m_descTreeDialog != nullptr)
if (m_descTreeDialog.ptr != nullptr)
{
m_descTreeDialog->reject();
m_descTreeDialog = nullptr;
m_descTreeDialog.ptr->reject();
m_descTreeDialog.ptr = nullptr;
m_dialogDescTree = nullptr;
}
saveSettingsAndGeometry();
Parent::closeEvent(close_event);
}
@ -1452,6 +1453,10 @@ void EasyMainWindow::loadGeometry()
if (!geometry.isEmpty())
m_fpsViewer->restoreGeometry(geometry);
geometry = settings.value("descTreeDialogGeometry").toByteArray();
if (!geometry.isEmpty())
m_descTreeDialog.geometry.swap(geometry);
geometry = settings.value("diagramGeometry").toByteArray();
if (!geometry.isEmpty())
m_graphicsView->restoreGeometry(geometry);
@ -1472,6 +1477,7 @@ void EasyMainWindow::saveSettingsAndGeometry()
settings.setValue("geometry", this->saveGeometry());
settings.setValue("fpsGeometry", m_fpsViewer->saveGeometry());
settings.setValue("descTreeDialogGeometry", m_descTreeDialog.geometry);
settings.setValue("diagramGeometry", m_graphicsView->saveGeometry());
static_cast<EasyGraphicsViewWidget*>(m_graphicsView->widget())->save(settings);
@ -1745,7 +1751,7 @@ void EasyMainWindow::onFileReaderTimeout()
{
if (m_reader.done())
{
auto nblocks = m_reader.size();
const auto nblocks = m_reader.size();
if (nblocks != 0)
{
static_cast<EasyHierarchyWidget*>(m_treeWidget->widget())->clear(true);
@ -1817,7 +1823,7 @@ void EasyMainWindow::onFileReaderTimeout()
EASY_GLOBALS.gui_blocks.clear();
EASY_GLOBALS.gui_blocks.resize(nblocks);
memset(EASY_GLOBALS.gui_blocks.data(), 0, sizeof(::profiler_gui::EasyBlock) * nblocks);
for (decltype(nblocks) i = 0; i < nblocks; ++i) {
for (std::remove_const<decltype(nblocks)>::type i = 0; i < nblocks; ++i) {
auto& guiblock = EASY_GLOBALS.gui_blocks[i];
guiblock.tree = ::std::move(blocks[i]);
#ifdef EASY_TREE_WIDGET__USE_VECTOR
@ -1859,9 +1865,11 @@ void EasyMainWindow::onFileReaderTimeout()
m_readerTimer.stop();
destroyProgressDialog();
if (EASY_GLOBALS.all_items_expanded_by_default)
if (nblocks != 0)
{
if (EASY_GLOBALS.all_items_expanded_by_default)
onExpandAllClicked(true);
emit EASY_GLOBALS.events.fileOpened();
}
}
else if (m_progress != nullptr)
@ -1960,12 +1968,9 @@ void EasyFileReader::load(::std::stringstream& _stream)
void EasyFileReader::interrupt()
{
m_progress.store(-100, ::std::memory_order_release);
if (m_thread.joinable())
m_thread.join();
join();
m_bDone.store(false, ::std::memory_order_release);
m_progress.store(0, ::std::memory_order_release);
m_size.store(0, ::std::memory_order_release);
m_serializedBlocks.clear();
m_serializedDescriptors.clear();
@ -1996,6 +2001,14 @@ void EasyFileReader::get(::profiler::SerializedData& _serializedBlocks, ::profil
}
}
void EasyFileReader::join()
{
m_progress.store(-100, ::std::memory_order_release);
if (m_thread.joinable())
m_thread.join();
m_progress.store(0, ::std::memory_order_release);
}
QString EasyFileReader::getError()
{
return QString(m_errorMessage.str().c_str());
@ -2283,13 +2296,13 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
m_serializedDescriptors.swap(serializedDescriptors);
m_descriptorsNumberInFile = static_cast<uint32_t>(EASY_GLOBALS.descriptors.size());
if (m_descTreeDialog != nullptr)
if (m_descTreeDialog.ptr != nullptr)
{
#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0
static_cast<EasyDescWidget*>(m_descTreeWidget->widget())->build();
#endif
m_dialogDescTree->build();
m_descTreeDialog->raise();
m_descTreeDialog.ptr->raise();
}
else
{
@ -2321,6 +2334,24 @@ void EasyMainWindow::onBlockStatusChange(::profiler::block_id_t _id, ::profiler:
m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast<uint8_t>(_status)));
}
void DialogWithGeometry::create()
{
ptr = new QDialog();
ptr->setAttribute(Qt::WA_DeleteOnClose, true);
ptr->setWindowTitle(EASY_DEFAULT_WINDOW_TITLE);
}
void DialogWithGeometry::saveGeometry()
{
geometry = ptr->saveGeometry();
}
void DialogWithGeometry::restoreGeometry()
{
if (!geometry.isEmpty())
ptr->restoreGeometry(geometry);
}
//////////////////////////////////////////////////////////////////////////
EasySocketListener::EasySocketListener() : m_receivedSize(0), m_port(0), m_regime(LISTENER_IDLE)

View File

@ -119,6 +119,8 @@ public:
::profiler::descriptors_list_t& _descriptors, ::profiler::blocks_t& _blocks, ::profiler::thread_blocks_tree_t& _tree,
uint32_t& _descriptorsNumberInFile, uint32_t& _version, QString& _filename);
void join();
QString getError();
}; // END of class EasyFileReader.
@ -202,14 +204,26 @@ public:
~EasyDockWidget() override;
};
struct DialogWithGeometry EASY_FINAL
{
QByteArray geometry;
class QDialog* ptr = nullptr;
void create();
void saveGeometry();
void restoreGeometry();
};
class EasyMainWindow : public QMainWindow
{
Q_OBJECT
protected:
typedef EasyMainWindow This;
typedef QMainWindow Parent;
using This = EasyMainWindow;
using Parent = QMainWindow;
DialogWithGeometry m_descTreeDialog;
QStringList m_lastFiles;
QString m_theme;
@ -223,7 +237,6 @@ protected:
#endif
class QProgressDialog* m_progress = nullptr;
class QDialog* m_descTreeDialog = nullptr;
class EasyDescWidget* m_dialogDescTree = nullptr;
class QMessageBox* m_listenerDialog = nullptr;
QTimer m_readerTimer;