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
getTypefaceForFontFromLookAndFeel(const Font & font)29 static Typeface::Ptr getTypefaceForFontFromLookAndFeel (const Font& font)
30 {
31 return LookAndFeel::getDefaultLookAndFeel().getTypefaceForFont (font);
32 }
33
34 using GetTypefaceForFont = Typeface::Ptr (*)(const Font&);
35 extern GetTypefaceForFont juce_getTypefaceForFont;
36
37 //==============================================================================
LookAndFeel()38 LookAndFeel::LookAndFeel()
39 {
40 /* if this fails it means you're trying to create a LookAndFeel object before
41 the static Colours have been initialised. That ain't gonna work. It probably
42 means that you're using a static LookAndFeel object and that your compiler has
43 decided to initialise it before the Colours class.
44 */
45 jassert (Colours::white == Colour (0xffffffff));
46
47 juce_getTypefaceForFont = getTypefaceForFontFromLookAndFeel;
48 }
49
~LookAndFeel()50 LookAndFeel::~LookAndFeel()
51 {
52 /* This assertion is triggered if you try to delete a LookAndFeel object while something
53 is still using it!
54
55 Reasons may be:
56 - it's still being used as the default LookAndFeel; or
57 - it's set as a Component's current lookandfeel; or
58 - there's a WeakReference to it somewhere else in your code
59
60 Generally the fix for this will be to make sure you call
61 Component::setLookandFeel (nullptr) on any components that were still using
62 it before you delete it, or call LookAndFeel::setDefaultLookAndFeel (nullptr)
63 if you had set it up to be the default one. This assertion can also be avoided by
64 declaring your LookAndFeel object before any of the Components that use it as
65 the Components will be destroyed before the LookAndFeel.
66
67 Deleting a LookAndFeel is unlikely to cause a crash since most things will use a
68 safe WeakReference to it, but it could cause some unexpected graphical behaviour,
69 so it's advisable to clear up any references before destroying them!
70 */
71 jassert (masterReference.getNumActiveWeakReferences() == 0
72 || (masterReference.getNumActiveWeakReferences() == 1
73 && this == &getDefaultLookAndFeel()));
74 }
75
76 //==============================================================================
findColour(int colourID) const77 Colour LookAndFeel::findColour (int colourID) const noexcept
78 {
79 const ColourSetting c = { colourID, Colour() };
80 auto index = colours.indexOf (c);
81
82 if (index >= 0)
83 return colours[index].colour;
84
85 jassertfalse;
86 return Colours::black;
87 }
88
setColour(int colourID,Colour newColour)89 void LookAndFeel::setColour (int colourID, Colour newColour) noexcept
90 {
91 const ColourSetting c = { colourID, newColour };
92 auto index = colours.indexOf (c);
93
94 if (index >= 0)
95 colours.getReference (index).colour = newColour;
96 else
97 colours.add (c);
98 }
99
isColourSpecified(const int colourID) const100 bool LookAndFeel::isColourSpecified (const int colourID) const noexcept
101 {
102 const ColourSetting c = { colourID, Colour() };
103 return colours.contains (c);
104 }
105
106 //==============================================================================
getDefaultLookAndFeel()107 LookAndFeel& LookAndFeel::getDefaultLookAndFeel() noexcept
108 {
109 return Desktop::getInstance().getDefaultLookAndFeel();
110 }
111
setDefaultLookAndFeel(LookAndFeel * newDefaultLookAndFeel)112 void LookAndFeel::setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) noexcept
113 {
114 Desktop::getInstance().setDefaultLookAndFeel (newDefaultLookAndFeel);
115 }
116
117 //==============================================================================
getTypefaceForFont(const Font & font)118 Typeface::Ptr LookAndFeel::getTypefaceForFont (const Font& font)
119 {
120 if (font.getTypefaceName() == Font::getDefaultSansSerifFontName())
121 {
122 if (defaultTypeface != nullptr)
123 return defaultTypeface;
124
125 if (defaultSans.isNotEmpty())
126 {
127 Font f (font);
128 f.setTypefaceName (defaultSans);
129 return Typeface::createSystemTypefaceFor (f);
130 }
131 }
132
133 return Font::getDefaultTypefaceForFont (font);
134 }
135
setDefaultSansSerifTypeface(Typeface::Ptr newDefaultTypeface)136 void LookAndFeel::setDefaultSansSerifTypeface (Typeface::Ptr newDefaultTypeface)
137 {
138 if (defaultTypeface != newDefaultTypeface)
139 {
140 defaultTypeface = newDefaultTypeface;
141 Typeface::clearTypefaceCache();
142 }
143 }
144
setDefaultSansSerifTypefaceName(const String & newName)145 void LookAndFeel::setDefaultSansSerifTypefaceName (const String& newName)
146 {
147 if (defaultSans != newName)
148 {
149 defaultTypeface.reset();
150 Typeface::clearTypefaceCache();
151 defaultSans = newName;
152 }
153 }
154
155 //==============================================================================
getMouseCursorFor(Component & component)156 MouseCursor LookAndFeel::getMouseCursorFor (Component& component)
157 {
158 auto cursor = component.getMouseCursor();
159
160 for (auto* parent = component.getParentComponent();
161 parent != nullptr && cursor == MouseCursor::ParentCursor;
162 parent = parent->getParentComponent())
163 {
164 cursor = parent->getMouseCursor();
165 }
166
167 return cursor;
168 }
169
createGraphicsContext(const Image & imageToRenderOn,Point<int> origin,const RectangleList<int> & initialClip)170 std::unique_ptr<LowLevelGraphicsContext> LookAndFeel::createGraphicsContext (const Image& imageToRenderOn,
171 Point<int> origin,
172 const RectangleList<int>& initialClip)
173 {
174 return std::make_unique<LowLevelGraphicsSoftwareRenderer> (imageToRenderOn, origin, initialClip);
175 }
176
177 //==============================================================================
setUsingNativeAlertWindows(bool shouldUseNativeAlerts)178 void LookAndFeel::setUsingNativeAlertWindows (bool shouldUseNativeAlerts)
179 {
180 useNativeAlertWindows = shouldUseNativeAlerts;
181 }
182
isUsingNativeAlertWindows()183 bool LookAndFeel::isUsingNativeAlertWindows()
184 {
185 #if JUCE_LINUX
186 return false; // not available currently..
187 #else
188 return useNativeAlertWindows;
189 #endif
190 }
191
192 } // namespace juce
193