diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp index f71542c3d..f805ef7c1 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.cpp @@ -45,6 +45,7 @@ void TerminalStripDrawer::paint(QPainter *painter) { if (m_strip && m_pattern) { + m_united_xref_text_rect = QRectF(); //To draw text, QPainter need a Qrect. Instead of create an instance //for each text, we re-use the same instance of QRect. QRect text_rect; @@ -91,11 +92,10 @@ void TerminalStripDrawer::paint(QPainter *painter) const auto text_{m_strip->installation() + " " + m_strip->location() + " " + m_strip->name()}; painter->drawText(text_rect, text_, m_pattern->headerTextOption()); - painter->restore(); + painter->restore(); //Move painter pos to next drawing painter->translate(m_pattern->m_header_rect.width(),0); - qreal x_offset{m_pattern->m_header_rect.width()}; //Draw spacer @@ -120,6 +120,8 @@ void TerminalStripDrawer::paint(QPainter *painter) QHash> bridges_anchor_points; + m_hovered_xref = hoverTerminal{}; + int physical_index = 0; //Loop over physical terminals for (const auto &physical_t : m_strip->physicalTerminal()) { @@ -190,15 +192,40 @@ void TerminalStripDrawer::paint(QPainter *painter) painter->restore(); //Draw xref - auto xref_string = shared_real_terminal->xref(); - painter->save(); xref_rect.setRect(0, xref_text_y, terminal_rect.width(), xref_text_height); + painter->save(); if (xref_text_orientation == Qt::Vertical) { painter->translate(xref_rect.bottomLeft()); painter->rotate(270); xref_rect.setRect(0, 0, xref_rect.height(), xref_rect.width()); } + + QTransform transform; + transform.translate(x_offset, 0); + + if (xref_text_orientation == Qt::Vertical) + { + transform.translate(0, xref_text_y + xref_text_height); + transform.rotate(270); + } + + auto xref_string = shared_real_terminal->xref(); + + const auto mapped_xref_text_rect = transform.mapRect(painter->boundingRect(xref_rect, xref_string, xref_text_option)); + if (m_united_xref_text_rect.isNull()) { + m_united_xref_text_rect = mapped_xref_text_rect; + } else { + m_united_xref_text_rect = m_united_xref_text_rect.united(mapped_xref_text_rect); + } + + //if mouse hover the xref text, draw it in blue to advise user the xref is clickable. + if (!m_mouse_hover_pos.isNull() && mapped_xref_text_rect.contains(m_mouse_hover_pos)) { + painter->setPen(Qt::blue); + m_hovered_xref.physical = physical_index; + m_hovered_xref.real = i; + } + painter->drawText(xref_rect, xref_string, xref_text_option); if (m_preview_draw) @@ -234,6 +261,7 @@ void TerminalStripDrawer::paint(QPainter *painter) painter->translate(terminal_rect.width(),0); x_offset += terminal_rect.width(); } + physical_index++; } painter->restore(); @@ -269,6 +297,41 @@ void TerminalStripDrawer::setPreviewDraw(bool draw) { m_preview_draw = draw; } +void TerminalStripDrawer::setMouseHoverPos(const QPointF &pos) +{ + m_last_mouse_pos_in_xrefs_rect = m_united_xref_text_rect.contains(m_mouse_hover_pos); + m_mouse_hover_pos = pos; +} + +/** + * @brief TerminalStripDrawer::mouseHoverXref + * @return True if the mouse position (given through the function setMouseHoverPos) + * hover the rect of a xref. + */ +bool TerminalStripDrawer::mouseHoverXref() const { + return m_united_xref_text_rect.contains(m_mouse_hover_pos); +} + +bool TerminalStripDrawer::needUpdate() +{ + if (mouseHoverXref()) { + return true; + } else if (m_last_mouse_pos_in_xrefs_rect) { + return true; + } + return false; +} + +/** + * @brief TerminalStripDrawer::hoveredXref + * @return the current terminal hovered by the mouse + * in the xref bounding rectangle + */ +hoverTerminal TerminalStripDrawer::hoveredXref() const +{ + return m_hovered_xref; +} + qreal TerminalStripDrawer::height() const { if (m_pattern) diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h index 8fa5fd8e1..363bc2cdf 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripdrawer.h @@ -27,6 +27,17 @@ class TerminalStrip; namespace TerminalStripDrawer { + /** + * @brief The hoverTerminal struct + * Just a little struct use to know what is the physical and real terminal + * when the mouse hover the Xref string of a terminal. + * If mouse don't hover a Xref the value is set to -1; + */ + struct hoverTerminal{ + int physical{-1}; + int real{-1}; + }; + class AbstractBridgeInterface { public: @@ -80,6 +91,11 @@ namespace TerminalStripDrawer void setPreviewDraw(bool draw = true); + void setMouseHoverPos(const QPointF &pos); + bool mouseHoverXref() const; + bool needUpdate(); + hoverTerminal hoveredXref() const; + private: qreal height() const; qreal width() const; @@ -88,6 +104,10 @@ namespace TerminalStripDrawer QSharedPointer m_strip; QSharedPointer m_pattern; bool m_preview_draw { false }; + QPointF m_mouse_hover_pos; + QRectF m_united_xref_text_rect; + bool m_last_mouse_pos_in_xrefs_rect{false}; + hoverTerminal m_hovered_xref; }; } diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp index 77f28adee..ad9634b4d 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.cpp @@ -22,6 +22,8 @@ #include "../../project/projectpropertieshandler.h" #include "../../qetgraphicsitem/qgraphicsitemutility.h" #include "../terminalstrip.h" +#include "../physicalterminal.h" +#include "../realterminal.h" #include "../ui/terminalstripeditorwindow.h" #include "trueterminalstrip.h" @@ -94,13 +96,53 @@ QString TerminalStripItem::name() const { return tr("plan de bornes"); } +void TerminalStripItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + QetGraphicsItem::hoverMoveEvent(event); + m_drawer.setMouseHoverPos(hoverMousePos()); + if (m_drawer.needUpdate()) { + update(); + } +} + +void TerminalStripItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + QetGraphicsItem::hoverLeaveEvent(event); + m_drawer.setMouseHoverPos(QPointF{}); +} + void TerminalStripItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { Q_UNUSED (event); - if (m_strip) { - TerminalStripEditorWindow::edit(m_strip); - } + const auto hovered = m_drawer.hoveredXref(); + + if (m_strip) { + if (hovered.physical >= 0 && + hovered.real >= 0) + { + if (const auto physical_terminal = m_strip->physicalTerminal(hovered.physical); + !physical_terminal.isNull()) + { + if (const auto real_terminal = physical_terminal->realTerminal(hovered.real); + !real_terminal.isNull() && + real_terminal->isElement()) + { + if (QPointer element = real_terminal->element(); + !element.isNull()) + { + //Unselect and ungrab mouse to prevent unwanted + //move when element is in the same scene of this. + setSelected(false); + ungrabMouse(); + QetGraphicsItem::showItem(element); + } + } + } + } else { + TerminalStripEditorWindow::edit(m_strip); + } + } } void TerminalStripItem::refreshPending() diff --git a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h index b26a6dd8b..f69e8595b 100644 --- a/sources/TerminalStrip/GraphicsItem/terminalstripitem.h +++ b/sources/TerminalStrip/GraphicsItem/terminalstripitem.h @@ -46,6 +46,8 @@ class TerminalStripItem : public QetGraphicsItem QRectF boundingRect() const override; QString name() const override; + void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override; + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; void refreshPending(); void setLayout(QSharedPointer layout); @@ -57,7 +59,6 @@ class TerminalStripItem : public QetGraphicsItem QPointer m_strip; TerminalStripDrawer::TerminalStripDrawer m_drawer; QUuid m_pending_strip_uuid; - }; #endif // TERMINALSTRIPITEM_H diff --git a/sources/TerminalStrip/physicalterminal.cpp b/sources/TerminalStrip/physicalterminal.cpp index 99165a20f..86eefb945 100644 --- a/sources/TerminalStrip/physicalterminal.cpp +++ b/sources/TerminalStrip/physicalterminal.cpp @@ -189,6 +189,20 @@ QVector> PhysicalTerminal::realTerminals() const { return m_real_terminal; } +/** + * @brief PhysicalTerminal::realTerminal + * @param pos + * @return the real terminal at position pos. + * Note that the returned QSharedPointer can be null + */ +QSharedPointer PhysicalTerminal::realTerminal(int pos) const +{ + if (pos < m_real_terminal.size()) { + return m_real_terminal.at(pos); + } + else return QSharedPointer{}; +} + /** * @brief uuid * @return the uuid of this physical terminal diff --git a/sources/TerminalStrip/physicalterminal.h b/sources/TerminalStrip/physicalterminal.h index 7d90ff681..4cb78e059 100644 --- a/sources/TerminalStrip/physicalterminal.h +++ b/sources/TerminalStrip/physicalterminal.h @@ -86,6 +86,7 @@ class PhysicalTerminal int levelCount() const; int levelOf(const QSharedPointer &terminal) const; QVector> realTerminals() const; + QSharedPointer realTerminal(int pos) const; QUuid uuid() const; int pos() const; int realTerminalCount() const; diff --git a/sources/qetgraphicsitem/qetgraphicsitem.cpp b/sources/qetgraphicsitem/qetgraphicsitem.cpp index fc1acc385..873a79fba 100644 --- a/sources/qetgraphicsitem/qetgraphicsitem.cpp +++ b/sources/qetgraphicsitem/qetgraphicsitem.cpp @@ -24,12 +24,31 @@ Default constructor @param parent : Parent Item */ +void QetGraphicsItem::showItem(QetGraphicsItem *item) +{ + if (item && item->diagram()) + { + item->diagram()->showMe(); + item->setSelected(true); + + //Zoom to the item + for(QGraphicsView *view : item->scene()->views()) + { + QRectF fit = item->sceneBoundingRect(); + fit.adjust(-200, -200, 200, 200); + view->fitInView(fit, Qt::KeepAspectRatioByExpanding); + } + } +} + QetGraphicsItem::QetGraphicsItem(QGraphicsItem *parent): QGraphicsObject(parent), is_movable_(true), m_first_move(true), snap_to_grid_(true) -{} +{ + setAcceptHoverEvents(true); +} QetGraphicsItem::~QetGraphicsItem() {} @@ -68,6 +87,11 @@ bool QetGraphicsItem::isHovered() const { return m_hovered; } +QPointF QetGraphicsItem::hoverMousePos() const +{ + return m_mouse_hover_pos; +} + /** @brief QetGraphicsItem::state @return the current state of this item @@ -166,6 +190,12 @@ void QetGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) QGraphicsObject::hoverEnterEvent(event); } +void QetGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) +{ + QGraphicsObject::hoverMoveEvent(event); + m_mouse_hover_pos = event->pos(); +} + void QetGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { m_hovered = false; diff --git a/sources/qetgraphicsitem/qetgraphicsitem.h b/sources/qetgraphicsitem/qetgraphicsitem.h index e6459403b..11a967a35 100644 --- a/sources/qetgraphicsitem/qetgraphicsitem.h +++ b/sources/qetgraphicsitem/qetgraphicsitem.h @@ -28,6 +28,9 @@ class QetGraphicsItem : public QGraphicsObject { Q_OBJECT + public : + static void showItem (QetGraphicsItem *item); + public: //constructor destructor QetGraphicsItem(QGraphicsItem *parent = nullptr); @@ -43,6 +46,7 @@ class QetGraphicsItem : public QGraphicsObject virtual void setMovable (bool movable) { is_movable_ = movable;} bool isHovered() const; + QPointF hoverMousePos() const; virtual void editProperty () {} virtual QString name ()const @@ -57,6 +61,7 @@ class QetGraphicsItem : public QGraphicsObject void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override; + void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override; void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override; protected: @@ -68,6 +73,7 @@ class QetGraphicsItem : public QGraphicsObject private: bool m_hovered{false}; + QPointF m_mouse_hover_pos; };