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

#0 [UI] Diagram tool-tips fix: no tool-tips if mouse cursor is over another widget (opened settings for example)

This commit is contained in:
Victor Zarubkin 2018-03-31 19:01:47 +03:00
parent c5ba69c8bc
commit cb8e66e9ae
4 changed files with 63 additions and 58 deletions

View File

@ -61,12 +61,10 @@
ArbitraryValueToolTip::ArbitraryValueToolTip(const QString& _name ArbitraryValueToolTip::ArbitraryValueToolTip(const QString& _name
, const profiler::BlocksTree& _block, QWidget* _parent) , 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); auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0); //layout->setContentsMargins(1, 1, 1, 1);
layout->setSpacing(0); layout->setSpacing(0);
auto pane = new QTextEdit(); auto pane = new QTextEdit();
@ -84,43 +82,51 @@ ArbitraryValueToolTip::ArbitraryValueToolTip(const QString& _name
QString firstString; QString firstString;
int rowsCount = 0; 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()) if (_block.value->isArray())
{ {
const auto size = profiler_gui::valueArraySize(*_block.value); const auto size = profiler_gui::valueArraySize(*_block.value);
firstString = QString("%1 %2[%3] (0x%4)").arg(profiler_gui::valueTypeString(_block.value->type())) 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); .arg(_name).arg(size).arg(_block.value->value_id(), 0, 16);
pane->append(firstString); 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) if (_block.value->type() == profiler::DataType::String)
{ {
pane->append(QString("value:\t%1").arg(profiler_gui::valueString(*_block.value))); pane->append(QString("value:\t%1").arg(profiler_gui::valueString(*_block.value)));
rowsCount += 2; rowsCount += 1;
} }
else else
{ {
rowsCount += size + 1; rowsCount += size;
for (int i = 0; i < size; ++i) for (int i = 0; i < size; ++i)
pane->append(QString("[%1]\t%2").arg(i).arg(profiler_gui::valueString(*_block.value, i))); pane->append(QString("[%1]\t%2").arg(i).arg(profiler_gui::valueString(*_block.value, i)));
if (rowsCount > 15) if (rowsCount > 9)
rowsCount = 15; rowsCount = 9;
} }
} }
else else
{ {
rowsCount += 2;
firstString = QString("%1 %2 (0x%3)").arg(profiler_gui::valueTypeString(_block.value->type())) firstString = QString("%1 %2 (0x%3)").arg(profiler_gui::valueTypeString(_block.value->type()))
.arg(_name).arg(_block.value->value_id(), 0, 16); .arg(_name).arg(_block.value->value_id(), 0, 16);
pane->append(firstString); 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; ++rowsCount;

View File

@ -304,6 +304,7 @@ BlocksGraphicsView::BlocksGraphicsView(QWidget* _parent)
, m_bUpdatingRect(false) , m_bUpdatingRect(false)
, m_bEmpty(true) , m_bEmpty(true)
, m_isArbitraryValueTooltip(false) , m_isArbitraryValueTooltip(false)
, m_bHovered(false)
{ {
initMode(); initMode();
setScene(new QGraphicsScene(this)); setScene(new QGraphicsScene(this));
@ -383,7 +384,8 @@ void BlocksGraphicsView::clear()
m_timelineStep = 1; m_timelineStep = 1;
m_offset = 0; // scroll back to the beginning of the scene m_offset = 0; // scroll back to the beginning of the scene
m_idleTimer.stop(); if (m_idleTimer.isActive())
m_idleTimer.stop();
m_idleTime = 0; m_idleTime = 0;
// Reset necessary flags // 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); 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 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) void BlocksGraphicsView::scaleTo(qreal _scale)
{ {
if (m_bEmpty) if (m_bEmpty)
@ -836,6 +814,28 @@ void BlocksGraphicsView::scaleTo(qreal _scale)
repaintScene(); 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) void BlocksGraphicsView::wheelEvent(QWheelEvent* _event)
{ {
if (needToIgnoreMouseEvent()) if (needToIgnoreMouseEvent())
@ -1508,6 +1508,8 @@ void BlocksGraphicsView::initMode()
connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout); connect(&m_flickerTimer, &QTimer::timeout, this, &This::onFlickerTimeout);
connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout); connect(&m_idleTimer, &QTimer::timeout, this, &This::onIdleTimeout);
m_idleTimer.setInterval(IDLE_TIMER_INTERVAL);
using profiler_gui::GlobalSignals; using profiler_gui::GlobalSignals;
auto globalSignals = &EASY_GLOBALS.events; auto globalSignals = &EASY_GLOBALS.events;
connect(globalSignals, &GlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange); connect(globalSignals, &GlobalSignals::hierarchyFlagChanged, this, &This::onHierarchyFlagChange);
@ -1693,15 +1695,11 @@ void BlocksGraphicsView::onIdleTimeout()
{ {
const auto& itemBlock = cse->tree; const auto& itemBlock = cse->tree;
auto widget = new QWidget(nullptr); auto widget = new QWidget(this, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput);
if (widget == nullptr) if (widget == nullptr)
return; return;
widget->setObjectName(QStringLiteral("DiagramPopup")); 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); auto lay = new QGridLayout(widget);
if (lay == nullptr) if (lay == nullptr)
@ -1803,19 +1801,15 @@ void BlocksGraphicsView::onIdleTimeout()
if (itemDesc.type() == profiler::BlockType::Value) if (itemDesc.type() == profiler::BlockType::Value)
{ {
m_isArbitraryValueTooltip = true; m_isArbitraryValueTooltip = true;
m_popupWidget = new ArbitraryValueToolTip(itemDesc.name(), itemBlock, nullptr); m_popupWidget = new ArbitraryValueToolTip(itemDesc.name(), itemBlock, this);
break; break;
} }
auto widget = new QWidget(nullptr); auto widget = new QWidget(this, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput);
if (widget == nullptr) if (widget == nullptr)
return; return;
widget->setObjectName(QStringLiteral("DiagramPopup")); 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); auto lay = new QGridLayout(widget);
if (lay == nullptr) if (lay == nullptr)
@ -2034,6 +2028,8 @@ void BlocksGraphicsView::onIdleTimeout()
const auto h = std::min(m_popupWidget->height(), (int)m_visibleSceneRect.height()); const auto h = std::min(m_popupWidget->height(), (int)m_visibleSceneRect.height());
m_popupWidget->setFixedSize(w, h); m_popupWidget->setFixedSize(w, h);
const auto prevPos = scenePos;
auto br = m_popupWidget->rect(); auto br = m_popupWidget->rect();
if (scenePos.y() + br.height() > m_visibleSceneRect.bottom()) if (scenePos.y() + br.height() > m_visibleSceneRect.bottom())
scenePos.setY(::std::max(scenePos.y() - br.height(), m_visibleSceneRect.top())); 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()) if (scenePos.x() + br.width() > m_visibleSceneRect.right())
scenePos.setX(::std::max(scenePos.x() - br.width(), m_visibleSceneRect.left())); 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) 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) if (widget == nullptr)
return; return;

View File

@ -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_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_bEmpty; ///< Indicates whether scene is empty and has no items
bool m_isArbitraryValueTooltip; bool m_isArbitraryValueTooltip;
bool m_bHovered;
public: public:
@ -162,7 +163,8 @@ public:
// Public virtual methods // 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 wheelEvent(QWheelEvent* _event) override;
void mousePressEvent(QMouseEvent* _event) override; void mousePressEvent(QMouseEvent* _event) override;
void mouseDoubleClickEvent(QMouseEvent* _event) override; void mouseDoubleClickEvent(QMouseEvent* _event) override;

View File

@ -390,7 +390,7 @@ void BlocksTreeWidget::onIdleTimeout()
if (item->hasToolTip(column)) if (item->hasToolTip(column))
return; 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->move(QCursor::pos());
m_valueTooltip->show(); m_valueTooltip->show();