diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index 4e2cb71..3f2bb28 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -852,13 +852,34 @@ void EasyGraphicsView::mousePressEvent(QMouseEvent* _event) m_mouseButtons = _event->buttons(); m_mousePressPos = _event->pos(); + if (m_mouseButtons & Qt::LeftButton) + { + if (m_chronometerItemAux->isVisible() && (m_chronometerItemAux->hoverLeft() || m_chronometerItemAux->hoverRight())) + { + m_chronometerItemAux->setReverse(m_chronometerItemAux->hoverLeft()); + m_bDoubleClick = true; + } + else if (m_chronometerItem->isVisible() && (m_chronometerItem->hoverLeft() || m_chronometerItem->hoverRight())) + { + m_chronometerItem->setReverse(m_chronometerItem->hoverLeft()); + m_mouseButtons = Qt::RightButton; + return; + } + } + if (m_mouseButtons & Qt::RightButton) { - const auto mouseX = m_offset + mapToScene(m_mousePressPos).x() / m_scale; - m_chronometerItem->setLeftRight(mouseX, mouseX); - m_chronometerItem->setReverse(false); - m_chronometerItem->hide(); - m_pScrollbar->hideChrono(); + if (m_chronometerItem->isVisible() && (m_chronometerItem->hoverLeft() || m_chronometerItem->hoverRight())) + { + m_chronometerItem->setReverse(m_chronometerItem->hoverLeft()); + } + else + { + const auto mouseX = m_offset + mapToScene(m_mousePressPos).x() / m_scale; + m_chronometerItem->setLeftRight(mouseX, mouseX); + m_chronometerItem->hide(); + m_pScrollbar->hideChrono(); + } } _event->accept(); @@ -882,7 +903,6 @@ void EasyGraphicsView::mouseDoubleClickEvent(QMouseEvent* _event) { const auto mouseX = m_offset + mapToScene(m_mousePressPos).x() / m_scale; m_chronometerItemAux->setLeftRight(mouseX, mouseX); - m_chronometerItemAux->setReverse(false); m_chronometerItemAux->hide(); emit sceneUpdated(); } @@ -909,7 +929,6 @@ void EasyGraphicsView::mouseReleaseEvent(QMouseEvent* _event) if (m_chronometerItem->isVisible() && m_chronometerItem->width() < 1e-6) { m_chronometerItem->hide(); - m_chronometerItem->setHover(false); m_pScrollbar->hideChrono(); } @@ -1054,6 +1073,12 @@ bool EasyGraphicsView::moveChrono(EasyChronometerItem* _chronometerItem, qreal _ { _chronometerItem->setReverse(false); _chronometerItem->setLeftRight(_chronometerItem->right(), _mouseX); + + if (_chronometerItem->hoverLeft()) + { + _chronometerItem->setHoverLeft(false); + _chronometerItem->setHoverRight(true); + } } else { @@ -1066,6 +1091,12 @@ bool EasyGraphicsView::moveChrono(EasyChronometerItem* _chronometerItem, qreal _ { _chronometerItem->setReverse(true); _chronometerItem->setLeftRight(_mouseX, _chronometerItem->left()); + + if (_chronometerItem->hoverRight()) + { + _chronometerItem->setHoverLeft(true); + _chronometerItem->setHoverRight(false); + } } else { @@ -1086,7 +1117,7 @@ void EasyGraphicsView::mouseMoveEvent(QMouseEvent* _event) { m_idleTime = 0; - if (m_bEmpty || (m_mouseButtons == 0 && !m_chronometerItem->isVisible())) + if (m_bEmpty || (m_mouseButtons == 0 && !m_chronometerItem->isVisible() && !m_chronometerItemAux->isVisible())) { _event->accept(); return; @@ -1152,11 +1183,41 @@ void EasyGraphicsView::mouseMoveEvent(QMouseEvent* _event) needUpdate = true; } - if (m_chronometerItem->isVisible()) + if (m_mouseButtons == 0) { - auto prevValue = m_chronometerItem->hoverIndicator(); - m_chronometerItem->setHover(m_chronometerItem->contains(mouseScenePos)); - needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverIndicator()); + if (m_chronometerItem->isVisible()) + { + auto prevValue = m_chronometerItem->hoverIndicator(); + m_chronometerItem->setHoverIndicator(m_chronometerItem->indicatorContains(mouseScenePos)); + needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverIndicator()); + + prevValue = m_chronometerItem->hoverLeft(); + m_chronometerItem->setHoverLeft(m_chronometerItem->hoverLeft(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverLeft()); + + if (!m_chronometerItem->hoverLeft()) + { + prevValue = m_chronometerItem->hoverRight(); + m_chronometerItem->setHoverRight(m_chronometerItem->hoverRight(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItem->hoverRight()); + } + } + + if (m_chronometerItemAux->isVisible()) + { + auto x = m_chronometerItemAux->toItem(mouseScenePos.x()); + + auto prevValue = m_chronometerItemAux->hoverLeft(); + m_chronometerItemAux->setHoverLeft(m_chronometerItemAux->hoverLeft(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItemAux->hoverLeft()); + + if (!m_chronometerItemAux->hoverLeft()) + { + prevValue = m_chronometerItemAux->hoverRight(); + m_chronometerItemAux->setHoverRight(m_chronometerItemAux->hoverRight(mouseScenePos.x())); + needUpdate = needUpdate || (prevValue != m_chronometerItemAux->hoverRight()); + } + } } if (needUpdate) diff --git a/profiler_gui/easy_chronometer_item.cpp b/profiler_gui/easy_chronometer_item.cpp index 014d149..1300356 100644 --- a/profiler_gui/easy_chronometer_item.cpp +++ b/profiler_gui/easy_chronometer_item.cpp @@ -74,13 +74,15 @@ const auto CHRONOMETER_FONT = ::profiler_gui::EFont("Helvetica", 16, QFont::Bold ////////////////////////////////////////////////////////////////////////// EasyChronometerItem::EasyChronometerItem(bool _main) - : QGraphicsItem() + : Parent() , m_color(::profiler_gui::CHRONOMETER_COLOR) , m_left(0) , m_right(0) , m_bMain(_main) , m_bReverse(false) , m_bHoverIndicator(false) + , m_bHoverLeftBorder(false) + , m_bHoverRightBorder(false) { m_indicator.reserve(3); } @@ -191,10 +193,47 @@ void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt } if (m_left > sceneLeft) + { + if (m_bHoverLeftBorder) + { + // Set bold if border is hovered + QPen p = _painter->pen(); + p.setWidth(3); + _painter->setPen(p); + } + _painter->drawLine(QPointF(rect.left(), rect.top()), QPointF(rect.left(), rect.bottom())); + } + if (m_right < sceneRight) + { + if (m_bHoverLeftBorder) + { + // Restore width + QPen p = _painter->pen(); + p.setWidth(1); + _painter->setPen(p); + } + else if (m_bHoverRightBorder) + { + // Set bold if border is hovered + QPen p = _painter->pen(); + p.setWidth(3); + _painter->setPen(p); + } + _painter->drawLine(QPointF(rect.right(), rect.top()), QPointF(rect.right(), rect.bottom())); + // This is not necessary because another setPen() invoked for draw text + //if (m_bHoverRightBorder) + //{ + // // Restore width + // QPen p = _painter->pen(); + // p.setWidth(1); + // _painter->setPen(p); + //} + } + // draw text _painter->setCompositionMode(QPainter::CompositionMode_Difference); // This lets the text to be visible on every background _painter->setRenderHint(QPainter::TextAntialiasing); @@ -252,13 +291,56 @@ void EasyChronometerItem::paint(QPainter* _painter, const QStyleOptionGraphicsIt // END Paint!~~~~~~~~~~~~~~~~~~~~~~ } -bool EasyChronometerItem::contains(const QPointF& _pos) const +void EasyChronometerItem::hide() +{ + m_bHoverIndicator = false; + m_bHoverLeftBorder = false; + m_bHoverRightBorder = false; + m_bReverse = false; + Parent::hide(); +} + +bool EasyChronometerItem::indicatorContains(const QPointF& _pos) const +{ + if (m_indicator.empty()) + return false; + + const auto itemX = toItem(_pos.x()); + return m_indicator.containsPoint(QPointF(itemX, _pos.y()), Qt::OddEvenFill); +} + +void EasyChronometerItem::setHoverLeft(bool _hover) +{ + m_bHoverLeftBorder = _hover; +} + +void EasyChronometerItem::setHoverRight(bool _hover) +{ + m_bHoverRightBorder = _hover; +} + +bool EasyChronometerItem::hoverLeft(qreal _x) const +{ + const auto dx = fabs(_x - m_left) * view()->scale(); + return dx < 4; +} + +bool EasyChronometerItem::hoverRight(qreal _x) const +{ + const auto dx = fabs(_x - m_right) * view()->scale(); + return dx < 4; +} + +QPointF EasyChronometerItem::toItem(const QPointF& _pos) const { const auto sceneView = view(); - const auto clickX = (_pos.x() - sceneView->offset()) * sceneView->scale() - x(); - if (!m_indicator.empty() && m_indicator.containsPoint(QPointF(clickX, _pos.y()), Qt::OddEvenFill)) - return true; - return false; + return QPointF((_pos.x() - sceneView->offset()) * sceneView->scale() - x(), _pos.y()); +} + +qreal EasyChronometerItem::toItem(qreal _x) const +{ + const auto sceneView = view(); + return (_x - sceneView->offset()) * sceneView->scale() - x(); } void EasyChronometerItem::setColor(const QColor& _color) @@ -295,7 +377,7 @@ void EasyChronometerItem::setReverse(bool _reverse) m_bReverse = _reverse; } -void EasyChronometerItem::setHover(bool _hover) +void EasyChronometerItem::setHoverIndicator(bool _hover) { m_bHoverIndicator = _hover; } diff --git a/profiler_gui/easy_chronometer_item.h b/profiler_gui/easy_chronometer_item.h index c3ac7c6..1c20865 100644 --- a/profiler_gui/easy_chronometer_item.h +++ b/profiler_gui/easy_chronometer_item.h @@ -71,6 +71,9 @@ class EasyGraphicsView; class EasyChronometerItem : public QGraphicsItem { + typedef QGraphicsItem Parent; + typedef EasyChronometerItem This; + QPolygonF m_indicator; ///< Indicator displayed when this chrono item is out of screen (displaying only for main item) QRectF m_boundingRect; ///< boundingRect (see QGraphicsItem) QColor m_color; ///< Color of the item @@ -78,6 +81,8 @@ class EasyChronometerItem : public QGraphicsItem bool m_bMain; ///< Is this chronometer main (true, by default) bool m_bReverse; ///< bool m_bHoverIndicator; ///< Mouse hover above indicator + bool m_bHoverLeftBorder; + bool m_bHoverRightBorder; public: @@ -93,6 +98,8 @@ public: // Public non-virtual methods + void hide(); + void setColor(const QColor& _color); void setBoundingRect(qreal x, qreal y, qreal w, qreal h); @@ -102,15 +109,34 @@ public: void setReverse(bool _reverse); - void setHover(bool _hover); + void setHoverIndicator(bool _hover); - bool contains(const QPointF& _pos) const override; + bool indicatorContains(const QPointF& _pos) const; + + void setHoverLeft(bool _hover); + void setHoverRight(bool _hover); + + bool hoverLeft(qreal _x) const; + bool hoverRight(qreal _x) const; + + QPointF toItem(const QPointF& _pos) const; + qreal toItem(qreal _x) const; inline bool hoverIndicator() const { return m_bHoverIndicator; } + inline bool hoverLeft() const + { + return m_bHoverLeftBorder; + } + + inline bool hoverRight() const + { + return m_bHoverRightBorder; + } + inline bool reverse() const { return m_bReverse;