diff --git a/profiler_gui/arbitrary_value_tooltip.cpp b/profiler_gui/arbitrary_value_tooltip.cpp index abd480b..6e7a1f4 100644 --- a/profiler_gui/arbitrary_value_tooltip.cpp +++ b/profiler_gui/arbitrary_value_tooltip.cpp @@ -61,12 +61,10 @@ ArbitraryValueToolTip::ArbitraryValueToolTip(const QString& _name , const profiler::BlocksTree& _block, QWidget* _parent) - : QWidget(_parent) + : QWidget(_parent, Qt::ToolTip | Qt::WindowStaysOnTopHint) { - setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); - auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); + //layout->setContentsMargins(1, 1, 1, 1); layout->setSpacing(0); auto pane = new QTextEdit(); @@ -84,43 +82,51 @@ ArbitraryValueToolTip::ArbitraryValueToolTip(const QString& _name QString firstString; int rowsCount = 0; - if (_block.per_thread_stats != nullptr) - { - pane->append(QString("N calls/Thread: %1").arg(_block.per_thread_stats->calls_number)); - rowsCount = 1; - } - if (_block.value->isArray()) { const auto size = profiler_gui::valueArraySize(*_block.value); firstString = QString("%1 %2[%3] (0x%4)").arg(profiler_gui::valueTypeString(_block.value->type())) .arg(_name).arg(size).arg(_block.value->value_id(), 0, 16); pane->append(firstString); + rowsCount += 1; + + if (_block.per_thread_stats != nullptr) + { + pane->append(QString("N calls/Thread: %1").arg(_block.per_thread_stats->calls_number)); + rowsCount += 1; + } if (_block.value->type() == profiler::DataType::String) { pane->append(QString("value:\t%1").arg(profiler_gui::valueString(*_block.value))); - rowsCount += 2; + rowsCount += 1; } else { - rowsCount += size + 1; + rowsCount += size; for (int i = 0; i < size; ++i) pane->append(QString("[%1]\t%2").arg(i).arg(profiler_gui::valueString(*_block.value, i))); - if (rowsCount > 15) - rowsCount = 15; + if (rowsCount > 9) + rowsCount = 9; } } else { + rowsCount += 2; + firstString = QString("%1 %2 (0x%3)").arg(profiler_gui::valueTypeString(_block.value->type())) .arg(_name).arg(_block.value->value_id(), 0, 16); pane->append(firstString); - pane->append(QString("value:\t%1").arg(profiler_gui::valueString(*_block.value))); - rowsCount += 2; + if (_block.per_thread_stats != nullptr) + { + pane->append(QString("N calls/Thread: %1").arg(_block.per_thread_stats->calls_number)); + rowsCount += 1; + } + + pane->append(QString("value:\t%1").arg(profiler_gui::valueString(*_block.value))); } ++rowsCount; diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index 7bfd730..c89037f 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -304,6 +304,7 @@ BlocksGraphicsView::BlocksGraphicsView(QWidget* _parent) , m_bUpdatingRect(false) , m_bEmpty(true) , m_isArbitraryValueTooltip(false) + , m_bHovered(false) { initMode(); setScene(new QGraphicsScene(this)); @@ -383,7 +384,8 @@ void BlocksGraphicsView::clear() m_timelineStep = 1; m_offset = 0; // scroll back to the beginning of the scene - m_idleTimer.stop(); + if (m_idleTimer.isActive()) + m_idleTimer.stop(); m_idleTime = 0; // Reset necessary flags @@ -603,7 +605,8 @@ void BlocksGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocks notifyVisibleRegionPosChange(longestItem->items(0).front().left() - m_visibleRegionWidth * 0.25); } - m_idleTimer.start(IDLE_TIMER_INTERVAL); + if (m_bHovered && !m_idleTimer.isActive()) + m_idleTimer.start(); } const BlocksGraphicsView::Items &BlocksGraphicsView::getItems() const @@ -791,31 +794,6 @@ void BlocksGraphicsView::repaintScene() ////////////////////////////////////////////////////////////////////////// -bool BlocksGraphicsView::eventFilter(QObject* _object, QEvent* _event) -{ - if (_object == m_popupWidget) - { - switch (_event->type()) - { - case QEvent::HoverEnter: - case QEvent::HoverLeave: - case QEvent::HoverMove: - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseButtonDblClick: - case QEvent::MouseMove: - m_idleTime = 0; - break; - } - - return false; - } - - return Parent::eventFilter(_object, _event); -} - -////////////////////////////////////////////////////////////////////////// - void BlocksGraphicsView::scaleTo(qreal _scale) { if (m_bEmpty) @@ -836,6 +814,28 @@ void BlocksGraphicsView::scaleTo(qreal _scale) repaintScene(); } +////////////////////////////////////////////////////////////////////////// + +void BlocksGraphicsView::enterEvent(QEvent* _event) +{ + Parent::enterEvent(_event); + m_bHovered = true; + if (!m_bEmpty && !m_idleTimer.isActive()) + m_idleTimer.start(); + m_idleTime = 0; +} + +void BlocksGraphicsView::leaveEvent(QEvent* _event) +{ + Parent::leaveEvent(_event); + m_bHovered = false; + if (m_idleTimer.isActive()) + m_idleTimer.stop(); + m_idleTime = 0; +} + +////////////////////////////////////////////////////////////////////////// + void BlocksGraphicsView::wheelEvent(QWheelEvent* _event) { if (needToIgnoreMouseEvent()) @@ -1508,6 +1508,8 @@ void BlocksGraphicsView::initMode() connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout); connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout); + m_idleTimer.setInterval(IDLE_TIMER_INTERVAL); + using profiler_gui::GlobalSignals; auto globalSignals = &EASY_GLOBALS.events; connect(globalSignals, &GlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange); @@ -1693,15 +1695,11 @@ void BlocksGraphicsView::onIdleTimeout() { const auto& itemBlock = cse->tree; - auto widget = new QWidget(nullptr); + auto widget = new QWidget(this, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput); if (widget == nullptr) return; widget->setObjectName(QStringLiteral("DiagramPopup")); - widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); - widget->setAttribute(Qt::WA_MouseTracking, true); - widget->setAttribute(Qt::WA_TransparentForMouseEvents, false); - widget->installEventFilter(this); auto lay = new QGridLayout(widget); if (lay == nullptr) @@ -1803,19 +1801,15 @@ void BlocksGraphicsView::onIdleTimeout() if (itemDesc.type() == profiler::BlockType::Value) { m_isArbitraryValueTooltip = true; - m_popupWidget = new ArbitraryValueToolTip(itemDesc.name(), itemBlock, nullptr); + m_popupWidget = new ArbitraryValueToolTip(itemDesc.name(), itemBlock, this); break; } - auto widget = new QWidget(nullptr); + auto widget = new QWidget(this, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput); if (widget == nullptr) return; widget->setObjectName(QStringLiteral("DiagramPopup")); - widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); - widget->setAttribute(Qt::WA_MouseTracking, true); - widget->setAttribute(Qt::WA_TransparentForMouseEvents, false); - widget->installEventFilter(this); auto lay = new QGridLayout(widget); if (lay == nullptr) @@ -2034,6 +2028,8 @@ void BlocksGraphicsView::onIdleTimeout() const auto h = std::min(m_popupWidget->height(), (int)m_visibleSceneRect.height()); m_popupWidget->setFixedSize(w, h); + const auto prevPos = scenePos; + auto br = m_popupWidget->rect(); if (scenePos.y() + br.height() > m_visibleSceneRect.bottom()) scenePos.setY(::std::max(scenePos.y() - br.height(), m_visibleSceneRect.top())); @@ -2041,7 +2037,8 @@ void BlocksGraphicsView::onIdleTimeout() if (scenePos.x() + br.width() > m_visibleSceneRect.right()) scenePos.setX(::std::max(scenePos.x() - br.width(), m_visibleSceneRect.left())); - m_popupWidget->move(mapToGlobal(mapFromScene(scenePos))); + if ((scenePos - prevPos).manhattanLength() != 0) + m_popupWidget->move(mapToGlobal(mapFromScene(scenePos))); } } @@ -2532,7 +2529,7 @@ void ThreadNamesWidget::onIdleTimeout() if (intersectingItem != nullptr) { - auto widget = new QWidget(nullptr, Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + auto widget = new QWidget(this, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput); if (widget == nullptr) return; diff --git a/profiler_gui/blocks_graphics_view.h b/profiler_gui/blocks_graphics_view.h index b0dc29d..5f44089 100644 --- a/profiler_gui/blocks_graphics_view.h +++ b/profiler_gui/blocks_graphics_view.h @@ -154,6 +154,7 @@ private: bool m_bUpdatingRect; ///< Stub flag which is used to avoid excess calculations on some scene update (flicking, scaling and so on) bool m_bEmpty; ///< Indicates whether scene is empty and has no items bool m_isArbitraryValueTooltip; + bool m_bHovered; public: @@ -162,7 +163,8 @@ public: // Public virtual methods - bool eventFilter(QObject* _object, QEvent* _event) override; + void enterEvent(QEvent* _event) override; + void leaveEvent(QEvent* _event) override; void wheelEvent(QWheelEvent* _event) override; void mousePressEvent(QMouseEvent* _event) override; void mouseDoubleClickEvent(QMouseEvent* _event) override; diff --git a/profiler_gui/blocks_tree_widget.cpp b/profiler_gui/blocks_tree_widget.cpp index ba97946..50f67b3 100644 --- a/profiler_gui/blocks_tree_widget.cpp +++ b/profiler_gui/blocks_tree_widget.cpp @@ -390,7 +390,7 @@ void BlocksTreeWidget::onIdleTimeout() if (item->hasToolTip(column)) return; - m_valueTooltip = new ArbitraryValueToolTip(itemUnderCursor->text(COL_NAME), block, nullptr); + m_valueTooltip = new ArbitraryValueToolTip(itemUnderCursor->text(COL_NAME), block, this); m_valueTooltip->move(QCursor::pos()); m_valueTooltip->show();