JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_TooltipWindow.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30 : Component ("tooltip"),
31 millisecondsBeforeTipAppears (delayMs)
32{
33 setAlwaysOnTop (true);
34 setOpaque (true);
35 setAccessible (false);
36
37 if (parentComp != nullptr)
38 parentComp->addChildComponent (this);
39
41
42 if (desktop.getMainMouseSource().canHover())
43 {
44 desktop.addGlobalMouseListener (this);
45 startTimer (123);
46 }
47}
48
54
56{
57 millisecondsBeforeTipAppears = newTimeMs;
58}
59
60void TooltipWindow::paint (Graphics& g)
61{
62 getLookAndFeel().drawTooltip (g, tipShowing, getWidth(), getHeight());
63}
64
65void TooltipWindow::mouseEnter (const MouseEvent& e)
66{
67 if (e.eventComponent == this)
68 hideTip();
69}
70
71void TooltipWindow::mouseDown (const MouseEvent&)
72{
73 if (isVisible())
74 dismissalMouseEventOccurred = true;
75}
76
77void TooltipWindow::mouseWheelMove (const MouseEvent&, const MouseWheelDetails&)
78{
79 if (isVisible())
80 dismissalMouseEventOccurred = true;
81}
82
83void TooltipWindow::updatePosition (const String& tip, Point<int> pos, Rectangle<int> parentArea)
84{
85 setBounds (getLookAndFeel().getTooltipBounds (tip, pos, parentArea));
86 setVisible (true);
87}
88
89#if JUCE_DEBUG
91#endif
92
94{
95 jassert (tip.isNotEmpty());
96
97 displayTipInternal (screenPos, tip, ShownManually::yes);
98}
99
100void TooltipWindow::displayTipInternal (Point<int> screenPos, const String& tip, ShownManually shownManually)
101{
102 if (! reentrant)
103 {
104 ScopedValueSetter<bool> setter (reentrant, true, false);
105
106 if (tipShowing != tip)
107 {
108 tipShowing = tip;
109 repaint();
110 }
111
112 if (auto* parent = getParentComponent())
113 {
114 updatePosition (tip, parent->getLocalPoint (nullptr, screenPos),
115 parent->getLocalBounds());
116 }
117 else
118 {
119 const auto physicalPos = detail::ScalingHelpers::scaledScreenPosToUnscaled (screenPos);
120 const auto scaledPos = detail::ScalingHelpers::unscaledScreenPosToScaled (*this, physicalPos);
121 updatePosition (tip, scaledPos, Desktop::getInstance().getDisplays().getDisplayForPoint (screenPos)->userArea);
122
127 }
128
129 #if JUCE_DEBUG
130 activeTooltipWindows.addIfNotAlreadyThere (this);
131
132 auto* parent = getParentComponent();
133
134 for (auto* w : activeTooltipWindows)
135 {
136 if (w != nullptr && w != this && w->tipShowing == tipShowing && w->getParentComponent() == parent)
137 {
138 // Looks like you have more than one TooltipWindow showing the same tip..
139 // Be careful not to create more than one instance of this class with the
140 // same parent component!
142 }
143 }
144 #endif
145
146 toFront (false);
147 manuallyShownTip = shownManually == ShownManually::yes ? tip : String();
148 dismissalMouseEventOccurred = false;
149 }
150}
151
153{
154 if (detail::WindowingHelpers::isForegroundOrEmbeddedProcess (&c)
155 && ! ModifierKeys::currentModifiers.isAnyMouseButtonDown())
156 {
157 if (auto* ttc = dynamic_cast<TooltipClient*> (&c))
159 return ttc->getTooltip();
160 }
161
162 return {};
163}
164
166{
167 if (isVisible() && ! reentrant)
168 {
169 tipShowing = {};
170 manuallyShownTip = {};
171 dismissalMouseEventOccurred = false;
172
174 setVisible (false);
175
177
178 #if JUCE_DEBUG
179 activeTooltipWindows.removeAllInstancesOf (this);
180 #endif
181 }
182}
183
185{
186 if (lastComponentUnderMouse != nullptr)
187 return Component::getApproximateScaleFactorForComponent (lastComponentUnderMouse);
188
190}
191
196
197void TooltipWindow::timerCallback()
198{
200 auto* newComp = mouseSource.isTouch() ? nullptr : mouseSource.getComponentUnderMouse();
201
202 if (manuallyShownTip.isNotEmpty())
203 {
204 if (dismissalMouseEventOccurred || newComp == nullptr)
205 hideTip();
206
207 return;
208 }
209
210 if (newComp == nullptr || getParentComponent() == nullptr || newComp->getPeer() == getPeer())
211 {
212 const auto newTip = newComp != nullptr ? getTipFor (*newComp) : String();
213
214 const auto mousePos = mouseSource.getScreenPosition();
215 const auto mouseMovedQuickly = (mousePos.getDistanceFrom (lastMousePos) > 12);
216 lastMousePos = mousePos;
217
218 const auto tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse);
220
221 lastComponentUnderMouse = newComp;
222 lastTipUnderMouse = newTip;
223
224 if (tipChanged || dismissalMouseEventOccurred || mouseMovedQuickly)
225 lastCompChangeTime = now;
226
227 const auto showTip = [this, &mouseSource, &mousePos, &newTip]
228 {
229 if (mouseSource.getLastMouseDownPosition() != lastMousePos)
230 displayTipInternal (mousePos.roundToInt(), newTip, ShownManually::no);
231 };
232
233 if (isVisible() || now < lastHideTime + 500)
234 {
235 // if a tip is currently visible (or has just disappeared), update to a new one
236 // immediately if needed..
237 if (newComp == nullptr || dismissalMouseEventOccurred || newTip.isEmpty())
238 hideTip();
239 else if (tipChanged)
240 showTip();
241 }
242 else
243 {
244 // if there isn't currently a tip, but one is needed, only let it appear after a timeout
245 if (newTip.isNotEmpty()
246 && newTip != tipShowing
247 && now > lastCompChangeTime + (uint32) millisecondsBeforeTipAppears)
248 {
249 showTip();
250 }
251 }
252 }
253}
254
255} // namespace juce
@ windowIsTemporary
Indicates that the window is a temporary popup, like a menu, tooltip, etc.
@ windowIgnoresKeyPresses
Tells the window not to catch any keypresses.
@ windowIgnoresMouseClicks
Indicates that the window should let mouse clicks pass through it (may not be possible on some platfo...
@ windowHasDropShadow
Indicates that the window should have a drop-shadow (this may not be possible on all platforms).
The base class for all JUCE user-interface objects.
void setAccessible(bool shouldBeAccessible)
Sets whether this component and its children are visible to accessibility clients.
bool isVisible() const noexcept
Tests whether the component is visible or not.
void removeFromDesktop()
If the component is currently showing on the desktop, this will hide it.
Component * getParentComponent() const noexcept
Returns the component which this component is inside.
int getHeight() const noexcept
Returns the component's height in pixels.
void toFront(bool shouldAlsoGainKeyboardFocus)
Brings the component to the front of its siblings.
static float JUCE_CALLTYPE getApproximateScaleFactorForComponent(const Component *targetComponent)
Returns the approximate scale factor for a given component by traversing its parent hierarchy and app...
void setAlwaysOnTop(bool shouldStayOnTop)
Sets whether the component should always be kept at the front of its siblings.
bool isCurrentlyBlockedByAnotherModalComponent() const
Checks whether there's a modal component somewhere that's stopping this one from receiving messages.
void setOpaque(bool shouldBeOpaque)
Indicates whether any parts of the component might be transparent.
void repaint()
Marks the whole component as needing to be redrawn.
virtual void addToDesktop(int windowStyleFlags, void *nativeWindowToAttachTo=nullptr)
Makes this component appear as a window on the desktop.
void setBounds(int x, int y, int width, int height)
Changes the component's position and size.
int getWidth() const noexcept
Returns the component's width in pixels.
ComponentPeer * getPeer() const
Returns the heavyweight window that contains this component.
LookAndFeel & getLookAndFeel() const noexcept
Finds the appropriate look-and-feel to use for this component.
virtual void setVisible(bool shouldBeVisible)
Makes the component visible or invisible.
virtual float getDesktopScaleFactor() const
Returns the default scale factor to use for this component when it is placed on the desktop.
MouseInputSource getMainMouseSource() const noexcept
Returns the main mouse input device that the system is using.
static Desktop &JUCE_CALLTYPE getInstance()
There's only one desktop object, and this method will return it.
void removeGlobalMouseListener(MouseListener *listener)
Unregisters a MouseListener that was added with addGlobalMouseListener().
A graphics context, used for drawing a component or image.
static ModifierKeys currentModifiers
This object represents the last-known state of the keyboard and mouse buttons.
bool isTouch() const noexcept
Returns true if this object represents a source of touch events.
A pair of (x, y) coordinates.
Definition juce_Point.h:42
Helper class providing an RAII-based mechanism for temporarily setting and then re-setting a value.
The JUCE String class!
Definition juce_String.h:53
bool isNotEmpty() const noexcept
Returns true if the string contains at least one character.
static uint32 getApproximateMillisecondCounter() noexcept
Less-accurate but faster version of getMillisecondCounter().
void startTimer(int intervalInMilliseconds) noexcept
Starts the timer and sets the length of interval required.
Components that want to use pop-up tooltips should implement this interface.
TooltipWindow(Component *parentComponent=nullptr, int millisecondsBeforeTipAppears=700)
Creates a tooltip window.
void displayTip(Point< int > screenPosition, const String &text)
Can be called to manually force a tip to be shown at a particular location.
~TooltipWindow() override
Destructor.
float getDesktopScaleFactor() const override
Returns the default scale factor to use for this component when it is placed on the desktop.
void hideTip()
Can be called to manually hide the tip if it's showing.
void setMillisecondsBeforeTipAppears(int newTimeMs=700) noexcept
Changes the time before the tip appears.
virtual String getTipFor(Component &)
Asks a component for its tooltip.
std::unique_ptr< AccessibilityHandler > createAccessibilityHandler() override
Override this method to return a custom AccessibilityHandler for this component.
#define jassert(expression)
Platform-independent assertion macro.
#define jassertfalse
This will always cause an assertion failure.
JUCE Namespace.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
unsigned int uint32
A platform-independent 32-bit unsigned integer type.