26#define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN \
27 jassert ((MessageManager::getInstanceWithoutCreating() != nullptr \
28 && MessageManager::getInstanceWithoutCreating()->currentThreadHasLockedMessageManager()) \
29 || getPeer() == nullptr);
34static Component* findFirstEnabledAncestor (Component* in)
42 return findFirstEnabledAncestor (in->getParentComponent());
45Component* Component::currentlyFocusedComponent =
nullptr;
55 hierarchy.emplace_back (comp);
60 for (
auto& comp : hierarchy)
67 bool shouldBailOut()
const
69 return nearestNonNullParent() ==
nullptr;
74 auto* comp = nearestNonNullParent();
99 void addListener (
MouseListener* newListener,
bool wantsEventsForAllNestedChildComponents)
101 if (! listeners.contains (newListener))
103 if (wantsEventsForAllNestedChildComponents)
105 listeners.insert (0, newListener);
106 ++numDeepMouseListeners;
110 listeners.add (newListener);
117 auto index = listeners.indexOf (listenerToRemove);
121 if (index < numDeepMouseListeners)
122 --numDeepMouseListeners;
124 listeners.remove (index);
128 template <
typename EventMethod,
typename... Params>
129 static void sendMouseEvent (
HierarchyChecker& checker, EventMethod&& eventMethod, Params&&... params)
131 const auto callListeners = [&] (
auto& parentComp,
const auto findNumListeners)
133 if (
auto* list = parentComp.mouseListeners.get())
137 for (
int i = findNumListeners (*list); --i >= 0; i =
jmin (i, findNumListeners (*list)))
139 (list->listeners.getUnchecked (i)->*eventMethod) (checker.eventWithNearestParent(), params...);
141 if (checker.shouldBailOut() || safePointer ==
nullptr)
149 if (
auto* parent = checker.nearestNonNullParent())
150 if (! callListeners (*parent, [] (
auto& list) {
return list.listeners.size(); }))
153 if (
auto* parent = checker.nearestNonNullParent())
154 for (
Component* p = parent->parentComponent; p !=
nullptr; p = p->parentComponent)
155 if (! callListeners (*p, [] (
auto& list) {
return list.numDeepMouseListeners; }))
161 int numDeepMouseListeners = 0;
173 : componentName (name), componentFlags (0)
179 static_assert (
sizeof (flags) <=
sizeof (componentFlags),
"componentFlags has too many bits!");
183 while (childComponentList.size() > 0)
186 masterReference.
clear();
188 if (parentComponent !=
nullptr)
189 parentComponent->removeChildComponent (parentComponent->childComponentList.indexOf (
this),
true,
false);
191 giveAwayKeyboardFocusInternal (
isParentOf (currentlyFocusedComponent));
193 if (flags.hasHeavyweightPeerFlag)
197 jassert (childComponentList.size() == 0);
205 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
207 if (componentName != name)
209 componentName = name;
211 if (flags.hasHeavyweightPeerFlag)
213 peer->setTitle (name);
227 if (flags.visibleFlag != shouldBeVisible)
231 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
234 flags.visibleFlag = shouldBeVisible;
243 if (! shouldBeVisible)
245 detail::ComponentHelpers::releaseAllCachedImageResources (*
this);
249 if (parentComponent !=
nullptr)
250 parentComponent->grabKeyboardFocus();
257 if (safePointer !=
nullptr)
259 sendVisibilityChangeMessage();
261 if (safePointer !=
nullptr && flags.hasHeavyweightPeerFlag)
265 peer->setVisible (shouldBeVisible);
266 internalHierarchyChanged();
275void Component::sendVisibilityChangeMessage()
277 BailOutChecker checker (
this);
280 if (! checker.shouldBailOut())
286 if (! flags.visibleFlag)
289 if (parentComponent !=
nullptr)
290 return parentComponent->isShowing();
293 return ! peer->isMinimised();
302 return peer->getNativeHandle();
323 if (peer ==
nullptr || styleWanted != peer->getStyleFlags())
327 #if JUCE_LINUX || JUCE_BSD
335 const auto unscaledPosition = detail::ScalingHelpers::scaledScreenPosToUnscaled (
getScreenPosition());
336 const auto topLeft = detail::ScalingHelpers::unscaledScreenPosToScaled (*
this, unscaledPosition);
338 bool wasFullscreen =
false;
339 bool wasMinimised =
false;
342 int oldRenderingEngine = -1;
348 wasFullscreen = peer->isFullScreen();
349 wasMinimised = peer->isMinimised();
350 currentConstrainer = peer->getConstrainer();
351 oldNonFullScreenBounds = peer->getNonFullScreenBounds();
352 oldRenderingEngine = peer->getCurrentRenderingEngine();
354 flags.hasHeavyweightPeerFlag =
false;
356 internalHierarchyChanged();
358 if (safePointer ==
nullptr)
364 if (parentComponent !=
nullptr)
365 parentComponent->removeChildComponent (
this);
367 if (safePointer !=
nullptr)
369 flags.hasHeavyweightPeerFlag =
true;
371 peer = createNewPeer (styleWanted, nativeWindowToAttachTo);
375 boundsRelativeToParent.setPosition (topLeft);
376 peer->updateBounds();
378 if (oldRenderingEngine >= 0)
379 peer->setCurrentRenderingEngine (oldRenderingEngine);
390 peer->setFullScreen (
true);
391 peer->setNonFullScreenBounds (oldNonFullScreenBounds);
395 peer->setMinimised (
true);
399 peer->setAlwaysOnTop (
true);
402 peer->setConstrainer (currentConstrainer);
412 peer->performAnyPendingRepaintsNow();
415 internalHierarchyChanged();
418 detail::AccessibilityHelpers::notifyAccessibilityEvent (*handler, detail::AccessibilityHelpers::Event::windowOpened);
427 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
429 if (flags.hasHeavyweightPeerFlag)
432 detail::AccessibilityHelpers::notifyAccessibilityEvent (*handler, detail::AccessibilityHelpers::Event::windowClosed);
434 detail::ComponentHelpers::releaseAllCachedImageResources (*
this);
439 flags.hasHeavyweightPeerFlag =
false;
448 return flags.hasHeavyweightPeerFlag;
453 if (flags.hasHeavyweightPeerFlag)
456 if (parentComponent ==
nullptr)
459 return parentComponent->getPeer();
481 if (shouldBeOpaque != flags.opaqueFlag)
483 flags.opaqueFlag = shouldBeOpaque;
485 if (flags.hasHeavyweightPeerFlag)
495 return flags.opaqueFlag;
505 scale = g.getInternalContext().getPhysicalPixelScaleFactor();
507 auto imageBounds = compBounds * scale;
513 jmax (1, imageBounds.getWidth()),
514 jmax (1, imageBounds.getHeight()),
523 auto& lg = imG.getInternalContext();
527 for (
auto& i : validArea)
528 lg.excludeClipRectangle (i);
532 lg.setFill (Colours::transparentBlack);
533 lg.fillRect (compBounds,
true);
534 lg.setFill (Colours::black);
540 validArea = compBounds;
544 (
float) compBounds.getHeight() / (
float) imageBounds.getHeight()),
false);
562 if (cachedImage.get() != newCachedImage)
564 cachedImage.reset (newCachedImage);
577 if (shouldBeBuffered)
579 if (cachedImage ==
nullptr)
589void Component::reorderChildInternal (
int sourceIndex,
int destIndex)
591 if (sourceIndex != destIndex)
593 auto* c = childComponentList.getUnchecked (sourceIndex);
597 childComponentList.move (sourceIndex, destIndex);
600 internalChildrenChanged();
608 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
610 if (flags.hasHeavyweightPeerFlag)
614 peer->toFront (shouldGrabKeyboardFocus);
620 else if (parentComponent !=
nullptr)
622 auto& childList = parentComponent->childComponentList;
624 if (childList.getLast() !=
this)
626 auto index = childList.indexOf (
this);
630 int insertIndex = -1;
632 if (! flags.alwaysOnTopFlag)
634 insertIndex = childList.size() - 1;
636 while (insertIndex > 0 && childList.getUnchecked (insertIndex)->isAlwaysOnTop())
640 parentComponent->reorderChildInternal (index, insertIndex);
644 if (shouldGrabKeyboardFocus)
646 internalBroughtToFront();
656 if (other !=
nullptr && other !=
this)
659 jassert (parentComponent == other->parentComponent);
661 if (parentComponent !=
nullptr)
663 auto& childList = parentComponent->childComponentList;
664 auto index = childList.indexOf (
this);
666 if (index >= 0 && childList [index + 1] != other)
668 auto otherIndex = childList.indexOf (other);
672 if (index < otherIndex)
675 parentComponent->reorderChildInternal (index, otherIndex);
687 jassert (us !=
nullptr && them !=
nullptr);
689 if (us !=
nullptr && them !=
nullptr)
702 else if (parentComponent !=
nullptr)
704 auto& childList = parentComponent->childComponentList;
706 if (childList.getFirst() !=
this)
708 auto index = childList.indexOf (
this);
714 if (flags.alwaysOnTopFlag)
715 while (insertIndex < childList.size() && ! childList.getUnchecked (insertIndex)->isAlwaysOnTop())
718 parentComponent->reorderChildInternal (index, insertIndex);
726 if (shouldStayOnTop != flags.alwaysOnTopFlag)
730 flags.alwaysOnTopFlag = shouldStayOnTop;
736 if (! peer->setAlwaysOnTop (shouldStayOnTop))
740 auto oldFlags = peer->getStyleFlags();
751 internalHierarchyChanged();
757 return flags.alwaysOnTopFlag;
766 return parentComponent !=
nullptr ? parentComponent->getWidth()
772 return parentComponent !=
nullptr ? parentComponent->getHeight()
801 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
807 const bool wasMoved = (
getX() != x ||
getY() != y);
814 if (wasMoved || wasResized)
823 if (! flags.hasHeavyweightPeerFlag)
827 boundsRelativeToParent.setBounds (x, y, w, h);
833 else if (! flags.hasHeavyweightPeerFlag)
836 else if (cachedImage !=
nullptr)
838 cachedImage->invalidateAll();
841 flags.isMoveCallbackPending = wasMoved;
842 flags.isResizeCallbackPending = wasResized;
844 if (flags.hasHeavyweightPeerFlag)
846 peer->updateBounds();
848 sendMovedResizedMessagesIfPending();
852void Component::sendMovedResizedMessagesIfPending()
854 const bool wasMoved = flags.isMoveCallbackPending;
855 const bool wasResized = flags.isResizeCallbackPending;
857 if (wasMoved || wasResized)
859 flags.isMoveCallbackPending =
false;
860 flags.isResizeCallbackPending =
false;
862 sendMovedResizedMessages (wasMoved, wasResized);
866void Component::sendMovedResizedMessages (
bool wasMoved,
bool wasResized)
868 BailOutChecker checker (
this);
874 if (checker.shouldBailOut())
882 if (checker.shouldBailOut())
885 for (
int i = childComponentList.size(); --i >= 0;)
887 childComponentList.getUnchecked (i)->parentSizeChanged();
889 if (checker.shouldBailOut())
892 i =
jmin (i, childComponentList.size());
896 if (parentComponent !=
nullptr)
897 parentComponent->childBoundsChanged (
this);
899 if (! checker.shouldBailOut())
901 componentListeners.callChecked (checker, [
this, wasMoved, wasResized] (ComponentListener& l)
903 l.componentMovedOrResized (*
this, wasMoved, wasResized);
907 if ((wasMoved || wasResized) && ! checker.shouldBailOut())
909 detail::AccessibilityHelpers::notifyAccessibilityEvent (*handler, detail::AccessibilityHelpers::Event::elementMovedOrResized);
942 auto parentArea = detail::ComponentHelpers::getParentOrMainMonitorBounds (*
this)
945 setBounds (parentArea.getCentreX() - width / 2,
946 parentArea.getCentreY() - height / 2,
978 if (sourceRatio <= targetRatio)
986 if (! sourceArea.isEmpty())
999 if (affineTransform !=
nullptr)
1002 affineTransform.reset();
1004 sendMovedResizedMessages (
false,
false);
1007 else if (affineTransform ==
nullptr)
1012 sendMovedResizedMessages (
false,
false);
1014 else if (*affineTransform != newTransform)
1017 *affineTransform = newTransform;
1019 sendMovedResizedMessages (
false,
false);
1025 return affineTransform !=
nullptr;
1030 return affineTransform !=
nullptr ? *affineTransform :
AffineTransform();
1037 for (
auto* target = targetComponent; target !=
nullptr; target = target->
getParentComponent())
1039 transform = transform.followedBy (target->getTransform());
1041 if (target->isOnDesktop())
1042 transform = transform.scaled (target->getDesktopScaleFactor());
1045 auto transformScale =
std::sqrt (std::abs (transform.getDeterminant()));
1052 if (! flags.ignoresMouseClicksFlag)
1055 if (flags.allowChildMouseClicksFlag)
1057 for (
int i = childComponentList.size(); --i >= 0;)
1059 auto& child = *childComponentList.getUnchecked (i);
1061 if (child.isVisible()
1062 && detail::ComponentHelpers::hitTest (child, detail::ComponentHelpers::convertFromParentSpace (child,
Point<int> (x, y).toFloat())))
1071 bool allowClicksOnChildComponents)
noexcept
1073 flags.ignoresMouseClicksFlag = ! allowClicks;
1074 flags.allowChildMouseClicksFlag = allowClicksOnChildComponents;
1078 bool& allowsClicksOnChildComponents)
const noexcept
1080 allowsClicksOnThisComponent = ! flags.ignoresMouseClicksFlag;
1081 allowsClicksOnChildComponents = flags.allowChildMouseClicksFlag;
1091 if (detail::ComponentHelpers::hitTest (*
this, point))
1093 if (parentComponent !=
nullptr)
1094 return parentComponent->contains (detail::ComponentHelpers::convertToParentSpace (*
this, point));
1096 if (flags.hasHeavyweightPeerFlag)
1098 return peer->contains (detail::ComponentHelpers::localPositionToRawPeerPos (*
this, point).
roundToInt(),
true);
1115 auto* compAtPosition = top->getComponentAt (top->getLocalPoint (
this, point));
1117 return (compAtPosition ==
this) || (returnTrueIfWithinAChild &&
isParentOf (compAtPosition));
1127 if (flags.visibleFlag && detail::ComponentHelpers::hitTest (*
this, position))
1129 for (
int i = childComponentList.size(); --i >= 0;)
1131 auto* child = childComponentList.getUnchecked (i);
1133 child = child->
getComponentAt (detail::ComponentHelpers::convertFromParentSpace (*child, position));
1135 if (child !=
nullptr)
1155 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
1159 if (child.parentComponent !=
this)
1161 if (child.parentComponent !=
nullptr)
1166 child.parentComponent =
this;
1169 child.repaintParent();
1173 if (zOrder < 0 || zOrder > childComponentList.size())
1174 zOrder = childComponentList.size();
1178 if (! childComponentList.getUnchecked (zOrder - 1)->isAlwaysOnTop())
1185 childComponentList.insert (zOrder, &child);
1187 child.internalHierarchyChanged();
1188 internalChildrenChanged();
1200 if (child !=
nullptr)
1206 if (child !=
nullptr)
1212 if (child !=
nullptr)
1233 JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED_OR_OFFSCREEN
1235 if (
auto* child = childComponentList [index])
1237 sendParentEvents = sendParentEvents && child->isShowing();
1239 if (sendParentEvents)
1241 sendFakeMouseMove();
1243 if (child->isVisible())
1244 child->repaintParent();
1247 childComponentList.remove (index);
1248 child->parentComponent =
nullptr;
1250 detail::ComponentHelpers::releaseAllCachedImageResources (*child);
1253 if (child->hasKeyboardFocus (
true))
1255 const WeakReference<Component> safeThis (
this);
1257 child->giveAwayKeyboardFocusInternal (sendChildEvents || currentlyFocusedComponent != child);
1259 if (sendParentEvents)
1261 if (safeThis ==
nullptr)
1268 if (sendChildEvents)
1269 child->internalHierarchyChanged();
1271 if (sendParentEvents)
1272 internalChildrenChanged();
1283 while (! childComponentList.isEmpty())
1289 while (! childComponentList.isEmpty())
1295 return childComponentList.size();
1300 return childComponentList[index];
1305 return childComponentList.indexOf (
const_cast<Component*
> (child));
1310 for (
auto* c : childComponentList)
1311 if (c->componentID == targetID)
1321 while (comp->parentComponent !=
nullptr)
1322 comp = comp->parentComponent;
1329 while (possibleChild !=
nullptr)
1331 possibleChild = possibleChild->parentComponent;
1333 if (possibleChild ==
this)
1344void Component::internalChildrenChanged()
1346 if (componentListeners.isEmpty())
1352 BailOutChecker checker (
this);
1356 if (! checker.shouldBailOut())
1357 componentListeners.callChecked (checker, [
this] (ComponentListener& l) { l.componentChildrenChanged (*
this); });
1361void Component::internalHierarchyChanged()
1363 BailOutChecker checker (
this);
1367 if (checker.shouldBailOut())
1370 componentListeners.callChecked (checker, [
this] (ComponentListener& l) { l.componentParentHierarchyChanged (*
this); });
1372 if (checker.shouldBailOut())
1375 for (
int i = childComponentList.size(); --i >= 0;)
1377 childComponentList.getUnchecked (i)->internalHierarchyChanged();
1379 if (checker.shouldBailOut())
1387 i =
jmin (i, childComponentList.size());
1390 if (flags.hasHeavyweightPeerFlag)
1396#if JUCE_MODAL_LOOPS_PERMITTED
1397int Component::runModalLoop()
1409 return ModalComponentManager::getInstance()->runEventLoopForCurrentComponent();
1416 bool deleteWhenDismissed)
1429 detail::ComponentHelpers::sendMouseEventToComponentsThatAreBlockedByModal (*
this, &Component::internalMouseExit);
1431 if (safeReference ==
nullptr)
1438 auto& mcm = *ModalComponentManager::getInstance();
1439 mcm.startModal (
this, deleteWhenDismissed);
1440 mcm.attachCallback (
this, callback);
1444 if (shouldTakeKeyboardFocus)
1462 auto& mcm = *ModalComponentManager::getInstance();
1463 mcm.endModal (
this, returnValue);
1464 mcm.bringModalComponentsToFront();
1469 if (deletionChecker !=
nullptr)
1470 detail::ComponentHelpers::sendMouseEventToComponentsThatAreBlockedByModal (*deletionChecker, &Component::internalMouseEnter);
1476 if (target !=
nullptr)
1477 target->exitModalState (returnValue);
1485 auto& mcm = *ModalComponentManager::getInstance();
1487 return onlyConsiderForemostModalComponent ? mcm.isFrontModalComponent (
this)
1488 : mcm.isModal (
this);
1498 return ModalComponentManager::getInstance()->getNumModalComponents();
1503 return ModalComponentManager::getInstance()->getModalComponent (index);
1509 flags.bringToFrontOnClickFlag = shouldBeBroughtToFront;
1514 return flags.bringToFrontOnClickFlag;
1520 if (cursor != newCursor)
1524 if (flags.visibleFlag)
1542 flags.repaintOnMouseActivityFlag = shouldRepaint;
1548 return (255 - componentTransparency) / 255.0f;
1555 if (componentTransparency != newIntAlpha)
1557 componentTransparency = newIntAlpha;
1564 if (flags.hasHeavyweightPeerFlag)
1583 internalRepaint ({ x, y, w, h });
1588 internalRepaint (area);
1591void Component::repaintParent()
1593 if (parentComponent !=
nullptr)
1594 parentComponent->internalRepaint (detail::ComponentHelpers::convertToParentSpace (*
this,
getLocalBounds()));
1597void Component::internalRepaint (Rectangle<int> area)
1601 if (! area.isEmpty())
1602 internalRepaintUnchecked (area,
false);
1605void Component::internalRepaintUnchecked (Rectangle<int> area,
bool isEntireComponent)
1611 if (flags.visibleFlag)
1613 if (cachedImage !=
nullptr)
1614 if (! (isEntireComponent ? cachedImage->invalidateAll()
1615 : cachedImage->invalidate (area)))
1621 if (flags.hasHeavyweightPeerFlag)
1626 auto peerBounds = peer->getBounds();
1627 auto scaled = area * Point<float> ((
float) peerBounds.getWidth() / (
float)
getWidth(),
1628 (
float) peerBounds.getHeight() / (
float)
getHeight());
1630 peer->repaint (affineTransform !=
nullptr ? scaled.transformedBy (*affineTransform) : scaled);
1635 if (parentComponent !=
nullptr)
1636 parentComponent->internalRepaint (detail::ComponentHelpers::convertToParentSpace (*
this, area));
1655void Component::paintWithinParentContext (
Graphics& g)
1659 if (cachedImage !=
nullptr)
1660 cachedImage->paint (g);
1665void Component::paintComponentAndChildren (Graphics& g)
1667 auto clipBounds = g.getClipBounds();
1675 Graphics::ScopedSaveState ss (g);
1677 if (! (detail::ComponentHelpers::clipObscuredRegions (*
this, g, clipBounds, {}) && g.isClipEmpty()))
1681 for (
int i = 0; i < childComponentList.size(); ++i)
1683 auto& child = *childComponentList.getUnchecked (i);
1685 if (child.isVisible())
1687 if (child.affineTransform !=
nullptr)
1689 Graphics::ScopedSaveState ss (g);
1691 g.addTransform (*child.affineTransform);
1693 if ((child.flags.dontClipGraphicsFlag && ! g.isClipEmpty()) || g.reduceClipRegion (child.getBounds()))
1694 child.paintWithinParentContext (g);
1696 else if (clipBounds.intersects (child.getBounds()))
1698 Graphics::ScopedSaveState ss (g);
1700 if (child.flags.dontClipGraphicsFlag)
1702 child.paintWithinParentContext (g);
1704 else if (g.reduceClipRegion (child.getBounds()))
1706 bool nothingClipped =
true;
1708 for (
int j = i + 1; j < childComponentList.size(); ++j)
1710 auto& sibling = *childComponentList.getUnchecked (j);
1712 if (sibling.flags.opaqueFlag && sibling.isVisible() && sibling.affineTransform ==
nullptr)
1714 nothingClipped =
false;
1715 g.excludeClipRegion (sibling.getBounds());
1719 if (nothingClipped || ! g.isClipEmpty())
1720 child.paintWithinParentContext (g);
1726 Graphics::ScopedSaveState ss (g);
1736 if (! flags.isInsidePaintCall)
1738 sendMovedResizedMessagesIfPending();
1741 flags.isInsidePaintCall =
true;
1744 if (effect !=
nullptr)
1746 auto scale = g.getInternalContext().getPhysicalPixelScaleFactor();
1751 scaledBounds.getWidth(), scaledBounds.getHeight(), ! flags.opaqueFlag);
1755 (
float) scaledBounds.getHeight() / (
float)
getHeight()));
1756 paintComponentAndChildren (g2);
1762 effect->applyEffect (effectImage, g, scale, ignoreAlphaLevel ? 1.0f :
getAlpha());
1764 else if (componentTransparency > 0 && ! ignoreAlphaLevel)
1766 if (componentTransparency < 255)
1769 paintComponentAndChildren (g);
1775 paintComponentAndChildren (g);
1779 flags.isInsidePaintCall =
false;
1785 flags.dontClipGraphicsFlag = shouldPaintWithoutClipping;
1790 return flags.dontClipGraphicsFlag;
1795 bool clipImageToComponentBounds,
float scaleFactor)
1797 auto r = areaToGrab;
1799 if (clipImageToComponentBounds)
1805 auto w =
roundToInt (scaleFactor * (
float) r.getWidth());
1806 auto h =
roundToInt (scaleFactor * (
float) r.getHeight());
1814 (
float) h / (
float) r.getHeight()));
1815 g.setOrigin (-r.getPosition());
1824 if (effect != newEffect)
1834 for (
auto* c =
this; c !=
nullptr; c = c->parentComponent)
1835 if (
auto lf = c->lookAndFeel.get())
1843 if (lookAndFeel != newLookAndFeel)
1845 lookAndFeel = newLookAndFeel;
1859 if (safePointer !=
nullptr)
1863 if (safePointer !=
nullptr)
1865 for (
int i = childComponentList.size(); --i >= 0;)
1867 childComponentList.getUnchecked (i)->sendLookAndFeelChange();
1869 if (safePointer ==
nullptr)
1872 i =
jmin (i, childComponentList.size());
1880 if (
auto* v = properties.getVarPointer (detail::ComponentHelpers::getColourPropertyID (colourID)))
1883 if (inheritFromParent && parentComponent !=
nullptr
1884 && (lookAndFeel ==
nullptr || ! lookAndFeel->isColourSpecified (colourID)))
1885 return parentComponent->findColour (colourID,
true);
1892 return properties.contains (detail::ComponentHelpers::getColourPropertyID (colourID));
1897 if (properties.remove (detail::ComponentHelpers::getColourPropertyID (colourID)))
1903 if (properties.set (detail::ComponentHelpers::getColourPropertyID (colourID), (
int) colour.
getARGB()))
1909 bool changed =
false;
1911 for (
int i = properties.size(); --i >= 0;)
1913 auto name = properties.getName (i);
1915 if (name.toString().startsWith (detail::colourPropertyPrefix))
1916 if (target.properties.set (name, properties [name]))
1931 return positioner.get();
1938 positioner.reset (newPositioner);
1949 return affineTransform ==
nullptr ? boundsRelativeToParent
1973 enabledComponent->mouseMagnify (e.
getEventRelativeTo (enabledComponent), magnifyAmount);
1986 #if JUCE_DEBUG || JUCE_LOG_ASSERTIONS
1993 componentListeners.add (newListener);
1998 componentListeners.remove (listenerToRemove);
2004 ModalComponentManager::getInstance()->bringModalComponentsToFront();
2013void Component::internalModalInputAttempt()
2016 current->inputAttemptWhenModal();
2024 if (target !=
nullptr)
2025 target->handleCommandMessage (commandID);
2036 bool wantsEventsForAllNestedChildComponents)
2044 jassert ((newListener !=
this) || wantsEventsForAllNestedChildComponents);
2046 if (mouseListeners ==
nullptr)
2049 mouseListeners->addListener (newListener, wantsEventsForAllNestedChildComponents);
2058 if (mouseListeners !=
nullptr)
2059 mouseListeners->removeListener (listenerToRemove);
2072 if (flags.repaintOnMouseActivityFlag)
2075 const auto me = makeMouseEvent (source,
2076 detail::PointerState().withPosition (relativePos),
2086 HierarchyChecker checker (
this, me);
2089 flags.cachedMouseInsideComponent =
true;
2091 if (checker.shouldBailOut())
2094 Desktop::getInstance().getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseEnter (me); });
2098void Component::internalMouseExit (MouseInputSource source, Point<float> relativePos, Time time)
2107 if (flags.repaintOnMouseActivityFlag)
2110 flags.cachedMouseInsideComponent =
false;
2112 const auto me = makeMouseEvent (source,
2113 detail::PointerState().withPosition (relativePos),
2114 source.getCurrentModifiers(),
2123 HierarchyChecker checker (
this, me);
2126 if (checker.shouldBailOut())
2129 Desktop::getInstance().getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseExit (me); });
2133void Component::internalMouseDown (MouseInputSource source,
2134 const detail::PointerState& relativePointerState,
2139 const auto me = makeMouseEvent (source,
2140 relativePointerState,
2141 source.getCurrentModifiers(),
2145 relativePointerState.position,
2147 source.getNumberOfMultipleClicks(),
2150 HierarchyChecker checker (
this, me);
2154 flags.mouseDownWasBlocked =
true;
2155 internalModalInputAttempt();
2157 if (checker.shouldBailOut())
2165 desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseDown (checker.eventWithNearestParent()); });
2170 flags.mouseDownWasBlocked =
false;
2172 for (
auto* c =
this; c !=
nullptr; c = c->parentComponent)
2174 if (c->isBroughtToFrontOnMouseClick())
2178 if (checker.shouldBailOut())
2185 if (checker.shouldBailOut())
2188 if (flags.repaintOnMouseActivityFlag)
2193 if (checker.shouldBailOut())
2196 desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseDown (checker.eventWithNearestParent()); });
2201void Component::internalMouseUp (MouseInputSource source,
2202 const detail::PointerState& relativePointerState,
2204 const ModifierKeys oldModifiers)
2209 const auto me = makeMouseEvent (source,
2210 relativePointerState,
2216 source.getLastMouseDownTime(),
2217 source.getNumberOfMultipleClicks(),
2218 source.isLongPressOrDrag());
2220 HierarchyChecker checker (
this, me);
2222 if (flags.repaintOnMouseActivityFlag)
2227 if (checker.shouldBailOut())
2231 desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseUp (checker.eventWithNearestParent()); });
2235 if (checker.shouldBailOut())
2239 if (me.getNumberOfClicks() >= 2)
2241 if (checker.nearestNonNullParent() ==
this)
2244 if (checker.shouldBailOut())
2247 desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseDoubleClick (checker.eventWithNearestParent()); });
2252void Component::internalMouseDrag (MouseInputSource source,
const detail::PointerState& relativePointerState, Time time)
2256 const auto me = makeMouseEvent (source,
2257 relativePointerState,
2258 source.getCurrentModifiers(),
2263 source.getLastMouseDownTime(),
2264 source.getNumberOfMultipleClicks(),
2265 source.isLongPressOrDrag());
2267 HierarchyChecker checker (
this, me);
2271 if (checker.shouldBailOut())
2274 Desktop::getInstance().getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseDrag (checker.eventWithNearestParent()); });
2279void Component::internalMouseMove (MouseInputSource source, Point<float> relativePos, Time time)
2286 desktop.sendMouseMove();
2290 const auto me = makeMouseEvent (source,
2291 detail::PointerState().withPosition (relativePos),
2292 source.getCurrentModifiers(),
2301 HierarchyChecker checker (
this, me);
2305 if (checker.shouldBailOut())
2308 desktop.getMouseListeners().callChecked (checker, [&] (MouseListener& l) { l.mouseMove (checker.eventWithNearestParent()); });
2313void Component::internalMouseWheel (MouseInputSource source, Point<float> relativePos,
2314 Time time,
const MouseWheelDetails& wheel)
2318 const auto me = makeMouseEvent (source,
2319 detail::PointerState().withPosition (relativePos),
2320 source.getCurrentModifiers(),
2329 HierarchyChecker checker (
this, me);
2334 desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseWheelMove (me, wheel); });
2340 if (checker.shouldBailOut())
2343 desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseWheelMove (checker.eventWithNearestParent(), wheel); });
2345 if (! checker.shouldBailOut())
2350void Component::internalMagnifyGesture (MouseInputSource source, Point<float> relativePos,
2351 Time time,
float amount)
2355 const auto me = makeMouseEvent (source,
2356 detail::PointerState().withPosition (relativePos),
2357 source.getCurrentModifiers(),
2366 HierarchyChecker checker (
this, me);
2371 desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseMagnify (me, amount); });
2377 if (checker.shouldBailOut())
2380 desktop.mouseListeners.callChecked (checker, [&] (MouseListener& l) { l.mouseMagnify (checker.eventWithNearestParent(), amount); });
2382 if (! checker.shouldBailOut())
2387void Component::sendFakeMouseMove()
const
2389 if (flags.ignoresMouseClicksFlag && ! flags.allowChildMouseClicksFlag)
2394 if (! mainMouse.isDragging())
2408void Component::internalBroughtToFront()
2410 if (flags.hasHeavyweightPeerFlag)
2413 BailOutChecker checker (
this);
2416 if (checker.shouldBailOut())
2421 if (checker.shouldBailOut())
2428 ModalComponentManager::getInstance()->bringModalComponentsToFront (
false);
2439void Component::internalKeyboardFocusGain (FocusChangeType cause)
2444void Component::internalKeyboardFocusGain (FocusChangeType cause,
2445 const WeakReference<Component>& safePointer,
2446 FocusChangeDirection direction)
2451 if (safePointer ==
nullptr)
2456 handler->grabFocus();
2458 if (safePointer ==
nullptr)
2461 internalChildKeyboardFocusChange (cause, safePointer);
2464void Component::internalKeyboardFocusLoss (FocusChangeType cause)
2466 const WeakReference<Component> safePointer (
this);
2470 if (safePointer !=
nullptr)
2473 handler->giveAwayFocus();
2475 internalChildKeyboardFocusChange (cause, safePointer);
2479void Component::internalChildKeyboardFocusChange (FocusChangeType cause,
2480 const WeakReference<Component>& safePointer)
2484 if (flags.childKeyboardFocusedFlag != childIsNowKeyboardFocused)
2486 flags.childKeyboardFocusedFlag = childIsNowKeyboardFocused;
2490 if (safePointer ==
nullptr)
2494 if (parentComponent !=
nullptr)
2495 parentComponent->internalChildKeyboardFocusChange (cause, parentComponent);
2500 flags.wantsKeyboardFocusFlag = wantsFocus;
2505 flags.dontFocusOnMouseClickFlag = ! shouldGrabFocus;
2510 return ! flags.dontFocusOnMouseClickFlag;
2515 return flags.wantsKeyboardFocusFlag && ! flags.isDisabledFlag;
2520 flags.isFocusContainerFlag = (containerType == FocusContainerType::focusContainer
2521 || containerType == FocusContainerType::keyboardFocusContainer);
2523 flags.isKeyboardFocusContainerFlag = (containerType == FocusContainerType::keyboardFocusContainer);
2528 return flags.isFocusContainerFlag;
2533 return flags.isKeyboardFocusContainerFlag;
2536template <
typename FocusContainerFn>
2537static Component* findContainer (
const Component* child, FocusContainerFn isFocusContainer)
2541 if ((parent->*isFocusContainer)() || parent->getParentComponent() ==
nullptr)
2544 return findContainer (parent, isFocusContainer);
2560static const Identifier explicitFocusOrderId (
"_jexfo");
2564 return properties [explicitFocusOrderId];
2569 properties.set (explicitFocusOrderId, newFocusOrderIndex);
2574 if (flags.isFocusContainerFlag || parentComponent ==
nullptr)
2577 return parentComponent->createFocusTraverser();
2582 if (flags.isKeyboardFocusContainerFlag || parentComponent ==
nullptr)
2585 return parentComponent->createKeyboardFocusTraverser();
2588void Component::takeKeyboardFocus (FocusChangeType cause, FocusChangeDirection direction)
2590 if (currentlyFocusedComponent ==
this)
2598 if (! peer->isFocused() || currentlyFocusedComponent ==
this)
2603 if (
auto* losingFocus = componentLosingFocus.get())
2604 if (
auto* otherPeer = losingFocus->getPeer())
2605 otherPeer->closeInputMethodContext();
2607 currentlyFocusedComponent =
this;
2613 if (componentLosingFocus !=
nullptr)
2614 componentLosingFocus->internalKeyboardFocusLoss (cause);
2616 if (currentlyFocusedComponent ==
this)
2617 internalKeyboardFocusGain (cause, safePointer, direction);
2621void Component::grabKeyboardFocusInternal (FocusChangeType cause,
bool canTryParent, FocusChangeDirection direction)
2629 if (flags.wantsKeyboardFocusFlag
2630 && (
isEnabled() || parentComponent ==
nullptr))
2632 takeKeyboardFocus (cause, direction);
2636 if (
isParentOf (currentlyFocusedComponent) && currentlyFocusedComponent->isShowing())
2641 if (
auto* defaultComp = traverser->getDefaultComponent (
this))
2643 defaultComp->grabKeyboardFocusInternal (cause,
false, direction);
2650 if (canTryParent && parentComponent !=
nullptr)
2651 parentComponent->grabKeyboardFocusInternal (cause,
true, direction);
2669void Component::giveAwayKeyboardFocusInternal (
bool sendFocusLossEvent)
2673 if (
auto* componentLosingFocus = currentlyFocusedComponent)
2675 if (
auto* otherPeer = componentLosingFocus->getPeer())
2676 otherPeer->closeInputMethodContext();
2678 currentlyFocusedComponent =
nullptr;
2680 if (sendFocusLossEvent && componentLosingFocus !=
nullptr)
2694 giveAwayKeyboardFocusInternal (
true);
2703 if (parentComponent !=
nullptr)
2707 auto findComponentToFocus = [&]() ->
Component*
2709 if (
auto* comp = (moveToNext ? traverser->getNextComponent (
this)
2710 : traverser->getPreviousComponent (
this)))
2715 auto allFocusableComponents = traverser->getAllComponents (
focusContainer);
2717 if (! allFocusableComponents.empty())
2718 return moveToNext ? allFocusableComponents.front()
2719 : allFocusableComponents.back();
2725 if (
auto* nextComp = findComponentToFocus())
2727 if (nextComp->isCurrentlyBlockedByAnotherModalComponent())
2730 internalModalInputAttempt();
2732 if (nextCompPointer ==
nullptr || nextComp->isCurrentlyBlockedByAnotherModalComponent())
2738 moveToNext ? FocusChangeDirection::forward
2739 : FocusChangeDirection::backward);
2744 parentComponent->moveKeyboardFocusToSibling (moveToNext);
2750 return (currentlyFocusedComponent ==
this)
2751 || (trueIfChildIsFocused &&
isParentOf (currentlyFocusedComponent));
2756 return currentlyFocusedComponent;
2761 if (currentlyFocusedComponent !=
nullptr)
2768 return (! flags.isDisabledFlag)
2769 && (parentComponent ==
nullptr || parentComponent->isEnabled());
2774 if (flags.isDisabledFlag == shouldBeEnabled)
2776 flags.isDisabledFlag = ! shouldBeEnabled;
2780 if (parentComponent ==
nullptr || parentComponent->isEnabled())
2781 sendEnablementChangeMessage();
2784 componentListeners.callChecked (checker, [
this] (
ComponentListener& l) { l.componentEnablementChanged (*
this); });
2788 if (parentComponent !=
nullptr)
2789 parentComponent->grabKeyboardFocus();
2799void Component::sendEnablementChangeMessage()
2805 if (safePointer ==
nullptr)
2812 c->sendEnablementChangeMessage();
2814 if (safePointer ==
nullptr)
2824 return flags.cachedMouseInsideComponent;
2828 auto* c = ms.getComponentUnderMouse();
2830 if (c !=
nullptr && (c ==
this || (includeChildren &&
isParentOf (c))))
2831 if (ms.isDragging() || ! (ms.isTouch() || ms.isPen()))
2832 if (c->reallyContains (c->getLocalPoint (
nullptr, ms.getScreenPosition()),
false))
2843 auto* c = ms.getComponentUnderMouse();
2845 if (c ==
this || (includeChildren &&
isParentOf (c)))
2846 if (ms.isDragging())
2857 auto* c = ms.getComponentUnderMouse();
2859 if (c ==
this || (includeChildren &&
isParentOf (c)))
2860 if (ms.isDragging() || ! ms.isTouch())
2880 if (keyListeners ==
nullptr)
2883 keyListeners->addIfNotAlreadyThere (newListener);
2888 if (keyListeners !=
nullptr)
2889 keyListeners->removeFirstMatchingValue (listenerToRemove);
2897 if (parentComponent !=
nullptr)
2898 parentComponent->modifierKeysChanged (modifiers);
2901void Component::internalModifierKeysChanged()
2903 sendFakeMouseMove();
2909 : safePointer (component)
2911 jassert (component !=
nullptr);
2916 return safePointer ==
nullptr;
2922 componentTitle = newTitle;
2927 componentDescription = newDescription;
2932 componentHelpText = newHelpText;
2937 flags.accessibilityIgnoredFlag = ! shouldBeAccessible;
2939 if (flags.accessibilityIgnoredFlag)
2945 return (! flags.accessibilityIgnoredFlag
2946 && (parentComponent ==
nullptr || parentComponent->isAccessible()));
2961 accessibilityHandler =
nullptr;
2969 if (accessibilityHandler ==
nullptr
2970 || accessibilityHandler->getTypeIndex() !=
std::type_index (typeid (*
this)))
2981 if (accessibilityHandler !=
nullptr)
2982 detail::AccessibilityHelpers::notifyAccessibilityEvent (*accessibilityHandler, detail::AccessibilityHelpers::Event::elementCreated);
2987 return accessibilityHandler.get();
Base class for accessible Components.
Holds a resizable array of primitive or copy-by-value objects.
void clear()
Removes all elements from the array.
Specifies a set of gaps to be left around the sides of a rectangle.
Rectangle< ValueType > subtractedFrom(const Rectangle< ValueType > &original) const noexcept
Returns a rectangle with these borders removed from it.
Base class used internally for structures that can store cached images of component state.
Represents a colour, also including a transparency value.
uint32 getARGB() const noexcept
Returns a 32-bit integer that represents this colour.
A class that imposes restrictions on a Component's size or position.
Gets informed about changes to a component's hierarchy or position.
virtual void componentBroughtToFront(Component &component)
Called when the component is brought to the top of the z-order.
virtual void componentBeingDeleted(Component &component)
Called when the component is in the process of being deleted.
virtual void componentNameChanged(Component &component)
Called when the component's name is changed.
virtual void componentVisibilityChanged(Component &component)
Called when the component is made visible or invisible.
The Component class uses a ComponentPeer internally to create and manage a real operating-system wind...
@ windowIsSemiTransparent
Not intended for public use - makes a window transparent.
static ComponentPeer * getPeerFor(const Component *) noexcept
Returns the peer that's attached to the given component, or nullptr if there isn't one.
A class to keep an eye on a component and check for it being deleted.
bool shouldBailOut() const noexcept
Returns true if either of the two components have been deleted since this object was created.
BailOutChecker(Component *component)
Creates a checker that watches one component.
Base class for objects that can be used to automatically position a component according to some kind ...
Positioner(Component &component) noexcept
Creates a Positioner which can control the specified component.
Component & getComponent() const noexcept
Returns the component that this positioner controls.
Holds a pointer to some type of Component, which automatically becomes null if the component is delet...
The base class for all JUCE user-interface objects.
bool contains(Point< int > localPoint)
Returns true if a given point lies within this component or one of its children.
virtual void focusLost(FocusChangeType cause)
Called to indicate that this component has just lost the keyboard focus.
void moveKeyboardFocusToSibling(bool moveToNext)
Tries to move the keyboard focus to one of this component's siblings.
void mouseMagnify(const MouseEvent &event, float scaleFactor) override
Called when a pinch-to-zoom mouse-gesture is used.
bool isColourSpecified(int colourID) const
Returns true if the specified colour ID has been explicitly set for this component using the setColou...
void paintEntireComponent(Graphics &context, bool ignoreAlphaLevel)
Draws this component and all its subcomponents onto the specified graphics context.
int proportionOfWidth(float proportion) const noexcept
Returns a proportion of the component's width.
static int JUCE_CALLTYPE getNumCurrentlyModalComponents() noexcept
Returns the number of components that are currently in a modal state.
void setLookAndFeel(LookAndFeel *newLookAndFeel)
Sets the look and feel to use for this component.
Rectangle< int > getBoundsInParent() const noexcept
Returns the area of this component's parent which this component covers.
AffineTransform getTransform() const
Returns the transform that is currently being applied to this component.
void deleteAllChildren()
Removes and deletes all of this component's children.
Component * findChildWithID(StringRef componentID) const noexcept
Looks for a child component with the specified ID.
void mouseDrag(const MouseEvent &event) override
Called when the mouse is moved while a button is held down.
void setTransform(const AffineTransform &transform)
Sets a transform matrix to be applied to this component.
bool isMouseButtonDown(bool includeChildren=false) const
Returns true if the mouse button is currently held down in this component.
static void JUCE_CALLTYPE unfocusAllComponents()
If any component has keyboard focus, this will defocus it.
void removeComponentListener(ComponentListener *listenerToRemove)
Removes a component listener.
void setRepaintsOnMouseActivity(bool shouldRepaint) noexcept
Causes automatic repaints when the mouse enters or exits this component.
bool isAccessible() const noexcept
Returns true if this component and its children are visible to accessibility clients.
virtual void childBoundsChanged(Component *child)
Called when one of this component's children is moved or resized.
void copyAllExplicitColoursTo(Component &target) const
This looks for any colours that have been specified for this component, and copies them to the specif...
void setComponentID(const String &newID)
Sets the component's ID string.
Component * getTopLevelComponent() const noexcept
Returns the highest-level component which contains this one or its parents.
virtual void inputAttemptWhenModal()
Called when the user tries to click on a component that is blocked by another modal component.
virtual void paintOverChildren(Graphics &g)
Components can override this method to draw over the top of their children.
void mouseMove(const MouseEvent &event) override
Called when the mouse moves inside a component.
virtual std::unique_ptr< AccessibilityHandler > createAccessibilityHandler()
Override this method to return a custom AccessibilityHandler for this component.
static Component *JUCE_CALLTYPE getCurrentlyModalComponent(int index=0) noexcept
Returns one of the components that are currently modal.
void setBroughtToFrontOnMouseClick(bool shouldBeBroughtToFront) noexcept
Indicates whether the component should be brought to the front when clicked.
void giveAwayKeyboardFocus()
If this component or any of its children currently have the keyboard focus, this will defocus it,...
void toBehind(Component *other)
Changes this component's z-order so that it's just behind another component.
void setAccessible(bool shouldBeAccessible)
Sets whether this component and its children are visible to accessibility clients.
void setBoundsInset(BorderSize< int > borders)
Changes the component's position and size based on the amount of space to leave around it.
void setInterceptsMouseClicks(bool allowClicksOnThisComponent, bool allowClicksOnChildComponents) noexcept
Changes the default return value for the hitTest() method.
bool isMouseOverOrDragging(bool includeChildren=false) const
True if the mouse is over this component, or if it's being dragged in this component.
void setCentreRelative(float x, float y)
Changes the position of the component's centre.
static bool JUCE_CALLTYPE isMouseButtonDownAnywhere() noexcept
Returns true if a mouse button is currently down.
virtual MouseCursor getMouseCursor()
Returns the mouse cursor shape to use when the mouse is over this component.
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.
int getScreenY() const
Returns this component's y coordinate relative the screen's top-left origin.
Component * getParentComponent() const noexcept
Returns the component which this component is inside.
void * getWindowHandle() const
Returns the underlying native window handle for this component.
int getNumChildComponents() const noexcept
Returns the number of child components that this component contains.
virtual void childrenChanged()
Subclasses can use this callback to be told when children are added or removed, or when their z-order...
int proportionOfHeight(float proportion) const noexcept
Returns a proportion of the component's height.
void exitModalState(int returnValue=0)
Ends a component's modal state.
virtual void parentHierarchyChanged()
Called to indicate that the component's parents have changed.
Image createComponentSnapshot(Rectangle< int > areaToGrab, bool clipImageToComponentBounds=true, float scaleFactor=1.0f)
Generates a snapshot of part of this component.
int getScreenX() const
Returns this component's x coordinate relative the screen's top-left origin.
void setPositioner(Positioner *newPositioner)
Sets a new Positioner object for this component.
virtual void focusGained(FocusChangeType cause)
Called to indicate that this component has just acquired the keyboard focus.
void setTitle(const String &newTitle)
Sets the title for this component.
bool reallyContains(Point< int > localPoint, bool returnTrueIfWithinAChild)
Returns true if a given point lies in this component, taking any overlapping siblings into account.
int getIndexOfChildComponent(const Component *child) const noexcept
Returns the index of this component in the list of child components.
bool isAlwaysOnTop() const noexcept
Returns true if this component is set to always stay in front of its siblings.
bool isOpaque() const noexcept
Returns true if no parts of this component are transparent.
void setFocusContainerType(FocusContainerType containerType) noexcept
Sets whether this component is a container for components that can have their focus traversed,...
virtual void minimisationStateChanged(bool isNowMinimised)
Called for a desktop component which has just been minimised or un-minimised.
Point< int > getPosition() const noexcept
Returns the component's top-left position as a Point.
int getHeight() const noexcept
Returns the component's height in pixels.
void grabKeyboardFocus()
Tries to give keyboard focus to this component.
Component * findFocusContainer() const
Returns the focus container for this component.
Rectangle< int > getLocalArea(const Component *sourceComponent, Rectangle< int > areaRelativeToSourceComponent) const
Converts a rectangle to be relative to this component's coordinate space.
bool isTransformed() const noexcept
Returns true if a non-identity transform is being applied to this component.
virtual void userTriedToCloseWindow()
For components on the desktop, this is called if the system wants to close the window.
int getX() const noexcept
Returns the x coordinate of the component's left edge.
int getExplicitFocusOrder() const
Returns the focus order of this component, if one has been specified.
void toBack()
Changes this component's z-order to be at the back of all its siblings.
void toFront(bool shouldAlsoGainKeyboardFocus)
Brings the component to the front of its siblings.
Point< int > getLocalPoint(const Component *sourceComponent, Point< int > pointRelativeToSourceComponent) const
Converts a point to be relative to this component's coordinate space.
static Component *JUCE_CALLTYPE getCurrentlyFocusedComponent() noexcept
Returns the component that currently has the keyboard focus.
bool isShowing() const
Tests whether this component and all its parents are visible.
virtual std::unique_ptr< ComponentTraverser > createKeyboardFocusTraverser()
Creates a ComponentTraverser object to use to determine the logic by which keyboard focus should be p...
void sendLookAndFeelChange()
Calls the methods repaint(), lookAndFeelChanged(), and colourChanged() in this component and all its ...
virtual void focusGainedWithDirection(FocusChangeType cause, FocusChangeDirection direction)
Called to indicate that this component has just acquired the keyboard focus.
void setTopRightPosition(int x, int y)
Moves the component to a new position.
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 setAlpha(float newAlpha)
Changes the transparency of this component.
void addComponentListener(ComponentListener *newListener)
Adds a listener to be told about changes to the component hierarchy or position.
void mouseUp(const MouseEvent &event) override
Called when a mouse button is released.
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.
virtual bool canModalEventBeSentToComponent(const Component *targetComponent)
When a component is modal, this callback allows it to choose which other components can still receive...
FocusChangeType
Enumeration used by the focusGained() and focusLost() methods.
@ focusChangedByTabKey
Means that the user pressed the tab key to move the focus.
@ focusChangedDirectly
Means that the focus was changed by a call to grabKeyboardFocus().
@ focusChangedByMouseClick
Means that the user clicked the mouse to change focus.
void mouseExit(const MouseEvent &event) override
Called when the mouse moves out of a component.
void setPaintingIsUnclipped(bool shouldPaintWithoutClipping) noexcept
This allows you to indicate that this component doesn't require its graphics context to be clipped wh...
void setAlwaysOnTop(bool shouldStayOnTop)
Sets whether the component should always be kept at the front of its siblings.
Positioner * getPositioner() const noexcept
Returns the Positioner object that has been set for this component.
float getAlpha() const noexcept
Returns the component's current transparency level.
bool hasKeyboardFocus(bool trueIfChildIsFocused) const
Returns true if this component currently has the keyboard focus.
virtual void alphaChanged()
Called when setAlpha() is used to change the alpha value of this component.
bool isCurrentlyBlockedByAnotherModalComponent() const
Checks whether there's a modal component somewhere that's stopping this one from receiving messages.
void addMouseListener(MouseListener *newListener, bool wantsEventsForAllNestedChildComponents)
Registers a listener to be told when mouse events occur in this component.
void setDescription(const String &newDescription)
Sets the description for this component.
bool isBroughtToFrontOnMouseClick() const noexcept
Indicates whether the component should be brought to the front when clicked-on.
AccessibilityHandler * getAccessibilityHandler()
Returns the accessibility handler for this component, or nullptr if this component is not accessible.
void setOpaque(bool shouldBeOpaque)
Indicates whether any parts of the component might be transparent.
void setMouseCursor(const MouseCursor &cursorType)
Changes the mouse cursor shape to use when the mouse is over this component.
void setCentrePosition(int x, int y)
Changes the position of the component's centre.
void postCommandMessage(int commandId)
Dispatches a numbered message to this component.
virtual void enablementChanged()
Callback to indicate that this component has been enabled or disabled.
virtual void modifierKeysChanged(const ModifierKeys &modifiers)
Called when a modifier key is pressed or released.
void mouseEnter(const MouseEvent &event) override
Called when the mouse first enters a component.
void setEnabled(bool shouldBeEnabled)
Enables or disables this component.
Rectangle< int > getBounds() const noexcept
Returns this component's bounding box.
void repaint()
Marks the whole component as needing to be redrawn.
void addKeyListener(KeyListener *newListener)
Adds a listener that wants to hear about keypresses that this component receives.
Component() noexcept
Creates a component.
FocusContainerType
A focus container type that can be passed to setFocusContainerType().
@ focusContainer
The component will act as a top-level component within which focus is passed around.
Rectangle< int > getScreenBounds() const
Returns the bounds of this component, relative to the screen's top-left.
void getInterceptsMouseClicks(bool &allowsClicksOnThisComponent, bool &allowsClicksOnChildComponents) const noexcept
Retrieves the current state of the mouse-click interception flags.
Point< int > getMouseXYRelative() const
Returns the mouse's current position, relative to this component.
void removeMouseListener(MouseListener *listenerToRemove)
Deregisters a mouse listener.
bool isOnDesktop() const noexcept
Returns true if this component is currently showing on the desktop.
virtual bool hitTest(int x, int y)
Tests whether a given point is inside the component.
void setBoundsToFit(Rectangle< int > targetArea, Justification justification, bool onlyReduceInSize)
Positions the component within a given rectangle, keeping its proportions unchanged.
bool getMouseClickGrabsKeyboardFocus() const noexcept
Returns the last value set with setMouseClickGrabsKeyboardFocus().
virtual void resized()
Called when this component's size has been changed.
Rectangle< int > localAreaToGlobal(Rectangle< int > localArea) const
Converts a rectangle from this component's coordinate space to a screen coordinate.
bool isKeyboardFocusContainer() const noexcept
Returns true if this component has been marked as a keyboard focus container.
int getY() const noexcept
Returns the y coordinate of the top of this component.
virtual void setName(const String &newName)
Sets the name of this component.
void removeChildComponent(Component *childToRemove)
Removes one of this component's child-components.
Component * getChildComponent(int index) const noexcept
Returns one of this component's child components, by it index.
FocusChangeDirection
Enumeration used by the focusGainedWithDirection() method.
bool isParentOf(const Component *possibleChild) const noexcept
Checks whether a component is anywhere inside this component or its children.
void removeColour(int colourID)
If a colour has been set with setColour(), this will remove it.
void removeAllChildren()
Removes all this component's children.
virtual void addToDesktop(int windowStyleFlags, void *nativeWindowToAttachTo=nullptr)
Makes this component appear as a window on the desktop.
void setBufferedToImage(bool shouldBeBuffered)
Makes the component use an internal buffer to optimise its redrawing.
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.
virtual bool keyStateChanged(bool isKeyDown)
Called when a key is pressed or released.
void setColour(int colourID, Colour newColour)
Registers a colour to be used for a particular purpose.
void enterModalState(bool takeKeyboardFocus=true, ModalComponentManager::Callback *callback=nullptr, bool deleteWhenDismissed=false)
Puts the component into a modal state.
bool isPaintingUnclipped() const noexcept
Returns true if this component doesn't require its graphics context to be clipped when it is being pa...
void setWantsKeyboardFocus(bool wantsFocus) noexcept
Sets a flag to indicate whether this component wants keyboard focus or not.
Colour findColour(int colourID, bool inheritFromParent=false) const
Looks for a colour that has been registered with the given colour ID number.
bool isMouseOver(bool includeChildren=false) const
Returns true if the mouse is currently over this component.
void setMouseClickGrabsKeyboardFocus(bool shouldGrabFocus)
Chooses whether a click on this component automatically grabs the focus.
void mouseDoubleClick(const MouseEvent &event) override
Called when a mouse button has been double-clicked on a component.
virtual void parentSizeChanged()
Called when this component's immediate parent has been resized.
Rectangle< int > getParentMonitorArea() const
Returns the screen coordinates of the monitor that contains this component.
int getWidth() const noexcept
Returns the component's width in pixels.
~Component() override
Destructor.
void mouseWheelMove(const MouseEvent &event, const MouseWheelDetails &wheel) override
Called when the mouse-wheel is moved.
bool isFocusContainer() const noexcept
Returns true if this component has been marked as a focus container.
static void JUCE_CALLTYPE beginDragAutoRepeat(int millisecondsBetweenCallbacks)
Ensures that a non-stop stream of mouse-drag events will be sent during the current mouse-drag operat...
bool isEnabled() const noexcept
Returns true if the component (and all its parents) are enabled.
virtual std::unique_ptr< ComponentTraverser > createFocusTraverser()
Creates a ComponentTraverser object to determine the logic by which focus should be passed from this ...
Point< int > localPointToGlobal(Point< int > localPoint) const
Converts a point relative to this component's top-left into a screen coordinate.
bool getWantsKeyboardFocus() const noexcept
Returns true if the component is interested in getting keyboard focus.
void updateMouseCursor() const
Forces the current mouse cursor to be updated.
void addChildAndSetID(Component *child, const String &componentID)
Adds a child component to this one, makes it visible, and sets its component ID.
ComponentPeer * getPeer() const
Returns the heavyweight window that contains this component.
virtual void focusOfChildComponentChanged(FocusChangeType cause)
Called to indicate a change in whether or not this component is the parent of the currently-focused c...
LookAndFeel & getLookAndFeel() const noexcept
Finds the appropriate look-and-feel to use for this component.
virtual bool keyPressed(const KeyPress &key)
Called when a key is pressed.
void setExplicitFocusOrder(int newFocusOrderIndex)
Sets the focus order of this component.
void setHelpText(const String &newHelpText)
Sets the help text 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.
Point< int > getScreenPosition() const
Returns the position of this component's top-left corner relative to the screen's top-left.
void setComponentEffect(ImageEffectFilter *newEffect)
Adds an effect filter to alter the component's appearance.
void setTopLeftPosition(int x, int y)
Moves the component to a new position.
virtual void broughtToFront()
Called when this component has been moved to the front of its siblings.
void centreWithSize(int width, int height)
Changes the component's size and centres it within its parent.
virtual void lookAndFeelChanged()
Called to let the component react to a change in the look-and-feel setting.
virtual void colourChanged()
This method is called when a colour is changed by the setColour() method, or when the look-and-feel i...
Component * findKeyboardFocusContainer() const
Returns the keyboard focus container for this component.
void addChildComponent(Component *child, int zOrder=-1)
Adds a child component to this one.
virtual void paint(Graphics &g)
Components can override this method to draw their content.
bool isCurrentlyModal(bool onlyConsiderForemostModalComponent=true) const noexcept
Returns true if this component is the modal one.
void mouseDown(const MouseEvent &event) override
Called when a mouse button is pressed.
virtual void setVisible(bool shouldBeVisible)
Makes the component visible or invisible.
void invalidateAccessibilityHandler()
Invalidates the AccessibilityHandler that is currently being used for this component.
virtual void visibilityChanged()
Called when this component's visibility changes.
void removeKeyListener(KeyListener *listenerToRemove)
Removes a previously-registered key listener.
Component * getComponentAt(int x, int y)
Returns the component at a certain point within this one.
virtual float getDesktopScaleFactor() const
Returns the default scale factor to use for this component when it is placed on the desktop.
int getParentHeight() const noexcept
Returns the height of the component's parent.
void setCachedComponentImage(CachedComponentImage *newCachedImage)
Gives the component a CachedComponentImage that should be used to buffer its painting.
virtual void moved()
Called when this component's position has been changed.
void setBoundsRelative(float proportionalX, float proportionalY, float proportionalWidth, float proportionalHeight)
Changes the component's position and size in terms of fractions of its parent's size.
virtual void handleCommandMessage(int commandId)
Called to handle a command that was sent by postCommandMessage().
float getGlobalScaleFactor() const noexcept
Returns the current global scale factor, as set by setGlobalScaleFactor().
const Displays & getDisplays() const noexcept
Returns the Displays object representing the connected displays.
MouseInputSource getMainMouseSource() const noexcept
Returns the main mouse input device that the system is using.
void beginDragAutoRepeat(int millisecondsBetweenCallbacks)
Ensures that a non-stop stream of mouse-drag events will be sent during the current mouse-drag operat...
static Desktop &JUCE_CALLTYPE getInstance()
There's only one desktop object, and this method will return it.
const Array< MouseInputSource > & getMouseSources() const noexcept
Provides access to the array of mouse sources, for iteration.
Rectangle< int > userArea
The total area of this display in logical pixels which isn't covered by OS-dependent objects like the...
const Display * getDisplayForRect(Rectangle< int > rect, bool isPhysical=false) const noexcept
Returns the Display object representing the display containing a given Rectangle (either in logical o...
Uses RAII to save and restore the state of a graphics context.
A graphics context, used for drawing a component or image.
void endTransparencyLayer()
Completes a drawing operation to a temporary semi-transparent buffer.
void drawImageTransformed(const Image &imageToDraw, const AffineTransform &transform, bool fillAlphaChannelWithCurrentBrush=false) const
Draws an image, having applied an affine transform to it.
void addTransform(const AffineTransform &transform)
Adds a transformation which will be performed on all the graphics operations that the context subsequ...
void beginTransparencyLayer(float layerOpacity)
Begins rendering to an off-screen bitmap which will later be flattened onto the current context with ...
void setColour(Colour newColour)
Changes the current drawing colour.
void setOrigin(Point< int > newOrigin)
Moves the position of the context's origin.
Represents a string identifier, designed for accessing properties by name.
A graphical effect filter that can be applied to components.
Holds a fixed-size bitmap.
Rectangle< int > getBounds() const noexcept
Returns a rectangle with the same size as this image.
bool isNull() const noexcept
Returns true if this image is not valid.
@ ARGB
< each pixel is a 4-byte ARGB premultiplied colour value.
@ RGB
< each pixel is a 3-byte packed RGB colour value.
Represents a type of justification to be used when positioning graphical items.
const Rectangle< ValueType > appliedToRectangle(const Rectangle< ValueType > &areaToAdjust, const Rectangle< ValueType > &targetSpace) const noexcept
Returns the new position of a rectangle that has been justified to fit within a given space.
Receives callbacks when keys are pressed.
Represents a key press, including any modifier keys that are needed.
LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses can be used to appl...
static LookAndFeel & getDefaultLookAndFeel() noexcept
Returns the current default look-and-feel for a component to use when it hasn't got one explicitly se...
virtual void playAlertSound()
Plays the system's default 'beep' noise, to alert the user about something very important.
Colour findColour(int colourId) const noexcept
Looks for a colour that has been registered with the given colour ID number.
static bool callAsync(std::function< void()> functionToCall)
Asynchronously invokes a function or C++11 lambda on the message thread.
void * callFunctionOnMessageThread(MessageCallbackFunction *callback, void *userData)
Calls a function using the message-thread.
static MessageManager * getInstance()
Returns the global instance of the MessageManager.
Receives callbacks when a modal component is dismissed.
Represents the state of the mouse buttons and modifier keys.
static ModifierKeys currentModifiers
This object represents the last-known state of the keyboard and mouse buttons.
bool isAnyMouseButtonDown() const noexcept
Tests for any of the mouse-button flags.
Represents a mouse cursor image.
@ NormalCursor
The standard arrow cursor.
Contains position and status information about a mouse event.
const float tiltY
The tilt of the pen device along the y-axis between -1.0 and 1.0.
const Point< float > mouseDownPosition
The coordinates of the last place that a mouse button was pressed.
const ModifierKeys mods
The key modifiers associated with the event.
MouseInputSource source
The source device that generated this event.
const Time mouseDownTime
The time that the corresponding mouse-down event occurred.
MouseEvent getEventRelativeTo(Component *newComponent) const noexcept
Creates a version of this event that is relative to a different component.
const float orientation
The orientation of the touch input for this event in radians where 0 indicates a touch aligned with t...
const float pressure
The pressure of the touch or stylus for this event.
const Point< float > position
The position of the mouse when the event occurred.
bool mouseWasDraggedSinceMouseDown() const noexcept
Returns true if the user seems to be performing a drag gesture.
const float rotation
The rotation of the pen device for this event in radians.
const Time eventTime
The time that this mouse-event occurred.
int getNumberOfClicks() const noexcept
For a click event, the number of times the mouse was clicked in succession.
const float tiltX
The tilt of the pen device along the x-axis between -1.0 and 1.0.
A MouseListener can be registered with a component to receive callbacks about mouse events that happe...
virtual void mouseEnter(const MouseEvent &event)
Called when the mouse first enters a component.
virtual void mouseMagnify(const MouseEvent &event, float scaleFactor)
Called when a pinch-to-zoom mouse-gesture is used.
virtual void mouseMove(const MouseEvent &event)
Called when the mouse moves inside a component.
virtual void mouseUp(const MouseEvent &event)
Called when a mouse button is released.
virtual void mouseDrag(const MouseEvent &event)
Called when the mouse is moved while a button is held down.
virtual void mouseDoubleClick(const MouseEvent &event)
Called when a mouse button has been double-clicked on a component.
virtual void mouseDown(const MouseEvent &event)
Called when a mouse button is pressed.
virtual void mouseExit(const MouseEvent &event)
Called when the mouse moves out of a component.
virtual void mouseWheelMove(const MouseEvent &event, const MouseWheelDetails &wheel)
Called when the mouse-wheel is moved.
A pair of (x, y) coordinates.
constexpr Point< float > toFloat() const noexcept
Casts this point to a Point<float> object.
constexpr Point< int > roundToInt() const noexcept
Casts this point to a Point<int> object using roundToInt() to convert the values.
ValueType y
The point's Y coordinate.
Point transformedBy(const AffineTransform &transform) const noexcept
Returns the position of this point, if it is transformed by a given AffineTransform.
ValueType x
The point's X coordinate.
Maintains a set of rectangles as a complex region.
void clear()
Removes all rectangles to leave an empty region.
bool containsRectangle(RectangleType rectangleToCheck) const
Checks whether the region contains the whole of a given rectangle.
void subtract(const RectangleType rect)
Removes a rectangular region from the list.
Manages a rectangle and allows geometric operations to be performed on it.
ValueType getX() const noexcept
Returns the x coordinate of the rectangle's left-hand-side.
Rectangle getIntersection(Rectangle other) const noexcept
Returns the region that is the overlap between this and another rectangle.
ValueType getWidth() const noexcept
Returns the width of the rectangle.
ValueType getY() const noexcept
Returns the y coordinate of the rectangle's top edge.
bool isEmpty() const noexcept
Returns true if the rectangle's width or height are zero or less.
Rectangle withZeroOrigin() const noexcept
Returns a rectangle whose size is the same as this one, but whose top-left position is (0,...
Rectangle transformedBy(const AffineTransform &transform) const noexcept
Returns the smallest rectangle that can contain the shape created by applying a transform to this rec...
ValueType getHeight() const noexcept
Returns the height of the rectangle.
A simple class for holding temporary references to a string literal or String.
Holds an absolute date and time.
This class acts as a pointer which will automatically become null if the object to which it points is...
#define JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED
This macro is used to catch unsafe use of functions which expect to only be called on the message thr...
int pointer_sized_int
A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
@ structureChanged
Indicates that the structure of the UI elements has changed in a significant way.
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
Contains status information about a mouse wheel event.
bool invalidate(const Rectangle< int > &area) override
Invalidates a section of the cached image data.
void releaseResources() override
Called to indicate that the component is no longer active, so any cached data should be released if p...
bool invalidateAll() override
Invalidates all cached image data.
void paint(Graphics &g) override
Called as part of the parent component's paint method, this must draw the given component into the ta...