From 903657b0b8d51b2ceadf7ff09dceddb6df0f4fa7 Mon Sep 17 00:00:00 2001 From: ed Date: Mon, 8 Nov 2021 12:32:08 +0000 Subject: [PATCH] Tooltip: Prevent tip from being immediately dismissed when shown from TooltipWindow::displayTip() --- .../windows/juce_TooltipWindow.cpp | 44 ++++++++++++++----- .../windows/juce_TooltipWindow.h | 5 ++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp index cef1bca8f9..8b090b1e8a 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp @@ -75,6 +75,11 @@ void TooltipWindow::displayTip (Point screenPos, const String& tip) { jassert (tip.isNotEmpty()); + displayTipInternal (screenPos, tip, ShownManually::yes); +} + +void TooltipWindow::displayTipInternal (Point screenPos, const String& tip, ShownManually shownManually) +{ if (! reentrant) { ScopedValueSetter setter (reentrant, true, false); @@ -120,6 +125,7 @@ void TooltipWindow::displayTip (Point screenPos, const String& tip) #endif toFront (false); + manuallyShownTip = shownManually == ShownManually::yes ? tip : String(); } } @@ -140,7 +146,9 @@ void TooltipWindow::hideTip() { if (! reentrant) { - tipShowing.clear(); + tipShowing = {}; + manuallyShownTip = {}; + removeFromDesktop(); setVisible (false); @@ -173,19 +181,29 @@ void TooltipWindow::timerCallback() if (newComp == nullptr || getParentComponent() == nullptr || newComp->getPeer() == getPeer()) { - auto newTip = newComp != nullptr ? getTipFor (*newComp) : String(); - bool tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse); + const auto componentChanged = (newComp != lastComponentUnderMouse); + + const auto newTip = [this, &newComp, componentChanged] + { + if (dynamic_cast (newComp) != nullptr) + return getTipFor (*newComp); + + return componentChanged ? String() : manuallyShownTip; + }(); + + const auto tipChanged = (newTip != lastTipUnderMouse || componentChanged); + lastComponentUnderMouse = newComp; lastTipUnderMouse = newTip; - auto clickCount = desktop.getMouseButtonClickCounter(); - auto wheelCount = desktop.getMouseWheelMoveCounter(); - bool mouseWasClicked = (clickCount > mouseClicks || wheelCount > mouseWheelMoves); + const auto clickCount = desktop.getMouseButtonClickCounter(); + const auto wheelCount = desktop.getMouseWheelMoveCounter(); + const auto mouseWasClicked = (clickCount > mouseClicks || wheelCount > mouseWheelMoves); mouseClicks = clickCount; mouseWheelMoves = wheelCount; - auto mousePos = mouseSource.getScreenPosition(); - bool mouseMovedQuickly = mousePos.getDistanceFrom (lastMousePos) > 12; + const auto mousePos = mouseSource.getScreenPosition(); + const auto mouseMovedQuickly = (mousePos.getDistanceFrom (lastMousePos) > 12); lastMousePos = mousePos; if (tipChanged || mouseWasClicked || mouseMovedQuickly) @@ -193,10 +211,14 @@ void TooltipWindow::timerCallback() auto showTip = [this, &mouseSource, &mousePos, &newTip] { - bool mouseHasMovedSinceClick = mouseSource.getLastMouseDownPosition() != lastMousePos; + if (mouseSource.getLastMouseDownPosition() == lastMousePos) + return; - if (mouseHasMovedSinceClick) - displayTip (mousePos.roundToInt(), newTip); + const auto isShowingManualTip = (manuallyShownTip.isNotEmpty() && manuallyShownTip == newTip); + + displayTipInternal (mousePos.roundToInt(), + newTip, + isShowingManualTip ? ShownManually::yes : ShownManually::no); }; if (isVisible() || now < lastHideTime + 500) diff --git a/modules/juce_gui_basics/windows/juce_TooltipWindow.h b/modules/juce_gui_basics/windows/juce_TooltipWindow.h index 36c1cb3c91..a5d30efe75 100644 --- a/modules/juce_gui_basics/windows/juce_TooltipWindow.h +++ b/modules/juce_gui_basics/windows/juce_TooltipWindow.h @@ -131,12 +131,15 @@ private: //============================================================================== Point lastMousePos; Component* lastComponentUnderMouse = nullptr; - String tipShowing, lastTipUnderMouse; + String tipShowing, lastTipUnderMouse, manuallyShownTip; int millisecondsBeforeTipAppears; int mouseClicks = 0, mouseWheelMoves = 0; unsigned int lastCompChangeTime = 0, lastHideTime = 0; bool reentrant = false; + enum ShownManually { yes, no }; + void displayTipInternal (Point, const String&, ShownManually); + std::unique_ptr createAccessibilityHandler() override; void paint (Graphics&) override; void mouseEnter (const MouseEvent&) override;