diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h index 4d2f5b7c87..3610c5c469 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h @@ -116,6 +116,7 @@ public: ValueTree getMarker (int index) const { return group.getChild (index); } ValueTree getMarkerNamed (const String& name) const { return group.getChildWithProperty (getMarkerNameProperty(), name); } bool contains (const ValueTree& markerState) const { return markerState.isAChildOf (group); } + bool isSpecialMarker (const ValueTree& markerState) const { return false; } void createMarker (const String& name, double position); void deleteMarker (ValueTree& markerState); diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp index 2c4c6efb0c..ef0f74cf75 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp @@ -479,6 +479,15 @@ void DrawableDocument::MarkerList::deleteMarker (ValueTree& markerState) object.removeMarker (isX, markerState, getUndoManager()); } +bool DrawableDocument::MarkerList::isSpecialMarker (const ValueTree& markerState) const +{ + const String name (markerState [DrawableComposite::ValueTreeWrapper::nameProperty].toString()); + return name == DrawableComposite::contentLeftMarkerName + || name == DrawableComposite::contentRightMarkerName + || name == DrawableComposite::contentTopMarkerName + || name == DrawableComposite::contentBottomMarkerName; +} + const RelativeCoordinate DrawableDocument::MarkerList::findNamedCoordinate (const String& objectName, const String& edge) const { if (objectName == "parent") diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h index 7f055037c4..54fac999b1 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h @@ -85,6 +85,7 @@ public: bool contains (const ValueTree& markerState) const; void createMarker (const String& name, double position); void deleteMarker (ValueTree& markerState); + bool isSpecialMarker (const ValueTree& markerState) const; private: DrawableDocument& document; diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h index fcf90d029d..19a9f0f8b0 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h @@ -706,6 +706,9 @@ public: } else if (f.hasFileExtension ("jpg;jpeg;gif;png")) { + AlertWindow::showMessageBox (AlertWindow::NoIcon, + "Images", + "To add an image, first add it to the project, and then insert it into the drawable"); } } } diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorPanel.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorPanel.h index d74b8edc47..8035bf96bc 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorPanel.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorPanel.h @@ -47,6 +47,7 @@ public: addAndMakeVisible (&viewport); addAndMakeVisible (&rulerX); addAndMakeVisible (&rulerY); + addAndMakeVisible (&tooltipBar); addChildComponent (&tree); tree.setRootItemVisible (true); @@ -114,6 +115,8 @@ public: virtual SelectedItemSet& getSelection() = 0; virtual void getSelectedItemProperties (Array& newComps) = 0; + static int getRulerThickness() throw() { return 16; } + void paint (Graphics& g) { g.setTiledImageFill (background, 0, 0, 1.0f); @@ -122,31 +125,29 @@ public: void resized() { - const int toolbarHeight = 22; - - toolbar.setBounds (0, 0, getWidth(), toolbarHeight); + Rectangle area (getLocalBounds()); - int contentL = 0, contentR = getWidth(); + toolbar.setBounds (area.removeFromTop (22)); if (infoPanel != 0 && infoPanel->isVisible()) { - contentR -= 200; - infoPanel->setBounds (contentR, toolbar.getBottom(), getWidth() - contentR, getHeight() - toolbar.getBottom()); + Rectangle panel (area.removeFromRight (200)); + tooltipBar.setBounds (panel.removeFromBottom (30)); + infoPanel->setBounds (panel); } - - if (tree.isVisible()) + else { - contentL = 200; - tree.setBounds (0, toolbar.getBottom(), contentL, getHeight() - toolbar.getBottom()); + tooltipBar.setBounds (area.removeFromBottom (18)); } - const int rulerThickness = 16; - viewport.setBounds (contentL + rulerThickness, toolbar.getBottom() + rulerThickness, - contentR - contentL - rulerThickness, - getHeight() - toolbar.getBottom() - rulerThickness); + if (tree.isVisible()) + tree.setBounds (area.removeFromLeft (200)); - rulerX.setBounds (viewport.getX(), viewport.getY() - rulerThickness, viewport.getWidth(), rulerThickness); - rulerY.setBounds (viewport.getX() - rulerThickness, viewport.getY(), rulerThickness, viewport.getHeight()); + Rectangle ry (area.removeFromLeft (getRulerThickness())); + ry.removeFromTop (getRulerThickness()); + rulerY.setBounds (ry); + rulerX.setBounds (area.removeFromTop (getRulerThickness())); + viewport.setBounds (area); updateRulers(); } @@ -247,7 +248,8 @@ private: } } - void updateMarkers (MarkerListBase& markerList, EditorCanvasBase* canvas_, const int viewportWidth, const int viewportHeight) + void updateMarkers (MarkerListBase& markerList, EditorCanvasBase* canvas_, + const int viewportWidth, const int viewportHeight) { canvas = canvas_; const int num = markerList.size(); @@ -281,7 +283,7 @@ private: for (i = requiredMarkers.size(); --i >= 0;) { MarkerComponent* marker = new MarkerComponent (*this, canvas, requiredMarkers.getReference(i), - isX, isX ? getHeight() : getWidth()); + markerList.isSpecialMarker (requiredMarkers.getReference(i)), isX); markers.add (marker); getParentComponent()->addAndMakeVisible (marker); marker->updatePosition (viewportWidth, viewportHeight); @@ -340,23 +342,39 @@ private: } //============================================================================== - class MarkerComponent : public Component + class MarkerComponent : public Component, + public ChangeListener { public: MarkerComponent (RulerComponent& ruler_, EditorCanvasBase* const canvas_, - const ValueTree& marker_, bool isX_, int headSize_) - : ruler (ruler_), canvas (canvas_), marker (marker_), isX (isX_), headSize (headSize_ - 2), - isDragging (false) + const ValueTree& marker_, bool isSpecial_, bool isX_) + : ruler (ruler_), canvas (canvas_), marker (marker_), isX (isX_), headSize (getRulerThickness() - 2), + isDragging (false), isSpecial (isSpecial_), isSelected (false) { + updateSelectionState(); + + canvas->getSelection().addChangeListener (this); } ~MarkerComponent() { + canvas->getSelection().removeChangeListener (this); } void paint (Graphics& g) { - g.setColour (Colours::lightblue.withAlpha (isMouseOverOrDragging() ? 0.9f : 0.5f)); + if (isSelected || isMouseOverOrDragging()) + { + g.setColour (Colours::white.withAlpha (0.5f)); + g.strokePath (path, PathStrokeType (isSelected ? 2.5f : 1.5f)); + } + + Colour c (isSpecial ? Colours::darkgreen : Colours::darkgrey); + + if (isSelected) + c = c.overlaidWith (Colours::red.withAlpha (0.5f)); + + g.setColour (c.withAlpha (isMouseOverOrDragging() ? 0.95f : 0.6f)); g.fillPath (path); } @@ -415,15 +433,29 @@ private: if (isX) { - const float centre = getWidth() / 2 + 0.5f; - path.addLineSegment (Line (centre, 2.0f, centre, getHeight() + 1.0f), lineThickness); - path.addTriangle (1.0f, 0.0f, centre * 2.0f - 1.0f, 0.0f, centre, headSize + 1.0f); + float w = getWidth() / 2.0f; + const float centre = w + 0.5f; + w -= 2.0f; + path.startNewSubPath (centre - w, 1.0f); + path.lineTo (centre + w, 1.0f); + path.lineTo (centre + lineThickness / 2.0f, headSize); + path.lineTo (centre + lineThickness / 2.0f, (float) getHeight()); + path.lineTo (centre - lineThickness / 2.0f, (float) getHeight()); + path.lineTo (centre - lineThickness / 2.0f, headSize); + path.closeSubPath(); } else { - const float centre = getHeight() / 2 + 0.5f; - path.addLineSegment (Line (2.0f, centre, getWidth() + 1.0f, centre), lineThickness); - path.addTriangle (0.0f, centre * 2.0f - 1.0f, 0.0f, 1.0f, headSize + 1.0f, centre); + float w = getHeight() / 2.0f; + const float centre = w + 0.5f; + w -= 2.0f; + path.startNewSubPath (1.0f, centre + w); + path.lineTo (1.0f, centre - w); + path.lineTo (headSize, centre - lineThickness / 2.0f); + path.lineTo ((float) getWidth(), centre - lineThickness / 2.0f); + path.lineTo ((float) getWidth(), centre + lineThickness / 2.0f); + path.lineTo (headSize, centre + lineThickness / 2.0f); + path.closeSubPath(); } updateLabel(); @@ -471,6 +503,8 @@ private: coord.moveToAbsolute (canvas->limitMarkerPosition (ruler.xToPosition (rulerPos)), &getMarkerList()); getMarkerList().setCoordinate (marker, coord); + + canvas->handleUpdateNowIfNeeded(); } else { @@ -497,6 +531,22 @@ private: repaint(); } + void updateSelectionState() + { + bool nowSelected = canvas->getSelection().isSelected (getMarkerList().getId (marker)); + + if (isSelected != nowSelected) + { + isSelected = nowSelected; + repaint(); + } + } + + void changeListenerCallback (void*) + { + updateSelectionState(); + } + MarkerListBase& getMarkerList() { return canvas->getMarkerList (isX); } ValueTree marker; @@ -507,7 +557,7 @@ private: EditorCanvasBase* canvas; const int headSize; Path path; - bool isDragging; + bool isSpecial, isDragging, isSelected; FloatingLabelComponent label; String labelText; Point mouseDownPos; @@ -561,12 +611,85 @@ private: EditorCanvasBase* canvas; }; + //============================================================================== + class TooltipBar : public Component, + public Timer + { + public: + TooltipBar() + : lastComp (0) + { + label.setColour (Label::textColourId, Colour::greyLevel (0.15f)); + label.setColour (Label::backgroundColourId, Colour::greyLevel (0.75f)); + label.setFont (Font (13.0f)); + label.setJustificationType (Justification::centredLeft); + + addAndMakeVisible (&label); + } + + ~TooltipBar() + { + } + + void timerCallback() + { + Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); + + if (newComp != lastComp) + { + lastComp = newComp; + label.setText (findTip (newComp), false); + } + } + + void resized() + { + label.setBounds (getLocalBounds()); + } + + void visibilityChanged() + { + if (isVisible()) + startTimer (150); + else + stopTimer(); + } + + private: + Label label; + Component* lastComp; + + const String findTip (Component* c) + { + while (c != 0 && c != this) + { + TooltipClient* const tc = dynamic_cast (c); + if (tc != 0) + { + const String tip (tc->getTooltip()); + + if (tip.isNotEmpty()) + return tip; + } + + c = c->getParentComponent(); + } + + return String::empty; + } + + TooltipBar (const TooltipBar&); + TooltipBar& operator= (const TooltipBar&); + }; + //============================================================================== Toolbar toolbar; CanvasViewport viewport; RulerComponent rulerX, rulerY; ScopedPointer infoPanel; TreeView tree; + TooltipBar tooltipBar; + EditorCanvasBase* canvas; bool markersVisible, snappingEnabled; Image background; diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h index ab71f00e54..24910a8f47 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h @@ -42,6 +42,7 @@ public: virtual ValueTree getMarker (int index) const = 0; virtual ValueTree getMarkerNamed (const String& name) const = 0; virtual bool contains (const ValueTree& markerState) const = 0; + virtual bool isSpecialMarker (const ValueTree& markerState) const = 0; const String getName (const ValueTree& markerState) const { return markerState [getMarkerNameProperty()].toString(); } Value getNameAsValue (const ValueTree& markerState) const { return markerState.getPropertyAsValue (getMarkerNameProperty(), getUndoManager()); } diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 75831d04f6..94c18ee2a3 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -16199,9 +16199,9 @@ private: class ValueTree::MoveChildAction : public UndoableAction { public: - MoveChildAction (const SharedObjectPtr& target_, + MoveChildAction (const SharedObjectPtr& parent_, const int startIndex_, const int endIndex_) - : target (target_), + : parent (parent_), startIndex (startIndex_), endIndex (endIndex_) { @@ -16211,13 +16211,13 @@ public: bool perform() { - target->moveChild (startIndex, endIndex, 0); + parent->moveChild (startIndex, endIndex, 0); return true; } bool undo() { - target->moveChild (endIndex, startIndex, 0); + parent->moveChild (endIndex, startIndex, 0); return true; } @@ -16230,14 +16230,14 @@ public: { MoveChildAction* next = dynamic_cast (nextAction); - if (next != 0 && next->target == target && next->child == child) - return new MoveChildAction (target, startIndex, next->endIndex); + if (next != 0 && next->parent == parent && next->startIndex == endIndex) + return new MoveChildAction (parent, startIndex, next->endIndex); return 0; } private: - const SharedObjectPtr target, child; + const SharedObjectPtr parent; const int startIndex, endIndex; MoveChildAction (const MoveChildAction&); @@ -47441,7 +47441,7 @@ public: if (customComp != 0) { addAndMakeVisible (customComp); - customComp->setBounds (0, 0, getWidth(), getHeight()); + customComp->setBounds (getLocalBounds()); for (int i = getNumChildComponents(); --i >= 0;) if (getChildComponent (i) != customComp) @@ -47514,7 +47514,7 @@ public: void resized() { if (getNumChildComponents() > 0) - getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight()); + getChildComponent(0)->setBounds (getLocalBounds()); } const String getTooltip() @@ -47695,7 +47695,6 @@ private: ListBox::ListBox (const String& name, ListBoxModel* const model_) : Component (name), model (model_), - headerComponent (0), totalItems (0), rowHeight (22), minimumRowWidth (0), @@ -47713,7 +47712,8 @@ ListBox::ListBox (const String& name, ListBoxModel* const model_) ListBox::~ListBox() { - deleteAllChildren(); + headerComponent = 0; + viewport = 0; } void ListBox::setModel (ListBoxModel* const newModel) @@ -48221,9 +48221,8 @@ void ListBox::setOutlineThickness (const int outlineThickness_) void ListBox::setHeaderComponent (Component* const newHeaderComponent) { - if (headerComponent != newHeaderComponent) + if (newHeaderComponent != headerComponent) { - delete headerComponent; headerComponent = newHeaderComponent; addAndMakeVisible (newHeaderComponent); @@ -49277,13 +49276,13 @@ void Slider::resized() if (style == LinearBar) { if (valueBox != 0) - valueBox->setBounds (0, 0, getWidth(), getHeight()); + valueBox->setBounds (getLocalBounds()); } else { if (textBoxPos == NoTextBox) { - sliderRect.setBounds (0, 0, getWidth(), getHeight()); + sliderRect = getLocalBounds(); } else if (textBoxPos == TextBoxLeft) { @@ -55634,7 +55633,7 @@ void TreeView::paint (Graphics& g) void TreeView::resized() { - viewport->setBounds (0, 0, getWidth(), getHeight()); + viewport->setBounds (getLocalBounds()); itemsChanged(); handleAsyncUpdate(); @@ -61415,7 +61414,7 @@ void MultiDocumentPanel::resized() if (mode == MaximisedWindowsWithTabs || components.size() == numDocsBeforeTabsUsed) { for (int i = getNumChildComponents(); --i >= 0;) - getChildComponent (i)->setBounds (0, 0, getWidth(), getHeight()); + getChildComponent (i)->setBounds (getLocalBounds()); } setWantsKeyboardFocus (components.size() == 0); @@ -63136,7 +63135,7 @@ void TabbedButtonBar::resized() } } - behindFrontTab->setBounds (0, 0, getWidth(), getHeight()); + behindFrontTab->setBounds (getLocalBounds()); if (frontTab != 0) { @@ -69194,7 +69193,7 @@ public: void resized() { if (getChildComponent(0) != 0) - getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight()); + getChildComponent(0)->setBounds (getLocalBounds()); } juce_UseDebuggingNewOperator @@ -71464,7 +71463,7 @@ void PropertyPanel::paint (Graphics& g) void PropertyPanel::resized() { - viewport.setBounds (0, 0, getWidth(), getHeight()); + viewport.setBounds (getLocalBounds()); updatePropHolderLayout(); } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 7cceb5681e..bcc483047b 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -64,7 +64,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 22 +#define JUCE_BUILDNUMBER 23 /** Current Juce version number. @@ -20577,6 +20577,72 @@ public: return expanded (-deltaX, -deltaY); } + /** Removes a strip from the top of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (100, 100, 300, 50) and leave this rectangle as (100, 150, 300, 250). + + If amountToRemove is greater than the height of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromTop (const ValueType amountToRemove) throw() + { + const Rectangle r (x, y, w, jmin (amountToRemove, h)); + y += r.h; h -= r.h; + return r; + } + + /** Removes a strip from the left-hand edge of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (100, 100, 50, 300) and leave this rectangle as (150, 100, 250, 300). + + If amountToRemove is greater than the width of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromLeft (const ValueType amountToRemove) throw() + { + const Rectangle r (x, y, jmin (amountToRemove, w), h); + x += r.w; w -= r.w; + return r; + } + + /** Removes a strip from the right-hand edge of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (250, 100, 50, 300) and leave this rectangle as (100, 100, 250, 300). + + If amountToRemove is greater than the width of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromRight (ValueType amountToRemove) throw() + { + amountToRemove = jmin (amountToRemove, w); + const Rectangle r (x + w - amountToRemove, y, amountToRemove, h); + w -= amountToRemove; + return r; + } + + /** Removes a strip from the bottom of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (100, 250, 300, 50) and leave this rectangle as (100, 100, 300, 250). + + If amountToRemove is greater than the height of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromBottom (ValueType amountToRemove) throw() + { + amountToRemove = jmin (amountToRemove, h); + const Rectangle r (x, y + h - amountToRemove, w, amountToRemove); + h -= amountToRemove; + return r; + } + /** Returns true if the two rectangles are identical. */ bool operator== (const Rectangle& other) const throw() { @@ -40053,8 +40119,8 @@ private: friend class ListViewport; friend class TableListBox; ListBoxModel* model; - ListViewport* viewport; - Component* headerComponent; + ScopedPointer viewport; + ScopedPointer headerComponent; int totalItems, rowHeight, minimumRowWidth; int outlineThickness; int lastRowSelected; diff --git a/src/containers/juce_ValueTree.cpp b/src/containers/juce_ValueTree.cpp index 064a56c398..964b066e4a 100644 --- a/src/containers/juce_ValueTree.cpp +++ b/src/containers/juce_ValueTree.cpp @@ -160,9 +160,9 @@ private: class ValueTree::MoveChildAction : public UndoableAction { public: - MoveChildAction (const SharedObjectPtr& target_, + MoveChildAction (const SharedObjectPtr& parent_, const int startIndex_, const int endIndex_) - : target (target_), + : parent (parent_), startIndex (startIndex_), endIndex (endIndex_) { @@ -172,13 +172,13 @@ public: bool perform() { - target->moveChild (startIndex, endIndex, 0); + parent->moveChild (startIndex, endIndex, 0); return true; } bool undo() { - target->moveChild (endIndex, startIndex, 0); + parent->moveChild (endIndex, startIndex, 0); return true; } @@ -191,14 +191,14 @@ public: { MoveChildAction* next = dynamic_cast (nextAction); - if (next != 0 && next->target == target && next->child == child) - return new MoveChildAction (target, startIndex, next->endIndex); + if (next != 0 && next->parent == parent && next->startIndex == endIndex) + return new MoveChildAction (parent, startIndex, next->endIndex); return 0; } private: - const SharedObjectPtr target, child; + const SharedObjectPtr parent; const int startIndex, endIndex; MoveChildAction (const MoveChildAction&); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index d236de2a92..29e61e4ee3 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 22 +#define JUCE_BUILDNUMBER 23 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_ListBox.cpp b/src/gui/components/controls/juce_ListBox.cpp index 2f95ac9e17..2dd0e56e47 100644 --- a/src/gui/components/controls/juce_ListBox.cpp +++ b/src/gui/components/controls/juce_ListBox.cpp @@ -73,7 +73,7 @@ public: if (customComp != 0) { addAndMakeVisible (customComp); - customComp->setBounds (0, 0, getWidth(), getHeight()); + customComp->setBounds (getLocalBounds()); for (int i = getNumChildComponents(); --i >= 0;) if (getChildComponent (i) != customComp) @@ -146,7 +146,7 @@ public: void resized() { if (getNumChildComponents() > 0) - getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight()); + getChildComponent(0)->setBounds (getLocalBounds()); } const String getTooltip() @@ -333,7 +333,6 @@ private: ListBox::ListBox (const String& name, ListBoxModel* const model_) : Component (name), model (model_), - headerComponent (0), totalItems (0), rowHeight (22), minimumRowWidth (0), @@ -351,7 +350,8 @@ ListBox::ListBox (const String& name, ListBoxModel* const model_) ListBox::~ListBox() { - deleteAllChildren(); + headerComponent = 0; + viewport = 0; } void ListBox::setModel (ListBoxModel* const newModel) @@ -865,9 +865,8 @@ void ListBox::setOutlineThickness (const int outlineThickness_) void ListBox::setHeaderComponent (Component* const newHeaderComponent) { - if (headerComponent != newHeaderComponent) + if (newHeaderComponent != headerComponent) { - delete headerComponent; headerComponent = newHeaderComponent; addAndMakeVisible (newHeaderComponent); diff --git a/src/gui/components/controls/juce_ListBox.h b/src/gui/components/controls/juce_ListBox.h index 38bf01e87f..b880c5eb84 100644 --- a/src/gui/components/controls/juce_ListBox.h +++ b/src/gui/components/controls/juce_ListBox.h @@ -568,8 +568,8 @@ private: friend class ListViewport; friend class TableListBox; ListBoxModel* model; - ListViewport* viewport; - Component* headerComponent; + ScopedPointer viewport; + ScopedPointer headerComponent; int totalItems, rowHeight, minimumRowWidth; int outlineThickness; int lastRowSelected; diff --git a/src/gui/components/controls/juce_Slider.cpp b/src/gui/components/controls/juce_Slider.cpp index 13057adcb4..ff81a8e210 100644 --- a/src/gui/components/controls/juce_Slider.cpp +++ b/src/gui/components/controls/juce_Slider.cpp @@ -880,13 +880,13 @@ void Slider::resized() if (style == LinearBar) { if (valueBox != 0) - valueBox->setBounds (0, 0, getWidth(), getHeight()); + valueBox->setBounds (getLocalBounds()); } else { if (textBoxPos == NoTextBox) { - sliderRect.setBounds (0, 0, getWidth(), getHeight()); + sliderRect = getLocalBounds(); } else if (textBoxPos == TextBoxLeft) { diff --git a/src/gui/components/controls/juce_TreeView.cpp b/src/gui/components/controls/juce_TreeView.cpp index 773c4501d1..e5e4be81d0 100644 --- a/src/gui/components/controls/juce_TreeView.cpp +++ b/src/gui/components/controls/juce_TreeView.cpp @@ -650,7 +650,7 @@ void TreeView::paint (Graphics& g) void TreeView::resized() { - viewport->setBounds (0, 0, getWidth(), getHeight()); + viewport->setBounds (getLocalBounds()); itemsChanged(); handleAsyncUpdate(); diff --git a/src/gui/components/layout/juce_MultiDocumentPanel.cpp b/src/gui/components/layout/juce_MultiDocumentPanel.cpp index 2d91e527b8..d2bbc7ffe0 100644 --- a/src/gui/components/layout/juce_MultiDocumentPanel.cpp +++ b/src/gui/components/layout/juce_MultiDocumentPanel.cpp @@ -464,7 +464,7 @@ void MultiDocumentPanel::resized() if (mode == MaximisedWindowsWithTabs || components.size() == numDocsBeforeTabsUsed) { for (int i = getNumChildComponents(); --i >= 0;) - getChildComponent (i)->setBounds (0, 0, getWidth(), getHeight()); + getChildComponent (i)->setBounds (getLocalBounds()); } setWantsKeyboardFocus (components.size() == 0); diff --git a/src/gui/components/layout/juce_TabbedButtonBar.cpp b/src/gui/components/layout/juce_TabbedButtonBar.cpp index 8fa3759fe0..164fbad800 100644 --- a/src/gui/components/layout/juce_TabbedButtonBar.cpp +++ b/src/gui/components/layout/juce_TabbedButtonBar.cpp @@ -483,7 +483,7 @@ void TabbedButtonBar::resized() } } - behindFrontTab->setBounds (0, 0, getWidth(), getHeight()); + behindFrontTab->setBounds (getLocalBounds()); if (frontTab != 0) { diff --git a/src/gui/components/menus/juce_PopupMenu.cpp b/src/gui/components/menus/juce_PopupMenu.cpp index 4b5d03004e..70bf9f0837 100644 --- a/src/gui/components/menus/juce_PopupMenu.cpp +++ b/src/gui/components/menus/juce_PopupMenu.cpp @@ -1397,7 +1397,7 @@ public: void resized() { if (getChildComponent(0) != 0) - getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight()); + getChildComponent(0)->setBounds (getLocalBounds()); } juce_UseDebuggingNewOperator diff --git a/src/gui/components/properties/juce_PropertyPanel.cpp b/src/gui/components/properties/juce_PropertyPanel.cpp index fb751cf591..c9c22268d4 100644 --- a/src/gui/components/properties/juce_PropertyPanel.cpp +++ b/src/gui/components/properties/juce_PropertyPanel.cpp @@ -250,7 +250,7 @@ void PropertyPanel::paint (Graphics& g) void PropertyPanel::resized() { - viewport.setBounds (0, 0, getWidth(), getHeight()); + viewport.setBounds (getLocalBounds()); updatePropHolderLayout(); } diff --git a/src/gui/graphics/geometry/juce_Rectangle.h b/src/gui/graphics/geometry/juce_Rectangle.h index ffcee6934d..1505ba09bb 100644 --- a/src/gui/graphics/geometry/juce_Rectangle.h +++ b/src/gui/graphics/geometry/juce_Rectangle.h @@ -313,6 +313,72 @@ public: return expanded (-deltaX, -deltaY); } + /** Removes a strip from the top of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (100, 100, 300, 50) and leave this rectangle as (100, 150, 300, 250). + + If amountToRemove is greater than the height of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromTop (const ValueType amountToRemove) throw() + { + const Rectangle r (x, y, w, jmin (amountToRemove, h)); + y += r.h; h -= r.h; + return r; + } + + /** Removes a strip from the left-hand edge of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (100, 100, 50, 300) and leave this rectangle as (150, 100, 250, 300). + + If amountToRemove is greater than the width of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromLeft (const ValueType amountToRemove) throw() + { + const Rectangle r (x, y, jmin (amountToRemove, w), h); + x += r.w; w -= r.w; + return r; + } + + /** Removes a strip from the right-hand edge of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (250, 100, 50, 300) and leave this rectangle as (100, 100, 250, 300). + + If amountToRemove is greater than the width of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromRight (ValueType amountToRemove) throw() + { + amountToRemove = jmin (amountToRemove, w); + const Rectangle r (x + w - amountToRemove, y, amountToRemove, h); + w -= amountToRemove; + return r; + } + + /** Removes a strip from the bottom of this rectangle, reducing this rectangle + by the specified amount and returning the section that was removed. + + E.g. if this rectangle is (100, 100, 300, 300) and amountToRemove is 50, this will + return (100, 250, 300, 50) and leave this rectangle as (100, 100, 300, 250). + + If amountToRemove is greater than the height of this rectangle, it'll be clipped to + that value. + */ + const Rectangle removeFromBottom (ValueType amountToRemove) throw() + { + amountToRemove = jmin (amountToRemove, h); + const Rectangle r (x, y + h - amountToRemove, w, amountToRemove); + h -= amountToRemove; + return r; + } + //============================================================================== /** Returns true if the two rectangles are identical. */ bool operator== (const Rectangle& other) const throw()