| @@ -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); | |||
| @@ -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") | |||
| @@ -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; | |||
| @@ -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"); | |||
| } | |||
| } | |||
| } | |||
| @@ -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<String>& getSelection() = 0; | |||
| virtual void getSelectedItemProperties (Array<PropertyComponent*>& 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<int> 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<int> 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<int> 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<float> (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<float> (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<int> 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 <TooltipClient*> (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> infoPanel; | |||
| TreeView tree; | |||
| TooltipBar tooltipBar; | |||
| EditorCanvasBase* canvas; | |||
| bool markersVisible, snappingEnabled; | |||
| Image background; | |||
| @@ -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()); } | |||
| @@ -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 <MoveChildAction*> (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(); | |||
| } | |||
| @@ -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<ListViewport> viewport; | |||
| ScopedPointer<Component> headerComponent; | |||
| int totalItems, rowHeight, minimumRowWidth; | |||
| int outlineThickness; | |||
| int lastRowSelected; | |||
| @@ -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 <MoveChildAction*> (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&); | |||
| @@ -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. | |||
| @@ -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); | |||
| @@ -568,8 +568,8 @@ private: | |||
| friend class ListViewport; | |||
| friend class TableListBox; | |||
| ListBoxModel* model; | |||
| ListViewport* viewport; | |||
| Component* headerComponent; | |||
| ScopedPointer<ListViewport> viewport; | |||
| ScopedPointer<Component> headerComponent; | |||
| int totalItems, rowHeight, minimumRowWidth; | |||
| int outlineThickness; | |||
| int lastRowSelected; | |||
| @@ -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) | |||
| { | |||
| @@ -650,7 +650,7 @@ void TreeView::paint (Graphics& g) | |||
| void TreeView::resized() | |||
| { | |||
| viewport->setBounds (0, 0, getWidth(), getHeight()); | |||
| viewport->setBounds (getLocalBounds()); | |||
| itemsChanged(); | |||
| handleAsyncUpdate(); | |||
| @@ -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); | |||
| @@ -483,7 +483,7 @@ void TabbedButtonBar::resized() | |||
| } | |||
| } | |||
| behindFrontTab->setBounds (0, 0, getWidth(), getHeight()); | |||
| behindFrontTab->setBounds (getLocalBounds()); | |||
| if (frontTab != 0) | |||
| { | |||
| @@ -1397,7 +1397,7 @@ public: | |||
| void resized() | |||
| { | |||
| if (getChildComponent(0) != 0) | |||
| getChildComponent(0)->setBounds (0, 0, getWidth(), getHeight()); | |||
| getChildComponent(0)->setBounds (getLocalBounds()); | |||
| } | |||
| juce_UseDebuggingNewOperator | |||
| @@ -250,7 +250,7 @@ void PropertyPanel::paint (Graphics& g) | |||
| void PropertyPanel::resized() | |||
| { | |||
| viewport.setBounds (0, 0, getWidth(), getHeight()); | |||
| viewport.setBounds (getLocalBounds()); | |||
| updatePropHolderLayout(); | |||
| } | |||
| @@ -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() | |||