From b4bc2c8710cd1b0ca0e992040c16f89c7e137e70 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 18 Nov 2021 15:43:22 +0000 Subject: [PATCH] Tooltip: Show manually shown tips until a dismissal mouse event occurs --- .../windows/juce_TooltipWindow.cpp | 52 +++++++------------ .../windows/juce_TooltipWindow.h | 8 ++- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp index 594967240e..513638f819 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp @@ -164,7 +164,7 @@ String TooltipWindow::getTipFor (Component& c) void TooltipWindow::hideTip() { - if (! reentrant) + if (isVisible() && ! reentrant) { tipShowing = {}; manuallyShownTip = {}; @@ -173,6 +173,8 @@ void TooltipWindow::hideTip() removeFromDesktop(); setVisible (false); + lastHideTime = Time::getApproximateMillisecondCounter(); + #if JUCE_DEBUG activeTooltipWindows.removeAllInstancesOf (this); #endif @@ -194,25 +196,20 @@ std::unique_ptr TooltipWindow::createAccessibilityHandler( void TooltipWindow::timerCallback() { - auto& desktop = Desktop::getInstance(); - auto mouseSource = desktop.getMainMouseSource(); - auto now = Time::getApproximateMillisecondCounter(); - + const auto mouseSource = Desktop::getInstance().getMainMouseSource(); auto* newComp = mouseSource.isTouch() ? nullptr : mouseSource.getComponentUnderMouse(); - if (newComp == nullptr || getParentComponent() == nullptr || newComp->getPeer() == getPeer()) + if (manuallyShownTip.isNotEmpty()) { - const auto componentChanged = (newComp != lastComponentUnderMouse); + if (dismissalMouseEventOccured || newComp == nullptr) + hideTip(); - const auto newTip = [this, &newComp, componentChanged] - { - if (dynamic_cast (newComp) != nullptr) - return getTipFor (*newComp); - - return componentChanged ? String() : manuallyShownTip; - }(); + return; + } - const auto tipChanged = (newTip != lastTipUnderMouse || componentChanged); + if (newComp == nullptr || getParentComponent() == nullptr || newComp->getPeer() == getPeer()) + { + const auto newTip = newComp != nullptr ? getTipFor (*newComp) : String(); lastComponentUnderMouse = newComp; lastTipUnderMouse = newTip; @@ -221,19 +218,16 @@ void TooltipWindow::timerCallback() const auto mouseMovedQuickly = (mousePos.getDistanceFrom (lastMousePos) > 12); lastMousePos = mousePos; + const auto tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse); + const auto now = Time::getApproximateMillisecondCounter(); + if (tipChanged || dismissalMouseEventOccured || mouseMovedQuickly) lastCompChangeTime = now; - auto showTip = [this, &mouseSource, &mousePos, &newTip] + const auto showTip = [this, &mouseSource, &mousePos, &newTip] { - if (mouseSource.getLastMouseDownPosition() == lastMousePos) - return; - - const auto isShowingManualTip = (manuallyShownTip.isNotEmpty() && manuallyShownTip == newTip); - - displayTipInternal (mousePos.roundToInt(), - newTip, - isShowingManualTip ? ShownManually::yes : ShownManually::no); + if (mouseSource.getLastMouseDownPosition() != lastMousePos) + displayTipInternal (mousePos.roundToInt(), newTip, ShownManually::no); }; if (isVisible() || now < lastHideTime + 500) @@ -241,17 +235,9 @@ void TooltipWindow::timerCallback() // if a tip is currently visible (or has just disappeared), update to a new one // immediately if needed.. if (newComp == nullptr || dismissalMouseEventOccured || newTip.isEmpty()) - { - if (isVisible()) - { - lastHideTime = now; - hideTip(); - } - } + hideTip(); else if (tipChanged) - { showTip(); - } } else { diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.h b/modules/juce_gui_basics/windows/juce_TooltipWindow.h index fe430cc5ec..158f0df15e 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.h +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.h @@ -84,7 +84,13 @@ public: */ void setMillisecondsBeforeTipAppears (int newTimeMs = 700) noexcept; - /** Can be called to manually force a tip to be shown at a particular location. */ + /** Can be called to manually force a tip to be shown at a particular location. + + The tip will be shown until hideTip() is called, or a dismissal mouse event + occurs. + + @see hideTip + */ void displayTip (Point screenPosition, const String& text); /** Can be called to manually hide the tip if it's showing. */