1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - 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 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-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 
26 namespace juce
27 {
28 
BubbleMessageComponent(int fadeOutLengthMs)29 BubbleMessageComponent::BubbleMessageComponent (int fadeOutLengthMs)
30     : fadeOutLength (fadeOutLengthMs), mouseClickCounter (0),
31       expiryTime (0), deleteAfterUse (false)
32 {
33 }
34 
~BubbleMessageComponent()35 BubbleMessageComponent::~BubbleMessageComponent()
36 {
37 }
38 
showAt(const Rectangle<int> & pos,const AttributedString & text,const int numMillisecondsBeforeRemoving,const bool removeWhenMouseClicked,const bool deleteSelfAfterUse)39 void BubbleMessageComponent::showAt (const Rectangle<int>& pos,
40                                      const AttributedString& text,
41                                      const int numMillisecondsBeforeRemoving,
42                                      const bool removeWhenMouseClicked,
43                                      const bool deleteSelfAfterUse)
44 {
45     createLayout (text);
46     setPosition (pos);
47     init (numMillisecondsBeforeRemoving, removeWhenMouseClicked, deleteSelfAfterUse);
48 }
49 
showAt(Component * const component,const AttributedString & text,const int numMillisecondsBeforeRemoving,const bool removeWhenMouseClicked,const bool deleteSelfAfterUse)50 void BubbleMessageComponent::showAt (Component* const component,
51                                      const AttributedString& text,
52                                      const int numMillisecondsBeforeRemoving,
53                                      const bool removeWhenMouseClicked,
54                                      const bool deleteSelfAfterUse)
55 {
56     createLayout (text);
57     setPosition (component);
58     init (numMillisecondsBeforeRemoving, removeWhenMouseClicked, deleteSelfAfterUse);
59 }
60 
createLayout(const AttributedString & text)61 void BubbleMessageComponent::createLayout (const AttributedString& text)
62 {
63     textLayout.createLayoutWithBalancedLineLengths (text, 256);
64 }
65 
init(const int numMillisecondsBeforeRemoving,const bool removeWhenMouseClicked,const bool deleteSelfAfterUse)66 void BubbleMessageComponent::init (const int numMillisecondsBeforeRemoving,
67                                    const bool removeWhenMouseClicked,
68                                    const bool deleteSelfAfterUse)
69 {
70     setAlpha (1.0f);
71     setVisible (true);
72     deleteAfterUse = deleteSelfAfterUse;
73 
74     expiryTime = numMillisecondsBeforeRemoving > 0
75                     ? (Time::getMillisecondCounter() + (uint32) numMillisecondsBeforeRemoving) : 0;
76 
77     mouseClickCounter = Desktop::getInstance().getMouseButtonClickCounter();
78 
79     if (! (removeWhenMouseClicked && isShowing()))
80         mouseClickCounter += 0xfffff;
81 
82     startTimer (77);
83     repaint();
84 }
85 
86 const float bubblePaddingX = 20.0f;
87 const float bubblePaddingY = 14.0f;
88 
getContentSize(int & w,int & h)89 void BubbleMessageComponent::getContentSize (int& w, int& h)
90 {
91     w = (int) (bubblePaddingX + textLayout.getWidth());
92     h = (int) (bubblePaddingY + textLayout.getHeight());
93 }
94 
paintContent(Graphics & g,int w,int h)95 void BubbleMessageComponent::paintContent (Graphics& g, int w, int h)
96 {
97     g.setColour (findColour (TooltipWindow::textColourId));
98 
99     textLayout.draw (g, Rectangle<float> (bubblePaddingX / 2.0f, bubblePaddingY / 2.0f,
100                                           (float) w - bubblePaddingX, (float) h - bubblePaddingY));
101 }
102 
timerCallback()103 void BubbleMessageComponent::timerCallback()
104 {
105     if (Desktop::getInstance().getMouseButtonClickCounter() > mouseClickCounter)
106         hide (false);
107     else if (expiryTime != 0 && Time::getMillisecondCounter() > expiryTime)
108         hide (true);
109 }
110 
hide(const bool fadeOut)111 void BubbleMessageComponent::hide (const bool fadeOut)
112 {
113     stopTimer();
114 
115     if (fadeOut)
116         Desktop::getInstance().getAnimator().fadeOut (this, fadeOutLength);
117     else
118         setVisible (false);
119 
120     if (deleteAfterUse)
121         delete this;
122 }
123 
124 } // namespace juce
125