| @@ -213,6 +213,7 @@ OBJECTS := \ | |||
| $(OBJDIR)/juce_PreferencesPanel_dbc7d503.o \ | |||
| $(OBJDIR)/juce_SystemTrayIconComponent_fa664512.o \ | |||
| $(OBJDIR)/juce_AlertWindow_94d8d1f5.o \ | |||
| $(OBJDIR)/juce_CallOutBox_61f42d7c.o \ | |||
| $(OBJDIR)/juce_ComponentPeer_1e4b4b08.o \ | |||
| $(OBJDIR)/juce_DialogWindow_535b27b9.o \ | |||
| $(OBJDIR)/juce_DocumentWindow_3cb9d4cc.o \ | |||
| @@ -1222,6 +1223,11 @@ $(OBJDIR)/juce_AlertWindow_94d8d1f5.o: ../../src/gui/components/windows/juce_Ale | |||
| @echo "Compiling juce_AlertWindow.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_CallOutBox_61f42d7c.o: ../../src/gui/components/windows/juce_CallOutBox.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_CallOutBox.cpp" | |||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
| $(OBJDIR)/juce_ComponentPeer_1e4b4b08.o: ../../src/gui/components/windows/juce_ComponentPeer.cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling juce_ComponentPeer.cpp" | |||
| @@ -182,6 +182,7 @@ | |||
| D9AAB4AE220010CD526C87D2 = { isa = PBXBuildFile; fileRef = A34C0E63D41CFF5E55FD1D9E; }; | |||
| C732ADB05901619B14F1D6BB = { isa = PBXBuildFile; fileRef = CC04F253CB70B20B774801A9; }; | |||
| 075D5995E41FDD670ED35E17 = { isa = PBXBuildFile; fileRef = A5AAF4475138358F33D4904A; }; | |||
| BBE02E8719411C8A7D43A401 = { isa = PBXBuildFile; fileRef = 8AEF18EE9B12D4677F96B709; }; | |||
| 35E3B9684ED968BAC0BC8021 = { isa = PBXBuildFile; fileRef = 2FFDC7636EFC2D7F74590A31; }; | |||
| 736AC4A9DA6515B92644FA02 = { isa = PBXBuildFile; fileRef = 929FEA5458430B7AE23BBB46; }; | |||
| DFFBADCBC9C7E31B391BA560 = { isa = PBXBuildFile; fileRef = 090907E4FE95EE2B11C1A0E1; }; | |||
| @@ -736,6 +737,8 @@ | |||
| 740D1808DB934123F05A1598 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_WebBrowserComponent.h; path = ../../src/gui/components/special/juce_WebBrowserComponent.h; sourceTree = SOURCE_ROOT; }; | |||
| A5AAF4475138358F33D4904A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AlertWindow.cpp; path = ../../src/gui/components/windows/juce_AlertWindow.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 72C4FDDDB8602591DD4F7B3B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AlertWindow.h; path = ../../src/gui/components/windows/juce_AlertWindow.h; sourceTree = SOURCE_ROOT; }; | |||
| 8AEF18EE9B12D4677F96B709 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CallOutBox.cpp; path = ../../src/gui/components/windows/juce_CallOutBox.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 8F54431CD3A672B1EB8335BE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CallOutBox.h; path = ../../src/gui/components/windows/juce_CallOutBox.h; sourceTree = SOURCE_ROOT; }; | |||
| 2FFDC7636EFC2D7F74590A31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ComponentPeer.cpp; path = ../../src/gui/components/windows/juce_ComponentPeer.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 12C66C90F3192AFFD6BCEDB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentPeer.h; path = ../../src/gui/components/windows/juce_ComponentPeer.h; sourceTree = SOURCE_ROOT; }; | |||
| 929FEA5458430B7AE23BBB46 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DialogWindow.cpp; path = ../../src/gui/components/windows/juce_DialogWindow.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1427,6 +1430,8 @@ | |||
| 48D41BA310DED74E900A5AB0 = { isa = PBXGroup; children = ( | |||
| A5AAF4475138358F33D4904A, | |||
| 72C4FDDDB8602591DD4F7B3B, | |||
| 8AEF18EE9B12D4677F96B709, | |||
| 8F54431CD3A672B1EB8335BE, | |||
| 2FFDC7636EFC2D7F74590A31, | |||
| 12C66C90F3192AFFD6BCEDB6, | |||
| 929FEA5458430B7AE23BBB46, | |||
| @@ -2011,6 +2016,7 @@ | |||
| D9AAB4AE220010CD526C87D2, | |||
| C732ADB05901619B14F1D6BB, | |||
| 075D5995E41FDD670ED35E17, | |||
| BBE02E8719411C8A7D43A401, | |||
| 35E3B9684ED968BAC0BC8021, | |||
| 736AC4A9DA6515B92644FA02, | |||
| DFFBADCBC9C7E31B391BA560, | |||
| @@ -559,6 +559,8 @@ | |||
| <Filter Name="windows"> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_AlertWindow.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_AlertWindow.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_CallOutBox.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_CallOutBox.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_ComponentPeer.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_ComponentPeer.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_DialogWindow.cpp"/> | |||
| @@ -559,6 +559,8 @@ | |||
| <Filter Name="windows"> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_AlertWindow.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_AlertWindow.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_CallOutBox.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_CallOutBox.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_ComponentPeer.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_ComponentPeer.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_DialogWindow.cpp"/> | |||
| @@ -561,6 +561,8 @@ | |||
| <Filter Name="windows"> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_AlertWindow.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_AlertWindow.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_CallOutBox.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_CallOutBox.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_ComponentPeer.cpp"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_ComponentPeer.h"/> | |||
| <File RelativePath="..\..\src\gui\components\windows\juce_DialogWindow.cpp"/> | |||
| @@ -182,6 +182,7 @@ | |||
| D9AAB4AE220010CD526C87D2 = { isa = PBXBuildFile; fileRef = A34C0E63D41CFF5E55FD1D9E; }; | |||
| C732ADB05901619B14F1D6BB = { isa = PBXBuildFile; fileRef = CC04F253CB70B20B774801A9; }; | |||
| 075D5995E41FDD670ED35E17 = { isa = PBXBuildFile; fileRef = A5AAF4475138358F33D4904A; }; | |||
| BBE02E8719411C8A7D43A401 = { isa = PBXBuildFile; fileRef = 8AEF18EE9B12D4677F96B709; }; | |||
| 35E3B9684ED968BAC0BC8021 = { isa = PBXBuildFile; fileRef = 2FFDC7636EFC2D7F74590A31; }; | |||
| 736AC4A9DA6515B92644FA02 = { isa = PBXBuildFile; fileRef = 929FEA5458430B7AE23BBB46; }; | |||
| DFFBADCBC9C7E31B391BA560 = { isa = PBXBuildFile; fileRef = 090907E4FE95EE2B11C1A0E1; }; | |||
| @@ -736,6 +737,8 @@ | |||
| 740D1808DB934123F05A1598 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_WebBrowserComponent.h; path = ../../src/gui/components/special/juce_WebBrowserComponent.h; sourceTree = SOURCE_ROOT; }; | |||
| A5AAF4475138358F33D4904A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AlertWindow.cpp; path = ../../src/gui/components/windows/juce_AlertWindow.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 72C4FDDDB8602591DD4F7B3B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_AlertWindow.h; path = ../../src/gui/components/windows/juce_AlertWindow.h; sourceTree = SOURCE_ROOT; }; | |||
| 8AEF18EE9B12D4677F96B709 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_CallOutBox.cpp; path = ../../src/gui/components/windows/juce_CallOutBox.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 8F54431CD3A672B1EB8335BE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CallOutBox.h; path = ../../src/gui/components/windows/juce_CallOutBox.h; sourceTree = SOURCE_ROOT; }; | |||
| 2FFDC7636EFC2D7F74590A31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ComponentPeer.cpp; path = ../../src/gui/components/windows/juce_ComponentPeer.cpp; sourceTree = SOURCE_ROOT; }; | |||
| 12C66C90F3192AFFD6BCEDB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentPeer.h; path = ../../src/gui/components/windows/juce_ComponentPeer.h; sourceTree = SOURCE_ROOT; }; | |||
| 929FEA5458430B7AE23BBB46 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DialogWindow.cpp; path = ../../src/gui/components/windows/juce_DialogWindow.cpp; sourceTree = SOURCE_ROOT; }; | |||
| @@ -1427,6 +1430,8 @@ | |||
| 48D41BA310DED74E900A5AB0 = { isa = PBXGroup; children = ( | |||
| A5AAF4475138358F33D4904A, | |||
| 72C4FDDDB8602591DD4F7B3B, | |||
| 8AEF18EE9B12D4677F96B709, | |||
| 8F54431CD3A672B1EB8335BE, | |||
| 2FFDC7636EFC2D7F74590A31, | |||
| 12C66C90F3192AFFD6BCEDB6, | |||
| 929FEA5458430B7AE23BBB46, | |||
| @@ -2011,6 +2016,7 @@ | |||
| D9AAB4AE220010CD526C87D2, | |||
| C732ADB05901619B14F1D6BB, | |||
| 075D5995E41FDD670ED35E17, | |||
| BBE02E8719411C8A7D43A401, | |||
| 35E3B9684ED968BAC0BC8021, | |||
| 736AC4A9DA6515B92644FA02, | |||
| DFFBADCBC9C7E31B391BA560, | |||
| @@ -887,6 +887,10 @@ | |||
| file="src/gui/components/windows/juce_AlertWindow.cpp"/> | |||
| <FILE id="q2qARl9MO" name="juce_AlertWindow.h" compile="0" resource="0" | |||
| file="src/gui/components/windows/juce_AlertWindow.h"/> | |||
| <FILE id="831V8C" name="juce_CallOutBox.cpp" compile="1" resource="0" | |||
| file="src/gui/components/windows/juce_CallOutBox.cpp"/> | |||
| <FILE id="EbIvE5" name="juce_CallOutBox.h" compile="0" resource="0" | |||
| file="src/gui/components/windows/juce_CallOutBox.h"/> | |||
| <FILE id="wriH2opIu" name="juce_ComponentPeer.cpp" compile="1" resource="0" | |||
| file="src/gui/components/windows/juce_ComponentPeer.cpp"/> | |||
| <FILE id="hlmMSNcRL" name="juce_ComponentPeer.h" compile="0" resource="0" | |||
| @@ -309,6 +309,7 @@ | |||
| #include "../src/gui/components/special/juce_PreferencesPanel.cpp" | |||
| #include "../src/gui/components/special/juce_SystemTrayIconComponent.cpp" | |||
| #include "../src/gui/components/windows/juce_AlertWindow.cpp" | |||
| #include "../src/gui/components/windows/juce_CallOutBox.cpp" | |||
| #include "../src/gui/components/windows/juce_ComponentPeer.cpp" | |||
| #include "../src/gui/components/windows/juce_DialogWindow.cpp" | |||
| #include "../src/gui/components/windows/juce_DocumentWindow.cpp" | |||
| @@ -65,7 +65,8 @@ public: | |||
| PopupColourSelector colourSelector (colourValue, defaultColour, canResetToDefault); | |||
| colourSelector.setSize (300, 400); | |||
| CallOutBox::showModal (colourSelector, targetComp, 0 /*targetComp->getTopLevelComponent()*/); | |||
| CallOutBox c (colourSelector, *targetComp, 0 /*targetComp->getTopLevelComponent()*/); | |||
| c.runModalLoop(); | |||
| } | |||
| void resized() | |||
| @@ -650,7 +650,9 @@ public: | |||
| undoManager->beginNewTransaction(); | |||
| PopupFillSelector popup (fillState, getDefaultGradient(), imageProvider, project, undoManager); | |||
| CallOutBox::showModal (popup, this, 0 /*getTopLevelComponent()*/); | |||
| CallOutBox c (popup, *this, 0 /*getTopLevelComponent()*/); | |||
| c.runModalLoop(); | |||
| } | |||
| void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { refresh(); } | |||
| @@ -415,209 +415,3 @@ const ColourGradient FillTypeEditorComponent::getDefaultGradient() const | |||
| jassert (p != 0); | |||
| return p->getDefaultGradient(); | |||
| } | |||
| //============================================================================== | |||
| CallOutBox::CallOutBox (Component& content_, const float arrowSize_) | |||
| : edge (jmax (20, (int) arrowSize_)), content (content_), arrowSize (arrowSize_) | |||
| { | |||
| addAndMakeVisible (&content); | |||
| } | |||
| CallOutBox::~CallOutBox() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| void CallOutBox::showModal (Component& content, Component* targetComp, Component* parentComp, float arrowSize) | |||
| { | |||
| showModal (content, | |||
| parentComp, | |||
| parentComp == 0 ? targetComp->getParentMonitorArea() | |||
| : parentComp->getLocalBounds(), | |||
| parentComp == 0 ? targetComp->getScreenBounds() | |||
| : (targetComp->getLocalBounds() + targetComp->relativePositionToOtherComponent (parentComp, Point<int>())), | |||
| arrowSize); | |||
| } | |||
| void CallOutBox::showModal (Component& content, Component* parent, | |||
| const Rectangle<int>& availableAreaInParent, | |||
| const Rectangle<int>& targetAreaInParent, float arrowSize) | |||
| { | |||
| CallOutBox p (content, arrowSize); | |||
| p.updatePosition (targetAreaInParent, availableAreaInParent); | |||
| if (parent != 0) | |||
| parent->addAndMakeVisible (&p); | |||
| else | |||
| p.addToDesktop (ComponentPeer::windowIsTemporary); | |||
| p.runModalLoop(); | |||
| } | |||
| //============================================================================== | |||
| void CallOutBox::paint (Graphics& g) | |||
| { | |||
| if (background.isNull()) | |||
| { | |||
| DropShadowEffect shadow; | |||
| shadow.setShadowProperties (5.0f, 0.4f, 0, 2); | |||
| Image im (Image::ARGB, getWidth(), getHeight(), true); | |||
| { | |||
| Graphics g (im); | |||
| g.setColour (Colour::greyLevel (0.23f).withAlpha (0.9f)); | |||
| g.fillPath (outline); | |||
| g.setColour (Colours::white.withAlpha (0.8f)); | |||
| g.strokePath (outline, PathStrokeType (2.0f)); | |||
| } | |||
| background = Image (Image::ARGB, getWidth(), getHeight(), true); | |||
| Graphics g (background); | |||
| shadow.applyEffect (im, g); | |||
| } | |||
| g.setColour (Colours::black); | |||
| g.drawImageAt (background, 0, 0); | |||
| } | |||
| void CallOutBox::resized() | |||
| { | |||
| content.setTopLeftPosition (edge, edge); | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::moved() | |||
| { | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::childBoundsChanged (Component*) | |||
| { | |||
| updatePosition (targetArea, availableArea); | |||
| } | |||
| bool CallOutBox::hitTest (int x, int y) | |||
| { | |||
| return outline.contains ((float) x, (float) y); | |||
| } | |||
| void CallOutBox::inputAttemptWhenModal() | |||
| { | |||
| exitModalState (0); | |||
| setVisible (false); | |||
| } | |||
| void CallOutBox::updatePosition (const Rectangle<int>& newTargetArea, const Rectangle<int>& newArea) | |||
| { | |||
| targetArea = newTargetArea; | |||
| availableArea = newArea; | |||
| Rectangle<int> bounds (0, 0, | |||
| content.getWidth() + edge * 2, | |||
| content.getHeight() + edge * 2); | |||
| const int hw = bounds.getWidth() / 2; | |||
| const int hh = bounds.getHeight() / 2; | |||
| const float hwReduced = (float) (hw - edge * 3); | |||
| const float hhReduced = (float) (hh - edge * 3); | |||
| const float arrowIndent = edge - arrowSize; | |||
| Point<float> targets[4] = { Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getBottom()), | |||
| Point<float> ((float) targetArea.getRight(), (float) targetArea.getCentreY()), | |||
| Point<float> ((float) targetArea.getX(), (float) targetArea.getCentreY()), | |||
| Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getY()) }; | |||
| Line<float> lines[4] = { Line<float> (targets[0].translated (-hwReduced, hh - arrowIndent), targets[0].translated (hwReduced, hh - arrowIndent)), | |||
| Line<float> (targets[1].translated (hw - arrowIndent, -hhReduced), targets[1].translated (hw - arrowIndent, hhReduced)), | |||
| Line<float> (targets[2].translated (-(hw - arrowIndent), -hhReduced), targets[2].translated (-(hw - arrowIndent), hhReduced)), | |||
| Line<float> (targets[3].translated (-hwReduced, -(hh - arrowIndent)), targets[3].translated (hwReduced, -(hh - arrowIndent))) }; | |||
| const Rectangle<float> reducedArea (newArea.reduced (hw, hh).toFloat()); | |||
| float bestDist = 1.0e9f; | |||
| for (int i = 0; i < 4; ++i) | |||
| { | |||
| Line<float> constrainedLine (reducedArea.getConstrainedPoint (lines[i].getStart()), | |||
| reducedArea.getConstrainedPoint (lines[i].getEnd())); | |||
| const Point<float> centre (constrainedLine.findNearestPointTo (reducedArea.getCentre())); | |||
| float distanceFromCentre = centre.getDistanceFrom (reducedArea.getCentre()); | |||
| if (! (reducedArea.contains (lines[i].getStart()) || reducedArea.contains (lines[i].getEnd()))) | |||
| distanceFromCentre *= 2.0f; | |||
| if (distanceFromCentre < bestDist) | |||
| { | |||
| bestDist = distanceFromCentre; | |||
| targetPoint = targets[i]; | |||
| bounds.setPosition ((int) (centre.getX() - hw), | |||
| (int) (centre.getY() - hh)); | |||
| } | |||
| } | |||
| setBounds (bounds); | |||
| } | |||
| void CallOutBox::refreshPath() | |||
| { | |||
| repaint(); | |||
| background = Image(); | |||
| outline.clear(); | |||
| const float gap = 4.5f; | |||
| const float cornerSize = 9.0f; | |||
| const float cornerSize2 = 2.0f * cornerSize; | |||
| const float arrowBaseWidth = arrowSize * 0.7f; | |||
| const float left = content.getX() - gap, top = content.getY() - gap, right = content.getRight() + gap, bottom = content.getBottom() + gap; | |||
| const float targetX = targetPoint.getX() - getX(), targetY = targetPoint.getY() - getY(); | |||
| outline.startNewSubPath (left + cornerSize, top); | |||
| if (targetY < edge) | |||
| { | |||
| outline.lineTo (targetX - arrowBaseWidth, top); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (targetX + arrowBaseWidth, top); | |||
| } | |||
| outline.lineTo (right - cornerSize, top); | |||
| outline.addArc (right - cornerSize2, top, cornerSize2, cornerSize2, 0, float_Pi * 0.5f); | |||
| if (targetX > right) | |||
| { | |||
| outline.lineTo (right, targetY - arrowBaseWidth); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (right, targetY + arrowBaseWidth); | |||
| } | |||
| outline.lineTo (right, bottom - cornerSize); | |||
| outline.addArc (right - cornerSize2, bottom - cornerSize2, cornerSize2, cornerSize2, float_Pi * 0.5f, float_Pi); | |||
| if (targetY > bottom) | |||
| { | |||
| outline.lineTo (targetX + arrowBaseWidth, bottom); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (targetX - arrowBaseWidth, bottom); | |||
| } | |||
| outline.lineTo (left + cornerSize, bottom); | |||
| outline.addArc (left, bottom - cornerSize2, cornerSize2, cornerSize2, float_Pi, float_Pi * 1.5f); | |||
| if (targetX < left) | |||
| { | |||
| outline.lineTo (left, targetY + arrowBaseWidth); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (left, targetY - arrowBaseWidth); | |||
| } | |||
| outline.lineTo (left, top + cornerSize); | |||
| outline.addArc (left, top, cornerSize2, cornerSize2, float_Pi * 1.5f, float_Pi * 2.0f - 0.05f); | |||
| outline.closeSubPath(); | |||
| } | |||
| @@ -81,58 +81,6 @@ private: | |||
| GlyphArrangement glyphs; | |||
| }; | |||
| //============================================================================== | |||
| class CallOutBox : public Component | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| CallOutBox (Component& content, float arrowSize = 16.0f); | |||
| ~CallOutBox(); | |||
| //============================================================================== | |||
| static void showModal (Component& contentComponent, Component* targetComp, | |||
| Component* parentComp, float arrowSize = 16.0f); | |||
| static void showModal (Component& contentComponent, Component* parent, | |||
| const Rectangle<int>& availableAreaInParent, | |||
| const Rectangle<int>& targetAreaInParent, | |||
| float arrowSize = 16.0f); | |||
| //============================================================================== | |||
| void updatePosition (const Rectangle<int>& newTargetArea, const Rectangle<int>& newArea); | |||
| //============================================================================== | |||
| /** @internal */ | |||
| void paint (Graphics& g); | |||
| /** @internal */ | |||
| void resized(); | |||
| /** @internal */ | |||
| void moved(); | |||
| /** @internal */ | |||
| void childBoundsChanged (Component*); | |||
| /** @internal */ | |||
| bool hitTest (int x, int y); | |||
| /** @internal */ | |||
| void inputAttemptWhenModal(); | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| const int edge; | |||
| const float arrowSize; | |||
| Component& content; | |||
| Path outline; | |||
| Point<float> targetPoint; | |||
| Rectangle<int> availableArea, targetArea; | |||
| Image background; | |||
| void refreshPath(); | |||
| CallOutBox (const CallOutBox&); | |||
| CallOutBox& operator= (const CallOutBox&); | |||
| }; | |||
| //============================================================================== | |||
| class JucerToolbarButton : public ToolbarItemComponent | |||
| { | |||
| @@ -256,28 +256,15 @@ public: | |||
| { | |||
| // create two colour selector components for our background and | |||
| // text colour.. | |||
| ColourSelector colourSelector1; | |||
| colourSelector1.setName ("background"); | |||
| colourSelector1.setCurrentColour (findColour (TextButton::buttonColourId)); | |||
| colourSelector1.addChangeListener (this); | |||
| ColourSelector colourSelector2; | |||
| colourSelector2.setName ("text"); | |||
| colourSelector2.setCurrentColour (findColour (TextButton::textColourOffId)); | |||
| colourSelector2.addChangeListener (this); | |||
| // and add the selectors as custom menu items to a PopupMenu, putting | |||
| // them in two different sub-menus.. | |||
| PopupMenu m, sub1, sub2; | |||
| sub1.addCustomItem (1234, &colourSelector1, 300, 300, false); | |||
| m.addSubMenu ("background colour", sub1); | |||
| sub2.addCustomItem (1234, &colourSelector2, 300, 300, false); | |||
| m.addSubMenu ("text colour", sub2); | |||
| // and show the menu (modally).. | |||
| m.showAt (this); | |||
| ColourSelector colourSelector; | |||
| colourSelector.setName ("background"); | |||
| colourSelector.setCurrentColour (findColour (TextButton::buttonColourId)); | |||
| colourSelector.addChangeListener (this); | |||
| colourSelector.setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); | |||
| colourSelector.setSize (300, 400); | |||
| CallOutBox callOut (colourSelector, *this, 0); | |||
| callOut.runModalLoop(); | |||
| } | |||
| void changeListenerCallback (void* source) | |||
| @@ -66032,6 +66032,25 @@ const Rectangle<int> LookAndFeel::getPropertyComponentContentPosition (PropertyC | |||
| component.getWidth() - component.getWidth() / 3 - 1, component.getHeight() - 3); | |||
| } | |||
| void LookAndFeel::drawCallOutBoxBackground (CallOutBox& box, Graphics& g, const Path& path) | |||
| { | |||
| Image content (Image::ARGB, box.getWidth(), box.getHeight(), true); | |||
| { | |||
| Graphics g2 (content); | |||
| g2.setColour (Colour::greyLevel (0.23f).withAlpha (0.9f)); | |||
| g2.fillPath (path); | |||
| g2.setColour (Colours::white.withAlpha (0.8f)); | |||
| g2.strokePath (path, PathStrokeType (2.0f)); | |||
| } | |||
| DropShadowEffect shadow; | |||
| shadow.setShadowProperties (5.0f, 0.4f, 0, 2); | |||
| shadow.applyEffect (content, g); | |||
| } | |||
| void LookAndFeel::createFileChooserHeaderText (const String& title, | |||
| const String& instructions, | |||
| GlyphArrangement& text, | |||
| @@ -76241,6 +76260,210 @@ END_JUCE_NAMESPACE | |||
| /*** End of inlined file: juce_AlertWindow.cpp ***/ | |||
| /*** Start of inlined file: juce_CallOutBox.cpp ***/ | |||
| BEGIN_JUCE_NAMESPACE | |||
| CallOutBox::CallOutBox (Component& contentComponent, | |||
| Component& componentToPointTo, | |||
| Component* const parentComponent) | |||
| : borderSpace (20), arrowSize (16.0f), content (contentComponent) | |||
| { | |||
| addAndMakeVisible (&content); | |||
| if (parentComponent != 0) | |||
| { | |||
| updatePosition (parentComponent->getLocalBounds(), | |||
| componentToPointTo.getLocalBounds() | |||
| + componentToPointTo.relativePositionToOtherComponent (parentComponent, Point<int>())); | |||
| parentComponent->addAndMakeVisible (this); | |||
| } | |||
| else | |||
| { | |||
| updatePosition (componentToPointTo.getScreenBounds(), | |||
| componentToPointTo.getParentMonitorArea()); | |||
| addToDesktop (ComponentPeer::windowIsTemporary); | |||
| } | |||
| } | |||
| CallOutBox::~CallOutBox() | |||
| { | |||
| } | |||
| void CallOutBox::setArrowSize (const float newSize) | |||
| { | |||
| arrowSize = newSize; | |||
| borderSpace = jmax (20, (int) arrowSize); | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::paint (Graphics& g) | |||
| { | |||
| if (background.isNull()) | |||
| { | |||
| background = Image (Image::ARGB, getWidth(), getHeight(), true); | |||
| Graphics g (background); | |||
| getLookAndFeel().drawCallOutBoxBackground (*this, g, outline); | |||
| } | |||
| g.setColour (Colours::black); | |||
| g.drawImageAt (background, 0, 0); | |||
| } | |||
| void CallOutBox::resized() | |||
| { | |||
| content.setTopLeftPosition (borderSpace, borderSpace); | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::moved() | |||
| { | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::childBoundsChanged (Component*) | |||
| { | |||
| updatePosition (targetArea, availableArea); | |||
| } | |||
| bool CallOutBox::hitTest (int x, int y) | |||
| { | |||
| return outline.contains ((float) x, (float) y); | |||
| } | |||
| void CallOutBox::inputAttemptWhenModal() | |||
| { | |||
| exitModalState (0); | |||
| setVisible (false); | |||
| } | |||
| bool CallOutBox::keyPressed (const KeyPress& key) | |||
| { | |||
| if (key.isKeyCode (KeyPress::escapeKey)) | |||
| { | |||
| inputAttemptWhenModal(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const Rectangle<int>& newAreaToFitIn) | |||
| { | |||
| targetArea = newAreaToPointTo; | |||
| availableArea = newAreaToFitIn; | |||
| Rectangle<int> bounds (0, 0, | |||
| content.getWidth() + borderSpace * 2, | |||
| content.getHeight() + borderSpace * 2); | |||
| const int hw = bounds.getWidth() / 2; | |||
| const int hh = bounds.getHeight() / 2; | |||
| const float hwReduced = (float) (hw - borderSpace * 3); | |||
| const float hhReduced = (float) (hh - borderSpace * 3); | |||
| const float arrowIndent = borderSpace - arrowSize; | |||
| Point<float> targets[4] = { Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getBottom()), | |||
| Point<float> ((float) targetArea.getRight(), (float) targetArea.getCentreY()), | |||
| Point<float> ((float) targetArea.getX(), (float) targetArea.getCentreY()), | |||
| Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getY()) }; | |||
| Line<float> lines[4] = { Line<float> (targets[0].translated (-hwReduced, hh - arrowIndent), targets[0].translated (hwReduced, hh - arrowIndent)), | |||
| Line<float> (targets[1].translated (hw - arrowIndent, -hhReduced), targets[1].translated (hw - arrowIndent, hhReduced)), | |||
| Line<float> (targets[2].translated (-(hw - arrowIndent), -hhReduced), targets[2].translated (-(hw - arrowIndent), hhReduced)), | |||
| Line<float> (targets[3].translated (-hwReduced, -(hh - arrowIndent)), targets[3].translated (hwReduced, -(hh - arrowIndent))) }; | |||
| const Rectangle<float> centrePointArea (newAreaToFitIn.reduced (hw, hh).toFloat()); | |||
| float nearest = 1.0e9f; | |||
| for (int i = 0; i < 4; ++i) | |||
| { | |||
| Line<float> constrainedLine (centrePointArea.getConstrainedPoint (lines[i].getStart()), | |||
| centrePointArea.getConstrainedPoint (lines[i].getEnd())); | |||
| const Point<float> centre (constrainedLine.findNearestPointTo (centrePointArea.getCentre())); | |||
| float distanceFromCentre = centre.getDistanceFrom (centrePointArea.getCentre()); | |||
| if (! (centrePointArea.contains (lines[i].getStart()) || centrePointArea.contains (lines[i].getEnd()))) | |||
| distanceFromCentre *= 2.0f; | |||
| if (distanceFromCentre < nearest) | |||
| { | |||
| nearest = distanceFromCentre; | |||
| targetPoint = targets[i]; | |||
| bounds.setPosition ((int) (centre.getX() - hw), | |||
| (int) (centre.getY() - hh)); | |||
| } | |||
| } | |||
| setBounds (bounds); | |||
| } | |||
| void CallOutBox::refreshPath() | |||
| { | |||
| repaint(); | |||
| background = Image(); | |||
| outline.clear(); | |||
| const float gap = 4.5f; | |||
| const float cornerSize = 9.0f; | |||
| const float cornerSize2 = 2.0f * cornerSize; | |||
| const float arrowBaseWidth = arrowSize * 0.7f; | |||
| const float left = content.getX() - gap, top = content.getY() - gap, right = content.getRight() + gap, bottom = content.getBottom() + gap; | |||
| const float targetX = targetPoint.getX() - getX(), targetY = targetPoint.getY() - getY(); | |||
| outline.startNewSubPath (left + cornerSize, top); | |||
| if (targetY <= top) | |||
| { | |||
| outline.lineTo (targetX - arrowBaseWidth, top); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (targetX + arrowBaseWidth, top); | |||
| } | |||
| outline.lineTo (right - cornerSize, top); | |||
| outline.addArc (right - cornerSize2, top, cornerSize2, cornerSize2, 0, float_Pi * 0.5f); | |||
| if (targetX >= right) | |||
| { | |||
| outline.lineTo (right, targetY - arrowBaseWidth); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (right, targetY + arrowBaseWidth); | |||
| } | |||
| outline.lineTo (right, bottom - cornerSize); | |||
| outline.addArc (right - cornerSize2, bottom - cornerSize2, cornerSize2, cornerSize2, float_Pi * 0.5f, float_Pi); | |||
| if (targetY >= bottom) | |||
| { | |||
| outline.lineTo (targetX + arrowBaseWidth, bottom); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (targetX - arrowBaseWidth, bottom); | |||
| } | |||
| outline.lineTo (left + cornerSize, bottom); | |||
| outline.addArc (left, bottom - cornerSize2, cornerSize2, cornerSize2, float_Pi, float_Pi * 1.5f); | |||
| if (targetX <= left) | |||
| { | |||
| outline.lineTo (left, targetY + arrowBaseWidth); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (left, targetY - arrowBaseWidth); | |||
| } | |||
| outline.lineTo (left, top + cornerSize); | |||
| outline.addArc (left, top, cornerSize2, cornerSize2, float_Pi * 1.5f, float_Pi * 2.0f - 0.05f); | |||
| outline.closeSubPath(); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| /*** End of inlined file: juce_CallOutBox.cpp ***/ | |||
| /*** Start of inlined file: juce_ComponentPeer.cpp ***/ | |||
| BEGIN_JUCE_NAMESPACE | |||
| @@ -84084,6 +84307,17 @@ void DrawableComposite::resetBoundingBoxToContentArea() | |||
| RelativePoint (content.left, content.bottom))); | |||
| } | |||
| void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren() | |||
| { | |||
| const Rectangle<float> bounds (getUntransformedBounds (false)); | |||
| setContentArea (RelativeRectangle (RelativeCoordinate (bounds.getX(), true), | |||
| RelativeCoordinate (bounds.getRight(), true), | |||
| RelativeCoordinate (bounds.getY(), false), | |||
| RelativeCoordinate (bounds.getBottom(), false))); | |||
| resetBoundingBoxToContentArea(); | |||
| } | |||
| int DrawableComposite::getNumMarkers (const bool xAxis) const throw() | |||
| { | |||
| return (xAxis ? markersX : markersY).size(); | |||
| @@ -84205,7 +84439,7 @@ const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& o | |||
| return RelativeCoordinate(); | |||
| } | |||
| const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||
| const Rectangle<float> DrawableComposite::getUntransformedBounds (const bool includeMarkers) const | |||
| { | |||
| Rectangle<float> bounds; | |||
| @@ -84213,58 +84447,57 @@ const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||
| for (i = 0; i < drawables.size(); ++i) | |||
| bounds = bounds.getUnion (drawables.getUnchecked(i)->getBounds()); | |||
| if (markersX.size() > 0) | |||
| if (includeMarkers) | |||
| { | |||
| float minX = std::numeric_limits<float>::max(); | |||
| float maxX = std::numeric_limits<float>::min(); | |||
| for (i = markersX.size(); --i >= 0;) | |||
| if (markersX.size() > 0) | |||
| { | |||
| const Marker* m = markersX.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minX = jmin (minX, pos); | |||
| maxX = jmax (maxX, pos); | |||
| } | |||
| float minX = std::numeric_limits<float>::max(); | |||
| float maxX = std::numeric_limits<float>::min(); | |||
| if (minX <= maxX) | |||
| { | |||
| if (bounds.getWidth() == 0) | |||
| for (i = markersX.size(); --i >= 0;) | |||
| { | |||
| bounds.setLeft (minX); | |||
| bounds.setWidth (maxX - minX); | |||
| const Marker* m = markersX.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minX = jmin (minX, pos); | |||
| maxX = jmax (maxX, pos); | |||
| } | |||
| else | |||
| if (minX <= maxX) | |||
| { | |||
| bounds.setLeft (jmin (bounds.getX(), minX)); | |||
| bounds.setRight (jmax (bounds.getRight(), maxX)); | |||
| if (bounds.getHeight() > 0) | |||
| { | |||
| minX = jmin (minX, bounds.getX()); | |||
| maxX = jmax (maxX, bounds.getRight()); | |||
| } | |||
| bounds.setLeft (minX); | |||
| bounds.setWidth (maxX - minX); | |||
| } | |||
| } | |||
| } | |||
| if (markersY.size() > 0) | |||
| { | |||
| float minY = std::numeric_limits<float>::max(); | |||
| float maxY = std::numeric_limits<float>::min(); | |||
| for (i = markersY.size(); --i >= 0;) | |||
| if (markersY.size() > 0) | |||
| { | |||
| const Marker* m = markersY.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minY = jmin (minY, pos); | |||
| maxY = jmax (maxY, pos); | |||
| } | |||
| float minY = std::numeric_limits<float>::max(); | |||
| float maxY = std::numeric_limits<float>::min(); | |||
| if (minY <= maxY) | |||
| { | |||
| if (bounds.getHeight() == 0) | |||
| for (i = markersY.size(); --i >= 0;) | |||
| { | |||
| bounds.setTop (minY); | |||
| bounds.setHeight (maxY - minY); | |||
| const Marker* m = markersY.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minY = jmin (minY, pos); | |||
| maxY = jmax (maxY, pos); | |||
| } | |||
| else | |||
| if (minY <= maxY) | |||
| { | |||
| bounds.setTop (jmin (bounds.getY(), minY)); | |||
| bounds.setBottom (jmax (bounds.getBottom(), maxY)); | |||
| if (bounds.getHeight() > 0) | |||
| { | |||
| minY = jmin (minY, bounds.getY()); | |||
| maxY = jmax (maxY, bounds.getBottom()); | |||
| } | |||
| bounds.setTop (minY); | |||
| bounds.setHeight (maxY - minY); | |||
| } | |||
| } | |||
| } | |||
| @@ -84274,7 +84507,7 @@ const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||
| const Rectangle<float> DrawableComposite::getBounds() const | |||
| { | |||
| return getUntransformedBounds().transformed (calculateTransform()); | |||
| return getUntransformedBounds (true).transformed (calculateTransform()); | |||
| } | |||
| bool DrawableComposite::hitTest (float x, float y) const | |||
| @@ -85643,13 +85876,7 @@ public: | |||
| newState.parseSubElements (xml, drawable); | |||
| const Rectangle<float> bounds (drawable->getBounds()); | |||
| drawable->setContentArea (RelativeRectangle (RelativeCoordinate (bounds.getX(), true), | |||
| RelativeCoordinate (bounds.getRight(), true), | |||
| RelativeCoordinate (bounds.getY(), false), | |||
| RelativeCoordinate (bounds.getBottom(), false))); | |||
| drawable->resetBoundingBoxToContentArea(); | |||
| drawable->resetContentAreaAndBoundingBoxToFitChildren(); | |||
| return drawable; | |||
| } | |||
| @@ -85711,6 +85938,7 @@ private: | |||
| parseSubElements (xml, drawable); | |||
| } | |||
| drawable->resetContentAreaAndBoundingBoxToFitChildren(); | |||
| return drawable; | |||
| } | |||
| @@ -64,7 +64,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 13 | |||
| #define JUCE_BUILDNUMBER 14 | |||
| /** Current Juce version number. | |||
| @@ -22284,17 +22284,20 @@ public: | |||
| /** Applies this stroke type to a path and returns the resultant stroke as another Path. | |||
| @param destPath the resultant stroked outline shape will be copied into this path. | |||
| Note that it's ok for the source and destination Paths to be | |||
| the same object, so you can easily turn a path into a stroked version | |||
| of itself. | |||
| @param destPath the resultant stroked outline shape will be copied into this path. | |||
| Note that it's ok for the source and destination Paths to be | |||
| the same object, so you can easily turn a path into a stroked version | |||
| of itself. | |||
| @param sourcePath the path to use as the source | |||
| @param transform an optional transform to apply to the points from the source path | |||
| as they are being used | |||
| @param arrowheadStartWidth the width of the arrowhead at the start of the path | |||
| @param arrowheadStartLength the length of the arrowhead at the start of the path | |||
| @param arrowheadEndWidth the width of the arrowhead at the end of the path | |||
| @param arrowheadEndLength the length of the arrowhead at the end of the path | |||
| @param transform an optional transform to apply to the points from the source path | |||
| as they are being used | |||
| @param extraAccuracy if this is greater than 1.0, it will subdivide the path to | |||
| a higher resolution, which improved the quality if you'll later want | |||
| to enlarge the stroked path | |||
| a higher resolution, which improved the quality if you'll later want | |||
| to enlarge the stroked path | |||
| @see createDashedStroke | |||
| */ | |||
| void createStrokeWithArrowheads (Path& destPath, | |||
| @@ -53213,6 +53216,7 @@ class FileBrowserComponent; | |||
| class DirectoryContentsDisplayComponent; | |||
| class FilePreviewComponent; | |||
| class ImageButton; | |||
| class CallOutBox; | |||
| /** | |||
| LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses | |||
| @@ -53719,6 +53723,8 @@ public: | |||
| virtual const Rectangle<int> getPropertyComponentContentPosition (PropertyComponent& component); | |||
| void drawCallOutBoxBackground (CallOutBox& box, Graphics& g, const Path& path); | |||
| virtual void drawLevelMeter (Graphics& g, int width, int height, float level); | |||
| virtual void drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription); | |||
| @@ -57130,6 +57136,109 @@ private: | |||
| #endif | |||
| #ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ | |||
| #endif | |||
| #ifndef __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| /*** Start of inlined file: juce_CallOutBox.h ***/ | |||
| #ifndef __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| #define __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| /** | |||
| A box with a small arrow that can be used as a temporary pop-up window to show | |||
| extra controls when a button or other component is clicked. | |||
| Using one of these is similar to having a popup menu attached to a button or | |||
| other component - but it looks fancier, and has an arrow that can indicate the | |||
| object that it applies to. | |||
| Normally, you'd create one of these on the stack and run it modally, e.g. | |||
| @code | |||
| void mouseUp (const MouseEvent& e) | |||
| { | |||
| MyContentComponent content; | |||
| content.setSize (300, 300); | |||
| CallOutBox callOut (content, *this, 0); | |||
| callOut.runModalLoop(); | |||
| } | |||
| @endcode | |||
| The call-out will resize and position itself when the content changes size. | |||
| */ | |||
| class JUCE_API CallOutBox : public Component | |||
| { | |||
| public: | |||
| /** Creates a CallOutBox. | |||
| @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). | |||
| 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 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. | |||
| */ | |||
| CallOutBox (Component& contentComponent, | |||
| Component& componentToPointTo, | |||
| Component* parentComponent); | |||
| /** Destructor. */ | |||
| ~CallOutBox(); | |||
| /** Changes the length of the arrow. */ | |||
| void setArrowSize (float newSize); | |||
| /** Updates the position and size of the box. | |||
| You shouldn't normally need to call this, unless you need more precise control over the | |||
| layout. | |||
| @param newAreaToPointTo the rectangle to make the box's arrow point to | |||
| @param newAreaToFitIn the area within which the box's position should be constrained | |||
| */ | |||
| void updatePosition (const Rectangle<int>& newAreaToPointTo, | |||
| const Rectangle<int>& newAreaToFitIn); | |||
| /** @internal */ | |||
| void paint (Graphics& g); | |||
| /** @internal */ | |||
| void resized(); | |||
| /** @internal */ | |||
| void moved(); | |||
| /** @internal */ | |||
| void childBoundsChanged (Component*); | |||
| /** @internal */ | |||
| bool hitTest (int x, int y); | |||
| /** @internal */ | |||
| void inputAttemptWhenModal(); | |||
| /** @internal */ | |||
| bool keyPressed (const KeyPress& key); | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| int borderSpace; | |||
| float arrowSize; | |||
| Component& content; | |||
| Path outline; | |||
| Point<float> targetPoint; | |||
| Rectangle<int> availableArea, targetArea; | |||
| Image background; | |||
| void refreshPath(); | |||
| void drawCallOutBoxBackground (Graphics& g, const Path& outline, int width, int height); | |||
| CallOutBox (const CallOutBox&); | |||
| CallOutBox& operator= (const CallOutBox&); | |||
| }; | |||
| #endif // __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| /*** End of inlined file: juce_CallOutBox.h ***/ | |||
| #endif | |||
| #ifndef __JUCE_COMPONENTPEER_JUCEHEADER__ | |||
| @@ -58558,6 +58667,11 @@ public: | |||
| */ | |||
| void resetBoundingBoxToContentArea(); | |||
| /** Resets the content area and the bounding transform to fit around the area occupied | |||
| by the child components (ignoring any markers). | |||
| */ | |||
| void resetContentAreaAndBoundingBoxToFitChildren(); | |||
| /** Represents a named marker position. | |||
| @see DrawableComposite::getMarker | |||
| */ | |||
| @@ -58654,7 +58768,7 @@ private: | |||
| RelativeParallelogram bounds; | |||
| OwnedArray <Marker> markersX, markersY; | |||
| const Rectangle<float> getUntransformedBounds() const; | |||
| const Rectangle<float> getUntransformedBounds (bool includeMarkers) const; | |||
| const AffineTransform calculateTransform() const; | |||
| DrawableComposite& operator= (const DrawableComposite&); | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 13 | |||
| #define JUCE_BUILDNUMBER 14 | |||
| /** Current Juce version number. | |||
| @@ -39,6 +39,7 @@ BEGIN_JUCE_NAMESPACE | |||
| #include "../windows/juce_AlertWindow.h" | |||
| #include "../windows/juce_DocumentWindow.h" | |||
| #include "../windows/juce_ResizableWindow.h" | |||
| #include "../windows/juce_CallOutBox.h" | |||
| #include "../menus/juce_MenuBarComponent.h" | |||
| #include "../menus/juce_PopupMenu.h" | |||
| #include "../layout/juce_ScrollBar.h" | |||
| @@ -2528,6 +2529,27 @@ const Rectangle<int> LookAndFeel::getPropertyComponentContentPosition (PropertyC | |||
| component.getWidth() - component.getWidth() / 3 - 1, component.getHeight() - 3); | |||
| } | |||
| //============================================================================== | |||
| void LookAndFeel::drawCallOutBoxBackground (CallOutBox& box, Graphics& g, const Path& path) | |||
| { | |||
| Image content (Image::ARGB, box.getWidth(), box.getHeight(), true); | |||
| { | |||
| Graphics g2 (content); | |||
| g2.setColour (Colour::greyLevel (0.23f).withAlpha (0.9f)); | |||
| g2.fillPath (path); | |||
| g2.setColour (Colours::white.withAlpha (0.8f)); | |||
| g2.strokePath (path, PathStrokeType (2.0f)); | |||
| } | |||
| DropShadowEffect shadow; | |||
| shadow.setShadowProperties (5.0f, 0.4f, 0, 2); | |||
| shadow.applyEffect (content, g); | |||
| } | |||
| //============================================================================== | |||
| void LookAndFeel::createFileChooserHeaderText (const String& title, | |||
| const String& instructions, | |||
| @@ -57,6 +57,7 @@ class FileBrowserComponent; | |||
| class DirectoryContentsDisplayComponent; | |||
| class FilePreviewComponent; | |||
| class ImageButton; | |||
| class CallOutBox; | |||
| //============================================================================== | |||
| @@ -597,6 +598,9 @@ public: | |||
| virtual const Rectangle<int> getPropertyComponentContentPosition (PropertyComponent& component); | |||
| //============================================================================== | |||
| void drawCallOutBoxBackground (CallOutBox& box, Graphics& g, const Path& path); | |||
| //============================================================================== | |||
| virtual void drawLevelMeter (Graphics& g, int width, int height, float level); | |||
| @@ -0,0 +1,234 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-10 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "../../../core/juce_StandardHeader.h" | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_CallOutBox.h" | |||
| #include "juce_ComponentPeer.h" | |||
| #include "../lookandfeel/juce_LookAndFeel.h" | |||
| //============================================================================== | |||
| CallOutBox::CallOutBox (Component& contentComponent, | |||
| Component& componentToPointTo, | |||
| Component* const parentComponent) | |||
| : borderSpace (20), arrowSize (16.0f), content (contentComponent) | |||
| { | |||
| addAndMakeVisible (&content); | |||
| if (parentComponent != 0) | |||
| { | |||
| updatePosition (parentComponent->getLocalBounds(), | |||
| componentToPointTo.getLocalBounds() | |||
| + componentToPointTo.relativePositionToOtherComponent (parentComponent, Point<int>())); | |||
| parentComponent->addAndMakeVisible (this); | |||
| } | |||
| else | |||
| { | |||
| updatePosition (componentToPointTo.getScreenBounds(), | |||
| componentToPointTo.getParentMonitorArea()); | |||
| addToDesktop (ComponentPeer::windowIsTemporary); | |||
| } | |||
| } | |||
| CallOutBox::~CallOutBox() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| void CallOutBox::setArrowSize (const float newSize) | |||
| { | |||
| arrowSize = newSize; | |||
| borderSpace = jmax (20, (int) arrowSize); | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::paint (Graphics& g) | |||
| { | |||
| if (background.isNull()) | |||
| { | |||
| background = Image (Image::ARGB, getWidth(), getHeight(), true); | |||
| Graphics g (background); | |||
| getLookAndFeel().drawCallOutBoxBackground (*this, g, outline); | |||
| } | |||
| g.setColour (Colours::black); | |||
| g.drawImageAt (background, 0, 0); | |||
| } | |||
| void CallOutBox::resized() | |||
| { | |||
| content.setTopLeftPosition (borderSpace, borderSpace); | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::moved() | |||
| { | |||
| refreshPath(); | |||
| } | |||
| void CallOutBox::childBoundsChanged (Component*) | |||
| { | |||
| updatePosition (targetArea, availableArea); | |||
| } | |||
| bool CallOutBox::hitTest (int x, int y) | |||
| { | |||
| return outline.contains ((float) x, (float) y); | |||
| } | |||
| void CallOutBox::inputAttemptWhenModal() | |||
| { | |||
| exitModalState (0); | |||
| setVisible (false); | |||
| } | |||
| bool CallOutBox::keyPressed (const KeyPress& key) | |||
| { | |||
| if (key.isKeyCode (KeyPress::escapeKey)) | |||
| { | |||
| inputAttemptWhenModal(); | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const Rectangle<int>& newAreaToFitIn) | |||
| { | |||
| targetArea = newAreaToPointTo; | |||
| availableArea = newAreaToFitIn; | |||
| Rectangle<int> bounds (0, 0, | |||
| content.getWidth() + borderSpace * 2, | |||
| content.getHeight() + borderSpace * 2); | |||
| const int hw = bounds.getWidth() / 2; | |||
| const int hh = bounds.getHeight() / 2; | |||
| const float hwReduced = (float) (hw - borderSpace * 3); | |||
| const float hhReduced = (float) (hh - borderSpace * 3); | |||
| const float arrowIndent = borderSpace - arrowSize; | |||
| Point<float> targets[4] = { Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getBottom()), | |||
| Point<float> ((float) targetArea.getRight(), (float) targetArea.getCentreY()), | |||
| Point<float> ((float) targetArea.getX(), (float) targetArea.getCentreY()), | |||
| Point<float> ((float) targetArea.getCentreX(), (float) targetArea.getY()) }; | |||
| Line<float> lines[4] = { Line<float> (targets[0].translated (-hwReduced, hh - arrowIndent), targets[0].translated (hwReduced, hh - arrowIndent)), | |||
| Line<float> (targets[1].translated (hw - arrowIndent, -hhReduced), targets[1].translated (hw - arrowIndent, hhReduced)), | |||
| Line<float> (targets[2].translated (-(hw - arrowIndent), -hhReduced), targets[2].translated (-(hw - arrowIndent), hhReduced)), | |||
| Line<float> (targets[3].translated (-hwReduced, -(hh - arrowIndent)), targets[3].translated (hwReduced, -(hh - arrowIndent))) }; | |||
| const Rectangle<float> centrePointArea (newAreaToFitIn.reduced (hw, hh).toFloat()); | |||
| float nearest = 1.0e9f; | |||
| for (int i = 0; i < 4; ++i) | |||
| { | |||
| Line<float> constrainedLine (centrePointArea.getConstrainedPoint (lines[i].getStart()), | |||
| centrePointArea.getConstrainedPoint (lines[i].getEnd())); | |||
| const Point<float> centre (constrainedLine.findNearestPointTo (centrePointArea.getCentre())); | |||
| float distanceFromCentre = centre.getDistanceFrom (centrePointArea.getCentre()); | |||
| if (! (centrePointArea.contains (lines[i].getStart()) || centrePointArea.contains (lines[i].getEnd()))) | |||
| distanceFromCentre *= 2.0f; | |||
| if (distanceFromCentre < nearest) | |||
| { | |||
| nearest = distanceFromCentre; | |||
| targetPoint = targets[i]; | |||
| bounds.setPosition ((int) (centre.getX() - hw), | |||
| (int) (centre.getY() - hh)); | |||
| } | |||
| } | |||
| setBounds (bounds); | |||
| } | |||
| void CallOutBox::refreshPath() | |||
| { | |||
| repaint(); | |||
| background = Image(); | |||
| outline.clear(); | |||
| const float gap = 4.5f; | |||
| const float cornerSize = 9.0f; | |||
| const float cornerSize2 = 2.0f * cornerSize; | |||
| const float arrowBaseWidth = arrowSize * 0.7f; | |||
| const float left = content.getX() - gap, top = content.getY() - gap, right = content.getRight() + gap, bottom = content.getBottom() + gap; | |||
| const float targetX = targetPoint.getX() - getX(), targetY = targetPoint.getY() - getY(); | |||
| outline.startNewSubPath (left + cornerSize, top); | |||
| if (targetY <= top) | |||
| { | |||
| outline.lineTo (targetX - arrowBaseWidth, top); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (targetX + arrowBaseWidth, top); | |||
| } | |||
| outline.lineTo (right - cornerSize, top); | |||
| outline.addArc (right - cornerSize2, top, cornerSize2, cornerSize2, 0, float_Pi * 0.5f); | |||
| if (targetX >= right) | |||
| { | |||
| outline.lineTo (right, targetY - arrowBaseWidth); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (right, targetY + arrowBaseWidth); | |||
| } | |||
| outline.lineTo (right, bottom - cornerSize); | |||
| outline.addArc (right - cornerSize2, bottom - cornerSize2, cornerSize2, cornerSize2, float_Pi * 0.5f, float_Pi); | |||
| if (targetY >= bottom) | |||
| { | |||
| outline.lineTo (targetX + arrowBaseWidth, bottom); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (targetX - arrowBaseWidth, bottom); | |||
| } | |||
| outline.lineTo (left + cornerSize, bottom); | |||
| outline.addArc (left, bottom - cornerSize2, cornerSize2, cornerSize2, float_Pi, float_Pi * 1.5f); | |||
| if (targetX <= left) | |||
| { | |||
| outline.lineTo (left, targetY + arrowBaseWidth); | |||
| outline.lineTo (targetX, targetY); | |||
| outline.lineTo (left, targetY - arrowBaseWidth); | |||
| } | |||
| outline.lineTo (left, top + cornerSize); | |||
| outline.addArc (left, top, cornerSize2, cornerSize2, float_Pi * 1.5f, float_Pi * 2.0f - 0.05f); | |||
| outline.closeSubPath(); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -0,0 +1,128 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-10 by Raw Material Software Ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||
| Public License (Version 2), as published by the Free Software Foundation. | |||
| A copy of the license is included in the JUCE distribution, or can be found | |||
| online at www.gnu.org/licenses. | |||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||
| ------------------------------------------------------------------------------ | |||
| To release a closed-source product which uses JUCE, commercial licenses are | |||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||
| ============================================================================== | |||
| */ | |||
| #ifndef __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| #define __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| #include "../juce_Component.h" | |||
| //============================================================================== | |||
| /** | |||
| A box with a small arrow that can be used as a temporary pop-up window to show | |||
| extra controls when a button or other component is clicked. | |||
| Using one of these is similar to having a popup menu attached to a button or | |||
| other component - but it looks fancier, and has an arrow that can indicate the | |||
| object that it applies to. | |||
| Normally, you'd create one of these on the stack and run it modally, e.g. | |||
| @code | |||
| void mouseUp (const MouseEvent& e) | |||
| { | |||
| MyContentComponent content; | |||
| content.setSize (300, 300); | |||
| CallOutBox callOut (content, *this, 0); | |||
| callOut.runModalLoop(); | |||
| } | |||
| @endcode | |||
| The call-out will resize and position itself when the content changes size. | |||
| */ | |||
| class JUCE_API CallOutBox : public Component | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates a CallOutBox. | |||
| @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). | |||
| 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 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. | |||
| */ | |||
| CallOutBox (Component& contentComponent, | |||
| Component& componentToPointTo, | |||
| Component* parentComponent); | |||
| /** Destructor. */ | |||
| ~CallOutBox(); | |||
| //============================================================================== | |||
| /** Changes the length of the arrow. */ | |||
| void setArrowSize (float newSize); | |||
| /** Updates the position and size of the box. | |||
| You shouldn't normally need to call this, unless you need more precise control over the | |||
| layout. | |||
| @param newAreaToPointTo the rectangle to make the box's arrow point to | |||
| @param newAreaToFitIn the area within which the box's position should be constrained | |||
| */ | |||
| void updatePosition (const Rectangle<int>& newAreaToPointTo, | |||
| const Rectangle<int>& newAreaToFitIn); | |||
| //============================================================================== | |||
| /** @internal */ | |||
| void paint (Graphics& g); | |||
| /** @internal */ | |||
| void resized(); | |||
| /** @internal */ | |||
| void moved(); | |||
| /** @internal */ | |||
| void childBoundsChanged (Component*); | |||
| /** @internal */ | |||
| bool hitTest (int x, int y); | |||
| /** @internal */ | |||
| void inputAttemptWhenModal(); | |||
| /** @internal */ | |||
| bool keyPressed (const KeyPress& key); | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| int borderSpace; | |||
| float arrowSize; | |||
| Component& content; | |||
| Path outline; | |||
| Point<float> targetPoint; | |||
| Rectangle<int> availableArea, targetArea; | |||
| Image background; | |||
| void refreshPath(); | |||
| void drawCallOutBoxBackground (Graphics& g, const Path& outline, int width, int height); | |||
| CallOutBox (const CallOutBox&); | |||
| CallOutBox& operator= (const CallOutBox&); | |||
| }; | |||
| #endif // __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| @@ -149,6 +149,17 @@ void DrawableComposite::resetBoundingBoxToContentArea() | |||
| RelativePoint (content.left, content.bottom))); | |||
| } | |||
| void DrawableComposite::resetContentAreaAndBoundingBoxToFitChildren() | |||
| { | |||
| const Rectangle<float> bounds (getUntransformedBounds (false)); | |||
| setContentArea (RelativeRectangle (RelativeCoordinate (bounds.getX(), true), | |||
| RelativeCoordinate (bounds.getRight(), true), | |||
| RelativeCoordinate (bounds.getY(), false), | |||
| RelativeCoordinate (bounds.getBottom(), false))); | |||
| resetBoundingBoxToContentArea(); | |||
| } | |||
| int DrawableComposite::getNumMarkers (const bool xAxis) const throw() | |||
| { | |||
| return (xAxis ? markersX : markersY).size(); | |||
| @@ -271,7 +282,7 @@ const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& o | |||
| return RelativeCoordinate(); | |||
| } | |||
| const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||
| const Rectangle<float> DrawableComposite::getUntransformedBounds (const bool includeMarkers) const | |||
| { | |||
| Rectangle<float> bounds; | |||
| @@ -279,58 +290,57 @@ const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||
| for (i = 0; i < drawables.size(); ++i) | |||
| bounds = bounds.getUnion (drawables.getUnchecked(i)->getBounds()); | |||
| if (markersX.size() > 0) | |||
| if (includeMarkers) | |||
| { | |||
| float minX = std::numeric_limits<float>::max(); | |||
| float maxX = std::numeric_limits<float>::min(); | |||
| for (i = markersX.size(); --i >= 0;) | |||
| if (markersX.size() > 0) | |||
| { | |||
| const Marker* m = markersX.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minX = jmin (minX, pos); | |||
| maxX = jmax (maxX, pos); | |||
| } | |||
| float minX = std::numeric_limits<float>::max(); | |||
| float maxX = std::numeric_limits<float>::min(); | |||
| if (minX <= maxX) | |||
| { | |||
| if (bounds.getWidth() == 0) | |||
| for (i = markersX.size(); --i >= 0;) | |||
| { | |||
| bounds.setLeft (minX); | |||
| bounds.setWidth (maxX - minX); | |||
| const Marker* m = markersX.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minX = jmin (minX, pos); | |||
| maxX = jmax (maxX, pos); | |||
| } | |||
| else | |||
| if (minX <= maxX) | |||
| { | |||
| bounds.setLeft (jmin (bounds.getX(), minX)); | |||
| bounds.setRight (jmax (bounds.getRight(), maxX)); | |||
| if (bounds.getHeight() > 0) | |||
| { | |||
| minX = jmin (minX, bounds.getX()); | |||
| maxX = jmax (maxX, bounds.getRight()); | |||
| } | |||
| bounds.setLeft (minX); | |||
| bounds.setWidth (maxX - minX); | |||
| } | |||
| } | |||
| } | |||
| if (markersY.size() > 0) | |||
| { | |||
| float minY = std::numeric_limits<float>::max(); | |||
| float maxY = std::numeric_limits<float>::min(); | |||
| for (i = markersY.size(); --i >= 0;) | |||
| if (markersY.size() > 0) | |||
| { | |||
| const Marker* m = markersY.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minY = jmin (minY, pos); | |||
| maxY = jmax (maxY, pos); | |||
| } | |||
| float minY = std::numeric_limits<float>::max(); | |||
| float maxY = std::numeric_limits<float>::min(); | |||
| if (minY <= maxY) | |||
| { | |||
| if (bounds.getHeight() == 0) | |||
| for (i = markersY.size(); --i >= 0;) | |||
| { | |||
| bounds.setTop (minY); | |||
| bounds.setHeight (maxY - minY); | |||
| const Marker* m = markersY.getUnchecked(i); | |||
| const float pos = (float) m->position.resolve (parent); | |||
| minY = jmin (minY, pos); | |||
| maxY = jmax (maxY, pos); | |||
| } | |||
| else | |||
| if (minY <= maxY) | |||
| { | |||
| bounds.setTop (jmin (bounds.getY(), minY)); | |||
| bounds.setBottom (jmax (bounds.getBottom(), maxY)); | |||
| if (bounds.getHeight() > 0) | |||
| { | |||
| minY = jmin (minY, bounds.getY()); | |||
| maxY = jmax (maxY, bounds.getBottom()); | |||
| } | |||
| bounds.setTop (minY); | |||
| bounds.setHeight (maxY - minY); | |||
| } | |||
| } | |||
| } | |||
| @@ -340,7 +350,7 @@ const Rectangle<float> DrawableComposite::getUntransformedBounds() const | |||
| const Rectangle<float> DrawableComposite::getBounds() const | |||
| { | |||
| return getUntransformedBounds().transformed (calculateTransform()); | |||
| return getUntransformedBounds (true).transformed (calculateTransform()); | |||
| } | |||
| bool DrawableComposite::hitTest (float x, float y) const | |||
| @@ -148,6 +148,11 @@ public: | |||
| */ | |||
| void resetBoundingBoxToContentArea(); | |||
| /** Resets the content area and the bounding transform to fit around the area occupied | |||
| by the child components (ignoring any markers). | |||
| */ | |||
| void resetContentAreaAndBoundingBoxToFitChildren(); | |||
| //============================================================================== | |||
| /** Represents a named marker position. | |||
| @see DrawableComposite::getMarker | |||
| @@ -248,7 +253,7 @@ private: | |||
| RelativeParallelogram bounds; | |||
| OwnedArray <Marker> markersX, markersY; | |||
| const Rectangle<float> getUntransformedBounds() const; | |||
| const Rectangle<float> getUntransformedBounds (bool includeMarkers) const; | |||
| const AffineTransform calculateTransform() const; | |||
| DrawableComposite& operator= (const DrawableComposite&); | |||
| @@ -130,13 +130,7 @@ public: | |||
| newState.parseSubElements (xml, drawable); | |||
| const Rectangle<float> bounds (drawable->getBounds()); | |||
| drawable->setContentArea (RelativeRectangle (RelativeCoordinate (bounds.getX(), true), | |||
| RelativeCoordinate (bounds.getRight(), true), | |||
| RelativeCoordinate (bounds.getY(), false), | |||
| RelativeCoordinate (bounds.getBottom(), false))); | |||
| drawable->resetBoundingBoxToContentArea(); | |||
| drawable->resetContentAreaAndBoundingBoxToFitChildren(); | |||
| return drawable; | |||
| } | |||
| @@ -199,6 +193,7 @@ private: | |||
| parseSubElements (xml, drawable); | |||
| } | |||
| drawable->resetContentAreaAndBoundingBoxToFitChildren(); | |||
| return drawable; | |||
| } | |||
| @@ -140,17 +140,20 @@ public: | |||
| //============================================================================== | |||
| /** Applies this stroke type to a path and returns the resultant stroke as another Path. | |||
| @param destPath the resultant stroked outline shape will be copied into this path. | |||
| Note that it's ok for the source and destination Paths to be | |||
| the same object, so you can easily turn a path into a stroked version | |||
| of itself. | |||
| @param sourcePath the path to use as the source | |||
| @param transform an optional transform to apply to the points from the source path | |||
| as they are being used | |||
| @param extraAccuracy if this is greater than 1.0, it will subdivide the path to | |||
| a higher resolution, which improved the quality if you'll later want | |||
| to enlarge the stroked path | |||
| @param destPath the resultant stroked outline shape will be copied into this path. | |||
| Note that it's ok for the source and destination Paths to be | |||
| the same object, so you can easily turn a path into a stroked version | |||
| of itself. | |||
| @param sourcePath the path to use as the source | |||
| @param arrowheadStartWidth the width of the arrowhead at the start of the path | |||
| @param arrowheadStartLength the length of the arrowhead at the start of the path | |||
| @param arrowheadEndWidth the width of the arrowhead at the end of the path | |||
| @param arrowheadEndLength the length of the arrowhead at the end of the path | |||
| @param transform an optional transform to apply to the points from the source path | |||
| as they are being used | |||
| @param extraAccuracy if this is greater than 1.0, it will subdivide the path to | |||
| a higher resolution, which improved the quality if you'll later want | |||
| to enlarge the stroked path | |||
| @see createDashedStroke | |||
| */ | |||
| void createStrokeWithArrowheads (Path& destPath, | |||
| @@ -584,6 +584,9 @@ | |||
| #ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ | |||
| #include "gui/components/windows/juce_AlertWindow.h" | |||
| #endif | |||
| #ifndef __JUCE_CALLOUTBOX_JUCEHEADER__ | |||
| #include "gui/components/windows/juce_CallOutBox.h" | |||
| #endif | |||
| #ifndef __JUCE_COMPONENTPEER_JUCEHEADER__ | |||
| #include "gui/components/windows/juce_ComponentPeer.h" | |||
| #endif | |||