diff --git a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h index dc3f4ace31..45a148b221 100644 --- a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h +++ b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h @@ -376,9 +376,10 @@ public: if (undoManager != nullptr) undoManager->beginNewTransaction(); - CallOutBox::launchAsynchronously (*this, new PopupColourSelector (colourValue, - defaultColour, - canResetToDefault), nullptr); + CallOutBox::launchAsynchronously (new PopupColourSelector (colourValue, + defaultColour, + canResetToDefault), + getScreenBounds(), nullptr); } void valueChanged (Value&) diff --git a/extras/JuceDemo/Source/demos/WidgetsDemo.cpp b/extras/JuceDemo/Source/demos/WidgetsDemo.cpp index fdb8c21c83..1e2eb7d903 100644 --- a/extras/JuceDemo/Source/demos/WidgetsDemo.cpp +++ b/extras/JuceDemo/Source/demos/WidgetsDemo.cpp @@ -242,7 +242,7 @@ public: colourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); colourSelector->setSize (300, 400); - CallOutBox::launchAsynchronously (*this, colourSelector, nullptr); + CallOutBox::launchAsynchronously (colourSelector, getScreenBounds(), nullptr); } void changeListenerCallback (ChangeBroadcaster* source) diff --git a/modules/juce_gui_basics/windows/juce_CallOutBox.cpp b/modules/juce_gui_basics/windows/juce_CallOutBox.cpp index aeb415aa14..9c21d1eaad 100644 --- a/modules/juce_gui_basics/windows/juce_CallOutBox.cpp +++ b/modules/juce_gui_basics/windows/juce_CallOutBox.cpp @@ -23,20 +23,15 @@ ============================================================================== */ -CallOutBox::CallOutBox (Component& contentComponent, - Component& componentToPointTo, - Component* const parent) - : borderSpace (20), arrowSize (16.0f), content (contentComponent) +CallOutBox::CallOutBox (Component& c, const Rectangle& area, Component* const parent) + : borderSpace (20), arrowSize (16.0f), content (c) { addAndMakeVisible (&content); if (parent != nullptr) { parent->addChildComponent (this); - - updatePosition (parent->getLocalArea (&componentToPointTo, componentToPointTo.getLocalBounds()), - parent->getLocalBounds()); - + updatePosition (area, parent->getLocalBounds()); setVisible (true); } else @@ -44,8 +39,8 @@ CallOutBox::CallOutBox (Component& contentComponent, if (! JUCEApplication::isStandaloneApp()) setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level - updatePosition (componentToPointTo.getScreenBounds(), - componentToPointTo.getParentMonitorArea()); + updatePosition (area, Desktop::getInstance().getDisplays() + .getDisplayContaining (area.getCentre()).userArea); addToDesktop (ComponentPeer::windowIsTemporary); } @@ -59,8 +54,8 @@ CallOutBox::~CallOutBox() class CallOutBoxCallback : public ModalComponentManager::Callback { public: - CallOutBoxCallback (Component& attachTo, Component* content_, Component* parentComponent) - : content (content_), callout (*content_, attachTo, parentComponent) + CallOutBoxCallback (Component* c, const Rectangle& area, Component* parent) + : content (c), callout (*c, area, parent) { callout.setVisible (true); callout.enterModalState (true, this); @@ -68,20 +63,19 @@ public: void modalStateFinished (int) {} -private: ScopedPointer content; CallOutBox callout; JUCE_DECLARE_NON_COPYABLE (CallOutBoxCallback); }; -void CallOutBox::launchAsynchronously (Component& componentToPointTo, - Component* contentComponent, - Component* parentComponent) +CallOutBox& CallOutBox::launchAsynchronously (Component* content, + const Rectangle& area, + Component* parent) { - jassert (contentComponent != nullptr); // must be a valid content component! + jassert (content != nullptr); // must be a valid content component! - new CallOutBoxCallback (componentToPointTo, contentComponent, parentComponent); + return (new CallOutBoxCallback (content, area, parent))->callout; } //============================================================================== @@ -185,6 +179,7 @@ void CallOutBox::updatePosition (const Rectangle& newAreaToPointTo, const R Line (targets[3].translated (-hwReduced, -(hh - arrowIndent)), targets[3].translated (hwReduced, -(hh - arrowIndent))) }; const Rectangle centrePointArea (newAreaToFitIn.reduced (hw, hh).toFloat()); + const Point targetCentre (targetArea.getCentre().toFloat()); float nearest = 1.0e9f; @@ -193,19 +188,19 @@ void CallOutBox::updatePosition (const Rectangle& newAreaToPointTo, const R Line constrainedLine (centrePointArea.getConstrainedPoint (lines[i].getStart()), centrePointArea.getConstrainedPoint (lines[i].getEnd())); - const Point centre (constrainedLine.findNearestPointTo (centrePointArea.getCentre())); - float distanceFromCentre = centre.getDistanceFrom (centrePointArea.getCentre()); + const Point centre (constrainedLine.findNearestPointTo (targetCentre)); + float distanceFromCentre = centre.getDistanceFrom (targets[i]); if (! (centrePointArea.contains (lines[i].getStart()) || centrePointArea.contains (lines[i].getEnd()))) - distanceFromCentre *= 2.0f; + distanceFromCentre *= 50.0f; if (distanceFromCentre < nearest) { nearest = distanceFromCentre; targetPoint = targets[i]; - newBounds.setPosition ((int) (centre.getX() - hw), - (int) (centre.getY() - hh)); + newBounds.setPosition ((int) (centre.x - hw), + (int) (centre.y - hh)); } } diff --git a/modules/juce_gui_basics/windows/juce_CallOutBox.h b/modules/juce_gui_basics/windows/juce_CallOutBox.h index b4bc6be0d3..ce4cb5c31d 100644 --- a/modules/juce_gui_basics/windows/juce_CallOutBox.h +++ b/modules/juce_gui_basics/windows/juce_CallOutBox.h @@ -64,12 +64,14 @@ public: update itself when the component's size is changed later). Obviously this component must not be deleted until the call-out box has been deleted. - @param componentToPointTo the component that the call-out's arrow should point towards + @param areaToPointTo the area that the call-out's arrow should point towards. If + a parentComponent is supplied, then this is relative to that + parent; otherwise, it's a global screen coord. @param parentComponent if non-zero, this is the component to add the call-out to. If - this is zero, the call-out will be added to the desktop. + this is a nullptr, the call-out will be added to the desktop. */ CallOutBox (Component& contentComponent, - Component& componentToPointTo, + const Rectangle& areaToPointTo, Component* parentComponent); /** Destructor. */ @@ -98,15 +100,20 @@ public: the box will continue to run modally until the user clicks on some other component, at which point it will be dismissed automatically. - The content component that is passed-in will be owned by the callout, which will - delete it when it is dismissed. - - The parentComponent parameter can be a nullptr if you want the window to appear on - the desktop. + @param contentComponent the component to display inside the call-out. This should + already have a size set (although the call-out will also + update itself when the component's size is changed later). + This copmonent will be owned by the callout box and deleted + later when the box is dismissed. + @param areaToPointTo the area that the call-out's arrow should point towards. If + a parentComponent is supplied, then this is relative to that + parent; otherwise, it's a global screen coord. + @param parentComponent if non-zero, this is the component to add the call-out to. If + this is a nullptr, the call-out will be added to the desktop. */ - static void launchAsynchronously (Component& componentToPointTo, - Component* contentComponent, - Component* parentComponent); + static CallOutBox& launchAsynchronously (Component* contentComponent, + const Rectangle& areaToPointTo, + Component* parentComponent); //============================================================================== /** @internal */