diff --git a/src/declarativeimports/core/tooltip.h b/src/declarativeimports/core/tooltip.h --- a/src/declarativeimports/core/tooltip.h +++ b/src/declarativeimports/core/tooltip.h @@ -101,6 +101,11 @@ * Returns whether the mouse is inside the item */ Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged) + + /** + * Returns whether the mouse is inside the tool tip window + */ + Q_PROPERTY(bool toolTipWindowContainsMouse READ toolTipWindowContainsMouse NOTIFY toolTipWindowContainsMouseChanged) /** * Plasma Location of the dialog window. Useful if this dialog is a popup for a panel @@ -120,6 +125,12 @@ Q_PROPERTY(bool active MEMBER m_active WRITE setActive NOTIFY activeChanged) /** + * Property that controls if a tooltips will show automatically or if they are shown/hidden manually. + * The default is true. + */ + Q_PROPERTY(bool autoShowHide MEMBER m_autoShowHide WRITE setAutoShowHide NOTIFY autoShowHideChanged) + + /** * if interactive is false (default), the tooltip will automatically hide * itself as soon as the mouse leaves the tooltiparea, if is true, if the mouse leaves tooltiparea and goes over the tooltip itself, the tooltip won't hide, so it will be possible to interact with tooltip contents */ @@ -133,7 +144,7 @@ QQuickItem *mainItem() const; void setMainItem(QQuickItem *mainItem); - void showToolTip(); + Q_INVOKABLE void showToolTip(); QString mainText() const; void setMainText(const QString &mainText); @@ -155,8 +166,12 @@ bool containsMouse() const; void setContainsMouse(bool contains); + + bool toolTipWindowContainsMouse() const; void setActive(bool active); + + void setAutoShowHide(bool autoShowHide); void setInteractive(bool interactive); /// @endcond @@ -184,19 +199,23 @@ void iconChanged(); void imageChanged(); void containsMouseChanged(); + void toolTipWindowContainsMouseChanged(); void locationChanged(); void activeChanged(); + void autoShowHideChanged(); void interactiveChanged(); private Q_SLOTS: void settingsChanged(); + void toolTipWindowContainsMouseChangedSlot(); private: bool isValid() const; void loadSettings(); bool m_tooltipsEnabledGlobally; bool m_containsMouse; + bool m_toolTipWindowContainsMouse; Plasma::Types::Location m_location; QWeakPointer m_mainItem; QTimer *m_showTimer; @@ -206,6 +225,7 @@ QVariant m_image; QVariant m_icon; bool m_active; + bool m_autoShowHide; bool m_interactive; int m_interval; diff --git a/src/declarativeimports/core/tooltip.cpp b/src/declarativeimports/core/tooltip.cpp --- a/src/declarativeimports/core/tooltip.cpp +++ b/src/declarativeimports/core/tooltip.cpp @@ -40,6 +40,7 @@ m_location(Plasma::Types::Floating), m_textFormat(Qt::AutoText), m_active(true), + m_autoShowHide(true), m_interactive(false), m_usingDialog(false) { @@ -157,6 +158,8 @@ dlg->setVisualParent(this); dlg->setMainItem(mainItem()); dlg->setInteractive(m_interactive); + dlg->SetAutoShowHide(m_autoShowHide); + connect(dlg, &ToolTipDialog:.containtsMouseChanged, this, &ToolTip::toolTipWindowContainsMouseChangedSlot); dlg->setVisible(true); } @@ -240,6 +243,16 @@ emit activeChanged(); } +void ToolTip::setAutoShowHide(bool autoShowHide) +{ + if (m_autoShowHide == autoShowHide) { + return; + } + + m_autoShowHide = autoShowHide; + emit autoShowHideChanged(); +} + void ToolTip::setInteractive(bool interactive) { if (m_interactive == interactive) { @@ -306,11 +319,21 @@ m_containsMouse = contains; emit containsMouseChanged(); } - if (!contains) { - tooltipDialogInstance()->dismiss(); + if (!contains && m_autoShowHide) { + tooltipDialogInstance()->dismiss(this); } } +bool ToolTip::toolTipWindowContainsMouse() const +{ + return m_toolTipWindowContainsMouse; +} + +void ToolTip::toolTipWindowContainsMouseChangedSlot() { + m_toolTipWindowContainsMouse = tooltipDialogInstance()->containsMouse(); + emit toolTipWindowContainsMouseChanged(); +} + void ToolTip::hoverEnterEvent(QHoverEvent *event) { Q_UNUSED(event) @@ -324,19 +347,21 @@ return; } - if (tooltipDialogInstance()->isVisible()) { - // We signal the tooltipmanager that we're "potentially interested, - // and ask to keep it open for a bit, so other items get the chance - // to update the content before the tooltip hides -- this avoids - // flickering - // It need to be considered only when other items can deal with tooltip area - if (m_active) { - tooltipDialogInstance()->keepalive(); - //FIXME: showToolTip needs to be renamed in sync or something like that - showToolTip(); + if(m_autoShowHide) { + if (tooltipDialogInstance()->isVisible()) { + // We signal the tooltipmanager that we're "potentially interested, + // and ask to keep it open for a bit, so other items get the chance + // to update the content before the tooltip hides -- this avoids + // flickering + // It need to be considered only when other items can deal with tooltip area + if (m_active) { + tooltipDialogInstance()->keepalive(); + //FIXME: showToolTip needs to be renamed in sync or something like that + showToolTip(); + } + } else { + m_showTimer->start(m_interval); } - } else { - m_showTimer->start(m_interval); } } diff --git a/src/declarativeimports/core/tooltipdialog.h b/src/declarativeimports/core/tooltipdialog.h --- a/src/declarativeimports/core/tooltipdialog.h +++ b/src/declarativeimports/core/tooltipdialog.h @@ -51,18 +51,27 @@ Plasma::Types::Direction direction() const; void setDirection(Plasma::Types::Direction loc); - void dismiss(); + void dismiss(QObject *owner); void keepalive(); bool interactive(); void setInteractive(bool interactive); + bool autoShowHide(); + void setAutoShowHide(bool autoShowHide); + + bool containsMouse(); + void setContainsMouse(bool contains); + /** * Basically the last one who has shown the dialog */ QObject *owner() const; void setOwner(QObject *owner); +Q_SIGNALS: + void containsMouseChanged(); + protected: void showEvent(QShowEvent *event) Q_DECL_OVERRIDE; void hideEvent(QHideEvent *event) Q_DECL_OVERRIDE; @@ -77,6 +86,8 @@ QTimer *m_showTimer; int m_hideTimeout; bool m_interactive; + bool m_autoShowHide; + bool m_containsMouse; QObject *m_owner; }; diff --git a/src/declarativeimports/core/tooltipdialog.cpp b/src/declarativeimports/core/tooltipdialog.cpp --- a/src/declarativeimports/core/tooltipdialog.cpp +++ b/src/declarativeimports/core/tooltipdialog.cpp @@ -69,7 +69,11 @@ void ToolTipDialog::showEvent(QShowEvent *event) { - m_showTimer->start(m_hideTimeout); + if (m_autoShowHide) { + m_showTimer->start(m_hideTimeout); + } else { + m_showTimer->stop(); + } Dialog::showEvent(event); } @@ -89,11 +93,15 @@ bool ToolTipDialog::event(QEvent *e) { if (e->type() == QEvent::Enter) { + setContainsMouse(true); if (m_interactive) { m_showTimer->stop(); } } else if (e->type() == QEvent::Leave) { - dismiss(); + setContainsMouse(false); + if (m_autoShowHide) { + dismiss(m_owner); + } } bool ret = Dialog::event(e); @@ -112,17 +120,26 @@ void ToolTipDialog::setOwner(QObject *owner) { - m_owner = owner; + if(m_owner != owner) { + m_owner = owner; + m_showTimer->stop(); // if the owner changes then don't hide the dialog + } } -void ToolTipDialog::dismiss() +void ToolTipDialog::dismiss(QObject *owner) { - m_showTimer->start(m_hideTimeout / 20); // pretty short: 200ms + if(m_owner == owner) { // only dismiss if the dialog is owned by the requester + m_showTimer->start(m_hideTimeout / 20); // pretty short: 200ms + } } void ToolTipDialog::keepalive() { - m_showTimer->start(m_hideTimeout); + if(m_autoShowHide) { + m_showTimer->start(m_hideTimeout); + } else { + m_showTimer->stop(); + } } bool ToolTipDialog::interactive() @@ -141,4 +158,27 @@ setPosition(value.toPoint()); } +bool ToolTipDialog::autoShowHide() +{ + return m_autoShowHide; +} + +void ToolTipDialog::setAutoShowHide(bool autoShowHide) +{ + m_autoShowHide = autoShowHide; +} + +bool ToolTipDialog::containsMouse() +{ + return m_containsMouse; +} + +void ToolTipDialog::setContainsMouse(bool contains) +{ + if (m_containsMouse != contains) { + m_containsMouse = contains; + emit containsMouseChanged(); + } +} + #include "moc_tooltipdialog.cpp"