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_ResizableWindow.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
29ResizableWindow::ResizableWindow (const String& name, bool shouldAddToDesktop)
31{
32 initialise (shouldAddToDesktop);
33}
34
35ResizableWindow::ResizableWindow (const String& name, Colour bkgnd, bool shouldAddToDesktop)
37{
39 initialise (shouldAddToDesktop);
40}
41
43{
44 splashScreen.deleteAndZero();
45
46 // Don't delete or remove the resizer components yourself! They're managed by the
47 // ResizableWindow, and you should leave them alone! You may have deleted them
48 // accidentally by careless use of deleteAllChildren()..?
49 jassert (resizableCorner == nullptr || getIndexOfChildComponent (resizableCorner.get()) >= 0);
50 jassert (resizableBorder == nullptr || getIndexOfChildComponent (resizableBorder.get()) >= 0);
51
52 resizableCorner.reset();
53 resizableBorder.reset();
55
56 // have you been adding your own components directly to this window..? tut tut tut.
57 // Read the instructions for using a ResizableWindow!
59}
60
61void ResizableWindow::initialise (const bool shouldAddToDesktop)
62{
63 /*
64 ==========================================================================
65
66 In accordance with the terms of the JUCE 7 End-Use License Agreement, the
67 JUCE Code in SECTION A cannot be removed, changed or otherwise rendered
68 ineffective unless you have a JUCE Indie or Pro license, or are using
69 JUCE under the GPL v3 license.
70
71 End User License Agreement: www.juce.com/juce-7-licence
72
73 ==========================================================================
74 */
75
76 // BEGIN SECTION A
77
78 #if ! JucePlugin_Build_Standalone
79 splashScreen = new JUCESplashScreen (*this);
80 #endif
81
82 // END SECTION A
83
84 defaultConstrainer.setMinimumOnscreenAmounts (0x10000, 16, 24, 16);
85
86 lastNonFullScreenPos.setBounds (50, 50, 256, 256);
87
90}
91
92int ResizableWindow::getDesktopWindowStyleFlags() const
93{
94 int styleFlags = TopLevelWindow::getDesktopWindowStyleFlags();
95
96 if (isResizable() && (styleFlags & ComponentPeer::windowHasTitleBar) != 0)
98
99 return styleFlags;
100}
101
102//==============================================================================
104{
105 if (ownsContentComponent)
106 {
107 contentComponent.deleteAndZero();
108 }
109 else
110 {
111 removeChildComponent (contentComponent);
112 contentComponent = nullptr;
113 }
114}
115
116void ResizableWindow::setContent (Component* newContentComponent,
117 bool takeOwnership,
119{
120 if (newContentComponent != contentComponent)
121 {
123
124 contentComponent = newContentComponent;
125 Component::addAndMakeVisible (contentComponent);
126 }
127
128 ownsContentComponent = takeOwnership;
129 resizeToFitContent = resizeToFitWhenContentChangesSize;
130
132 childBoundsChanged (contentComponent);
133
134 resized(); // must always be called to position the new content comp
135}
136
141
146
147void ResizableWindow::setContentComponent (Component* const newContentComponent,
148 const bool deleteOldOne,
150{
151 if (newContentComponent != contentComponent)
152 {
153 if (deleteOldOne)
154 {
155 contentComponent.deleteAndZero();
156 }
157 else
158 {
159 removeChildComponent (contentComponent);
160 contentComponent = nullptr;
161 }
162 }
163
165}
166
168{
169 jassert (width > 0 && height > 0); // not a great idea to give it a zero size..
170
171 auto border = getContentComponentBorder();
172
173 setSize (width + border.getLeftAndRight(),
174 height + border.getTopAndBottom());
175}
176
178{
180 return {};
181
182 return BorderSize<int> ((resizableBorder != nullptr && ! isFullScreen()) ? 4 : 1);
183}
184
189
191{
192 updateLastPosIfShowing();
193}
194
196{
198 updateLastPosIfShowing();
199}
200
202{
204
205 if (resizableBorder != nullptr)
206 {
207 resizableBorder->setVisible (! resizerHidden);
208 resizableBorder->setBorderThickness (getBorderThickness());
209 resizableBorder->setSize (getWidth(), getHeight());
210 resizableBorder->toBack();
211 }
212
213 if (resizableCorner != nullptr)
214 {
215 resizableCorner->setVisible (! resizerHidden);
216
217 const int resizerSize = 18;
218 resizableCorner->setBounds (getWidth() - resizerSize,
221 }
222
223 if (contentComponent != nullptr)
224 {
225 // The window expects to be able to be able to manage the size and position
226 // of its content component, so you can't arbitrarily add a transform to it!
227 jassert (! contentComponent->isTransformed());
228
229 contentComponent->setBoundsInset (getContentComponentBorder());
230 }
231
232 updateLastPosIfShowing();
233
234 #if JUCE_DEBUG
235 hasBeenResized = true;
236 #endif
237}
238
240{
241 if ((child == contentComponent) && (child != nullptr) && resizeToFitContent)
242 {
243 // not going to look very good if this component has a zero size..
244 jassert (child->getWidth() > 0);
245 jassert (child->getHeight() > 0);
246
248
249 setSize (child->getWidth() + borders.getLeftAndRight(),
250 child->getHeight() + borders.getTopAndBottom());
251 }
252}
253
254
255//==============================================================================
257{
258 auto border = getContentComponentBorder();
259 auto area = getLocalBounds();
260
261 repaint (area.removeFromTop (border.getTop()));
262 repaint (area.removeFromLeft (border.getLeft()));
263 repaint (area.removeFromRight (border.getRight()));
264 repaint (area.removeFromBottom (border.getBottom()));
265}
266
267//==============================================================================
269 const bool useBottomRightCornerResizer)
270{
272 {
273 if (useBottomRightCornerResizer)
274 {
275 resizableBorder.reset();
276
277 if (resizableCorner == nullptr)
278 {
279 resizableCorner.reset (new ResizableCornerComponent (this, constrainer));
280 Component::addChildComponent (resizableCorner.get());
281 resizableCorner->setAlwaysOnTop (true);
282 }
283 }
284 else
285 {
286 resizableCorner.reset();
287
288 if (resizableBorder == nullptr)
289 {
290 resizableBorder.reset (new ResizableBorderComponent (this, constrainer));
291 Component::addChildComponent (resizableBorder.get());
292 }
293 }
294 }
295 else
296 {
297 resizableCorner.reset();
298 resizableBorder.reset();
299 }
300
302 recreateDesktopWindow();
303
304 childBoundsChanged (contentComponent);
305 resized();
306}
307
309{
310 return resizableCorner != nullptr
311 || resizableBorder != nullptr;
312}
313
316 int newMaximumWidth,
317 int newMaximumHeight) noexcept
318{
319 // if you've set up a custom constrainer then these settings won't have any effect..
320 jassert (constrainer == &defaultConstrainer || constrainer == nullptr);
321
322 if (constrainer == nullptr)
323 setConstrainer (&defaultConstrainer);
324
325 defaultConstrainer.setSizeLimits (newMinimumWidth, newMinimumHeight,
327
328 setBoundsConstrained (getBounds());
329}
330
332{
333 canDrag = shouldBeDraggable;
334}
335
337{
338 if (constrainer != newConstrainer)
339 {
340 constrainer = newConstrainer;
341
342 bool useBottomRightCornerResizer = resizableCorner != nullptr;
343 bool shouldBeResizable = useBottomRightCornerResizer || resizableBorder != nullptr;
344
345 resizableCorner.reset();
346 resizableBorder.reset();
347
348 setResizable (shouldBeResizable, useBottomRightCornerResizer);
349 updatePeerConstrainer();
350 }
351}
352
354{
355 if (constrainer != nullptr)
356 constrainer->setBoundsForComponent (this, newBounds, false, false, false, false);
357 else
359}
360
361//==============================================================================
363{
364 auto& lf = getLookAndFeel();
365
366 lf.fillResizableWindowBackground (g, getWidth(), getHeight(),
367 getBorderThickness(), *this);
368
369 if (! isFullScreen())
370 lf.drawResizableWindowBorder (g, getWidth(), getHeight(),
371 getBorderThickness(), *this);
372
373 #if JUCE_DEBUG
374 /* If this fails, then you've probably written a subclass with a resized()
375 callback but forgotten to make it call its parent class's resized() method.
376
377 It's important when you override methods like resized(), moved(),
378 etc., that you make sure the base class methods also get called.
379
380 Of course you shouldn't really be overriding ResizableWindow::resized() anyway,
381 because your content should all be inside the content component - and it's the
382 content component's resized() method that you should be using to do your
383 layout.
384 */
385 jassert (hasBeenResized || (getWidth() == 0 && getHeight() == 0));
386 #endif
387}
388
390{
391 resized();
392
393 if (isOnDesktop())
394 {
395 Component::addToDesktop (getDesktopWindowStyleFlags());
396 updatePeerConstrainer();
397 }
398}
399
404
406{
407 auto backgroundColour = newColour;
408
410 backgroundColour = newColour.withAlpha (1.0f);
411
412 setColour (backgroundColourId, backgroundColour);
413 setOpaque (backgroundColour.isOpaque());
414 repaint();
415}
416
417//==============================================================================
419{
420 if (isOnDesktop())
421 {
422 auto* peer = getPeer();
423 return peer != nullptr && peer->isFullScreen();
424 }
425
426 return fullscreen;
427}
428
430{
432 {
433 updateLastPosIfShowing();
434 fullscreen = shouldBeFullScreen;
435
436 if (isOnDesktop())
437 {
438 if (auto* peer = getPeer())
439 {
440 // keep a copy of this intact in case the real one gets messed-up while we're un-maximising
441 auto lastPos = lastNonFullScreenPos;
442
443 peer->setFullScreen (shouldBeFullScreen);
444
445 if ((! shouldBeFullScreen) && ! lastPos.isEmpty())
447 }
448 else
449 {
451 }
452 }
453 else
454 {
457 else
458 setBounds (lastNonFullScreenPos);
459 }
460
461 resized();
462 }
463}
464
466{
467 if (auto* peer = getPeer())
468 return peer->isMinimised();
469
470 return false;
471}
472
474{
476 {
477 if (auto* peer = getPeer())
478 {
479 updateLastPosIfShowing();
480 peer->setMinimised (shouldMinimise);
481 }
482 else
483 {
485 }
486 }
487}
488
490{
491 if (isOnDesktop())
492 if (auto* peer = getPeer())
493 return peer->isKioskMode();
494
496}
497
498void ResizableWindow::updateLastPosIfShowing()
499{
500 if (isShowing())
501 {
502 updateLastPosIfNotFullScreen();
503 updatePeerConstrainer();
504 }
505}
506
507void ResizableWindow::updateLastPosIfNotFullScreen()
508{
509 if (! (isFullScreen() || isMinimised() || isKioskMode()))
510 lastNonFullScreenPos = getBounds();
511}
512
513void ResizableWindow::updatePeerConstrainer()
514{
515 if (isOnDesktop())
516 if (auto* peer = getPeer())
517 peer->setConstrainer (constrainer);
518}
519
525
526//==============================================================================
528{
529 updateLastPosIfShowing();
530 auto stateString = (isFullScreen() && ! isKioskMode() ? "fs " : "") + lastNonFullScreenPos.toString();
531
532 #if JUCE_LINUX
533 if (auto* peer = isOnDesktop() ? getPeer() : nullptr)
534 {
535 if (const auto optionalFrameSize = peer->getFrameSizeIfPresent())
536 {
537 const auto& frameSize = *optionalFrameSize;
538 stateString << " frame " << frameSize.getTop() << ' ' << frameSize.getLeft()
539 << ' ' << frameSize.getBottom() << ' ' << frameSize.getRight();
540 }
541 }
542 #endif
543
544 return stateString;
545}
546
548{
549 StringArray tokens;
550 tokens.addTokens (s, false);
551 tokens.removeEmptyStrings();
552 tokens.trim();
553
554 const bool fs = tokens[0].startsWithIgnoreCase ("fs");
555 const int firstCoord = fs ? 1 : 0;
556
557 if (tokens.size() < firstCoord + 4)
558 return false;
559
560 Rectangle<int> newPos (tokens[firstCoord].getIntValue(),
561 tokens[firstCoord + 1].getIntValue(),
562 tokens[firstCoord + 2].getIntValue(),
563 tokens[firstCoord + 3].getIntValue());
564
565 if (newPos.isEmpty())
566 return false;
567
568 auto* peer = isOnDesktop() ? getPeer() : nullptr;
569
570 if (peer != nullptr)
571 {
572 if (const auto frameSize = peer->getFrameSizeIfPresent())
573 frameSize->addTo (newPos);
574 }
575
576 #if JUCE_LINUX
577 if (peer == nullptr || ! peer->getFrameSizeIfPresent())
578 {
579 // We need to adjust for the frame size before we create a peer, as X11
580 // doesn't provide this information at construction time.
581 if (tokens[firstCoord + 4] == "frame" && tokens.size() == firstCoord + 9)
582 {
583 BorderSize<int> frame { tokens[firstCoord + 5].getIntValue(),
584 tokens[firstCoord + 6].getIntValue(),
585 tokens[firstCoord + 7].getIntValue(),
586 tokens[firstCoord + 8].getIntValue() };
587
588 newPos.setX (newPos.getX() - frame.getLeft());
589 newPos.setY (newPos.getY() - frame.getTop());
590
592 }
593 }
594 #endif
595
596 {
598 auto allMonitors = desktop.getDisplays().getRectangleList (true);
599 allMonitors.clipTo (newPos);
600 auto onScreenArea = allMonitors.getBounds();
601
602 if (onScreenArea.getWidth() * onScreenArea.getHeight() < 32 * 32)
603 {
604 auto screen = desktop.getDisplays().getDisplayForRect (newPos)->userArea;
605
606 newPos.setSize (jmin (newPos.getWidth(), screen.getWidth()),
607 jmin (newPos.getHeight(), screen.getHeight()));
608
609 newPos.setPosition (jlimit (screen.getX(), screen.getRight() - newPos.getWidth(), newPos.getX()),
610 jlimit (screen.getY(), screen.getBottom() - newPos.getHeight(), newPos.getY()));
611 }
612 }
613
614 if (peer != nullptr)
615 {
616 if (const auto frameSize = peer->getFrameSizeIfPresent())
617 frameSize->subtractFrom (newPos);
618
619 peer->setNonFullScreenBounds (newPos);
620 }
621
622 updateLastPosIfNotFullScreen();
623
624 if (fs)
626
628
629 if (! fs)
631
632 return true;
633}
634
635//==============================================================================
637{
638 if (canDrag && ! isFullScreen())
639 {
640 dragStarted = true;
641 dragger.startDraggingComponent (this, e);
642 }
643}
644
646{
647 if (dragStarted)
648 dragger.dragComponent (this, e, constrainer);
649}
650
652{
653 dragStarted = false;
654}
655
656//==============================================================================
657#if JUCE_DEBUG
659{
660 /* Agh! You shouldn't add components directly to a ResizableWindow - this class
661 manages its child components automatically, and if you add your own it'll cause
662 trouble. Instead, use setContentComponent() to give it a component which
663 will be automatically resized and kept in the right place - then you can add
664 subcomponents to the content comp. See the notes for the ResizableWindow class
665 for more info.
666
667 If you really know what you're doing and want to avoid this assertion, just call
668 Component::addChildComponent directly.
669 */
671
673}
674
675void ResizableWindow::addAndMakeVisible (Component* const child, int zOrder)
676{
677 /* Agh! You shouldn't add components directly to a ResizableWindow - this class
678 manages its child components automatically, and if you add your own it'll cause
679 trouble. Instead, use setContentComponent() to give it a component which
680 will be automatically resized and kept in the right place - then you can add
681 subcomponents to the content comp. See the notes for the ResizableWindow class
682 for more info.
683
684 If you really know what you're doing and want to avoid this assertion, just call
685 Component::addAndMakeVisible directly.
686 */
688
690}
691#endif
692
693} // namespace juce
Specifies a set of gaps to be left around the sides of a rectangle.
Represents a colour, also including a transparency value.
Definition juce_Colour.h:38
A class that imposes restrictions on a Component's size or position.
void setMinimumOnscreenAmounts(int minimumWhenOffTheTop, int minimumWhenOffTheLeft, int minimumWhenOffTheBottom, int minimumWhenOffTheRight) noexcept
Sets the amount by which the component is allowed to go off-screen.
void setBoundsForComponent(Component *component, Rectangle< int > bounds, bool isStretchingTop, bool isStretchingLeft, bool isStretchingBottom, bool isStretchingRight)
Checks the given bounds, and then sets the component to the corrected size.
void dragComponent(Component *componentToDrag, const MouseEvent &e, ComponentBoundsConstrainer *constrainer)
Call this from your mouseDrag() callback to move the component.
void startDraggingComponent(Component *componentToDrag, const MouseEvent &e)
Call this from your component's mouseDown() method, to prepare for dragging.
@ windowIsResizable
Indicates that the window should have a resizable border.
@ windowHasTitleBar
Indicates that the window should have a normal OS-specific title bar and frame.
The base class for all JUCE user-interface objects.
Component * getParentComponent() const noexcept
Returns the component which this component is inside.
int getNumChildComponents() const noexcept
Returns the number of child components that this component contains.
int getIndexOfChildComponent(const Component *child) const noexcept
Returns the index of this component in the list of child components.
int getHeight() const noexcept
Returns the component's height in pixels.
bool isShowing() const
Tests whether this component and all its parents are visible.
void addAndMakeVisible(Component *child, int zOrder=-1)
Adds a child component to this one, and also makes the child visible if it isn't already.
void setOpaque(bool shouldBeOpaque)
Indicates whether any parts of the component might be transparent.
Rectangle< int > getBounds() const noexcept
Returns this component's bounding box.
void repaint()
Marks the whole component as needing to be redrawn.
bool isOnDesktop() const noexcept
Returns true if this component is currently showing on the desktop.
void removeChildComponent(Component *childToRemove)
Removes one of this component's child-components.
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.
void setSize(int newWidth, int newHeight)
Changes the size of the component.
void setColour(int colourID, Colour newColour)
Registers a colour to be used for a particular purpose.
Colour findColour(int colourID, bool inheritFromParent=false) const
Looks for a colour that has been registered with the given colour ID number.
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.
Rectangle< int > getLocalBounds() const noexcept
Returns the component's bounds, relative to its own origin.
int getParentWidth() const noexcept
Returns the width of the component's parent.
void addChildComponent(Component *child, int zOrder=-1)
Adds a child component to this one.
int getParentHeight() const noexcept
Returns the height of the component's parent.
Component * getKioskModeComponent() const noexcept
Returns the component that is currently being used in kiosk-mode.
static Desktop &JUCE_CALLTYPE getInstance()
There's only one desktop object, and this method will return it.
static bool canUseSemiTransparentWindows() noexcept
True if the OS supports semitransparent windows.
A graphics context, used for drawing a component or image.
The standard JUCE splash screen component.
Contains position and status information about a mouse event.
Manages a rectangle and allows geometric operations to be performed on it.
String toString() const
Creates a string describing this rectangle.
void setBounds(ValueType newX, ValueType newY, ValueType newWidth, ValueType newHeight) noexcept
Changes all the rectangle's coordinates.
A component that resizes its parent component when dragged.
A component that resizes a parent component when dragged.
void setResizable(bool shouldBeResizable, bool useBottomRightCornerResizer)
Make the window resizable or fixed.
void setBoundsConstrained(const Rectangle< int > &newBounds)
Calls the window's setBounds method, after first checking these bounds with the current constrainer.
void setFullScreen(bool shouldBeFullScreen)
Puts the window into full-screen mode, or restores it to its normal size.
void mouseDown(const MouseEvent &) override
Called when a mouse button is pressed.
String getWindowStateAsString()
Returns a string which encodes the window's current size and position.
void setDraggable(bool shouldBeDraggable) noexcept
Can be used to enable or disable user-dragging of the window.
void resized() override
(if overriding this, make sure you call ResizableWindow::resized() in your subclass)
bool isResizable() const noexcept
Returns true if resizing is enabled.
void mouseUp(const MouseEvent &) override
Called when a mouse button is released.
void setResizeLimits(int newMinimumWidth, int newMinimumHeight, int newMaximumWidth, int newMaximumHeight) noexcept
This sets the maximum and minimum sizes for the window.
bool isMinimised() const
Returns true if the window is currently minimised.
bool isKioskMode() const
Returns true if the window has been placed in kiosk-mode.
void setContentOwned(Component *newContentComponent, bool resizeToFitWhenContentChangesSize)
Changes the current content component.
void mouseDrag(const MouseEvent &) override
Called when the mouse is moved while a button is held down.
void clearContentComponent()
Removes the current content component.
void lookAndFeelChanged() override
Called to let the component react to a change in the look-and-feel setting.
@ backgroundColourId
A colour to use to fill the window's background.
void setBackgroundColour(Colour newColour)
Changes the colour currently being used for the window's background.
void visibilityChanged() override
Called when this component's visibility changes.
virtual BorderSize< int > getContentComponentBorder()
Returns the insets to use when positioning the content component.
void paint(Graphics &) override
Components can override this method to draw their content.
virtual BorderSize< int > getBorderThickness()
Returns the width of the frame to use around the window.
bool isFullScreen() const
Returns true if the window is currently in full-screen mode.
void activeWindowStatusChanged() override
This callback happens when this window becomes active or inactive.
void parentSizeChanged() override
Called when this component's immediate parent has been resized.
Colour getBackgroundColour() const noexcept
Returns the colour currently being used for the window's background.
void setConstrainer(ComponentBoundsConstrainer *newConstrainer)
Sets the bounds-constrainer object to use for resizing and dragging this window.
void moved() override
(if overriding this, make sure you call ResizableWindow::moved() in your subclass)
bool restoreWindowStateFromString(const String &previousState)
Restores the window to a previously-saved size and position.
void setContentNonOwned(Component *newContentComponent, bool resizeToFitWhenContentChangesSize)
Changes the current content component.
~ResizableWindow() override
Destructor.
void setContentComponentSize(int width, int height)
Changes the window so that the content component ends up with the specified size.
void childBoundsChanged(Component *) override
Called when one of this component's children is moved or resized.
void setMinimised(bool shouldMinimise)
Minimises the window, or restores it to its previous position and size.
void addToDesktop()
Adds the window to the desktop using the default flags.
A special array for holding a list of strings.
void removeEmptyStrings(bool removeWhitespaceStrings=true)
Removes empty strings from the array.
int size() const noexcept
Returns the number of strings in the array.
void trim()
Deletes any whitespace characters from the starts and ends of all the strings.
int addTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
Breaks up a string into tokens and adds them to this array.
The JUCE String class!
Definition juce_String.h:53
A base class for top-level windows.
void visibilityChanged() override
Called when this component's visibility changes.
bool isUsingNativeTitleBar() const noexcept
Returns true if the window is currently using an OS-native title bar.
#define jassert(expression)
Platform-independent assertion macro.
#define jassertfalse
This will always cause an assertion failure.
JUCE Namespace.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
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