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_ModalComponentManager.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{
33 component (comp), autoDelete (shouldAutoDelete)
34 {
35 jassert (comp != nullptr);
36 }
37
38 ~ModalItem() override
39 {
40 if (autoDelete)
42 }
43
44 void componentMovedOrResized (bool, bool) override {}
45
47
48 void componentPeerChanged() override
49 {
51 }
52
54 {
55 if (! component->isShowing())
56 cancel();
57 }
58
60
61 void componentBeingDeleted (Component& comp) override
62 {
64
65 if (component == &comp || comp.isParentOf (component))
66 {
67 autoDelete = false;
68 cancel();
69 }
70 }
71
72 void cancel()
73 {
74 if (isActive)
75 {
76 isActive = false;
77
78 if (auto* mcm = ModalComponentManager::getInstanceWithoutCreating())
79 mcm->triggerAsyncUpdate();
80 }
81 }
82
83 Component* component;
84 OwnedArray<Callback> callbacks;
85 int returnValue = 0;
86 bool isActive = true, autoDelete;
87
89};
90
91//==============================================================================
95
101
103
104
105//==============================================================================
106void ModalComponentManager::startModal (Component* component, bool autoDelete)
107{
108 if (component != nullptr)
109 {
110 stack.add (new ModalItem (component, autoDelete));
111 detail::ComponentHelpers::ModalComponentManagerChangeNotifier::getInstance().modalComponentManagerChanged();
112 }
113}
114
116{
117 if (callback != nullptr)
118 {
120
121 for (int i = stack.size(); --i >= 0;)
122 {
123 auto* item = stack.getUnchecked (i);
124
125 if (item->component == component)
126 {
127 item->callbacks.add (callback);
128 callbackDeleter.release();
129 break;
130 }
131 }
132 }
133}
134
135void ModalComponentManager::endModal (Component* component)
136{
137 for (int i = stack.size(); --i >= 0;)
138 {
139 auto* item = stack.getUnchecked (i);
140
141 if (item->component == component)
142 item->cancel();
143 }
144}
145
146void ModalComponentManager::endModal (Component* component, int returnValue)
147{
148 for (int i = stack.size(); --i >= 0;)
149 {
150 auto* item = stack.getUnchecked (i);
151
152 if (item->component == component)
153 {
154 item->returnValue = returnValue;
155 item->cancel();
156 }
157 }
158}
159
161{
162 int n = 0;
163
164 for (auto* item : stack)
165 if (item->isActive)
166 ++n;
167
168 return n;
169}
170
172{
173 int n = 0;
174
175 for (int i = stack.size(); --i >= 0;)
176 {
177 auto* item = stack.getUnchecked (i);
178
179 if (item->isActive)
180 if (n++ == index)
181 return item->component;
182 }
183
184 return nullptr;
185}
186
188{
189 for (auto* item : stack)
190 if (item->isActive && item->component == comp)
191 return true;
192
193 return false;
194}
195
197{
198 return comp == getModalComponent (0);
199}
200
202{
203 for (int i = stack.size(); --i >= 0;)
204 {
205 auto* item = stack.getUnchecked (i);
206
207 if (! item->isActive)
208 {
209 std::unique_ptr<ModalItem> deleter (stack.removeAndReturn (i));
210 Component::SafePointer<Component> compToDelete (item->autoDelete ? item->component : nullptr);
211
212 for (int j = item->callbacks.size(); --j >= 0;)
213 item->callbacks.getUnchecked (j)->modalStateFinished (item->returnValue);
214
216
217 detail::ComponentHelpers::ModalComponentManagerChangeNotifier::getInstance().modalComponentManagerChanged();
218 }
219 }
220}
221
223{
224 ComponentPeer* lastOne = nullptr;
225
226 for (int i = 0; i < getNumModalComponents(); ++i)
227 {
228 auto* c = getModalComponent (i);
229
230 if (c == nullptr)
231 break;
232
233 if (auto* peer = c->getPeer())
234 {
235 if (peer != lastOne)
236 {
237 if (lastOne == nullptr)
238 {
239 peer->toFront (topOneShouldGrabFocus);
240
242 peer->grabFocus();
243 }
244 else
245 {
246 peer->toBehind (lastOne);
247 }
248
249 lastOne = peer;
250 }
251 }
252 }
253}
254
256{
258
259 for (int i = numModal; --i >= 0;)
260 if (auto* c = getModalComponent (i))
261 c->exitModalState (0);
262
263 return numModal > 0;
264}
265
266//==============================================================================
267#if JUCE_MODAL_LOOPS_PERMITTED
268int ModalComponentManager::runEventLoopForCurrentComponent()
269{
270 // This can only be run from the message thread!
272
273 int returnValue = 0;
274
275 if (auto* currentlyModal = getModalComponent (0))
276 {
278 bool finished = false;
279
280 attachCallback (currentlyModal, ModalCallbackFunction::create ([&] (int r) { returnValue = r; finished = true; }));
281
283 {
284 while (! finished)
285 {
287 break;
288 }
289 }
291 }
292
293 return returnValue;
294}
295#endif
296
297} // namespace juce
An object that watches for any movement of a component or any of its parent components.
void componentBeingDeleted(Component &) override
Called when the component is in the process of being deleted.
virtual void componentMovedOrResized(bool wasMoved, bool wasResized)=0
This callback happens when the component that is being watched is moved relative to its top-level pee...
virtual void componentVisibilityChanged()=0
This callback happens when the component's visibility state changes, possibly due to one of its paren...
The Component class uses a ComponentPeer internally to create and manage a real operating-system wind...
Holds a pointer to some type of Component, which automatically becomes null if the component is delet...
void deleteAndZero()
If the component is valid, this deletes it and sets this pointer to null.
The base class for all JUCE user-interface objects.
bool isShowing() const
Tests whether this component and all its parents are visible.
bool isParentOf(const Component *possibleChild) const noexcept
Checks whether a component is anywhere inside this component or its children.
static MessageManager * getInstance()
Returns the global instance of the MessageManager.
static ModalComponentManager::Callback * create(CallbackFn &&fn)
This is a utility function to create a ModalComponentManager::Callback that will call a callable obje...
Receives callbacks when a modal component is dismissed.
Manages the system's stack of modal components.
void handleAsyncUpdate() override
Called back to do whatever your class needs to do.
bool isModal(const Component *component) const
Returns true if the specified component is in a modal state.
void bringModalComponentsToFront(bool topOneShouldGrabFocus=true)
Brings any modal components to the front.
Component * getModalComponent(int index) const
Returns one of the components being shown modally.
bool isFrontModalComponent(const Component *component) const
Returns true if the specified component is currently the topmost modal component.
void attachCallback(Component *component, Callback *callback)
Adds a new callback that will be called when the specified modal component is dismissed.
bool cancelAllModalComponents()
Calls exitModalState (0) on any components that are currently modal.
ModalComponentManager()
Creates a ModalComponentManager.
int getNumModalComponents() const
Returns the number of components currently being shown modally.
#define JUCE_TRY
The JUCE_TRY/JUCE_CATCH_EXCEPTION wrappers can be used to pass any uncaught exceptions to the JUCEApp...
#define JUCE_CATCH_EXCEPTION
The JUCE_TRY/JUCE_CATCH_EXCEPTION wrappers can be used to pass any uncaught exceptions to the JUCEApp...
#define JUCE_ASSERT_MESSAGE_THREAD
This macro is used to catch unsafe use of functions which expect to only be called on the message thr...
#define jassert(expression)
Platform-independent assertion macro.
#define JUCE_DECLARE_NON_COPYABLE(className)
This is a shorthand macro for deleting a class's copy constructor and copy assignment operator.
#define JUCE_IMPLEMENT_SINGLETON(Classname)
This is a counterpart to the JUCE_DECLARE_SINGLETON macros.
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
void componentBeingDeleted(Component &comp) override
Called when the component is in the process of being deleted.
void componentVisibilityChanged() override
This callback happens when the component's visibility state changes, possibly due to one of its paren...
void componentMovedOrResized(bool, bool) override
This callback happens when the component that is being watched is moved relative to its top-level pee...
void componentPeerChanged() override
This callback happens when the component's top-level peer is changed.