| @@ -282,16 +282,12 @@ const ValueTree ComponentDocument::getComponent (int index) const | |||||
| const ValueTree ComponentDocument::getComponentWithMemberName (const String& name) const | const ValueTree ComponentDocument::getComponentWithMemberName (const String& name) const | ||||
| { | { | ||||
| const ValueTree comps (getComponentGroup()); | |||||
| for (int i = comps.getNumChildren(); --i >= 0;) | |||||
| { | |||||
| const ValueTree v (comps.getChild(i)); | |||||
| if (v [memberNameProperty] == name) | |||||
| return v; | |||||
| } | |||||
| return getComponentGroup().getChildWithProperty (memberNameProperty, name); | |||||
| } | |||||
| return ValueTree::invalid; | |||||
| const ValueTree ComponentDocument::getComponentWithID (const String& uid) const | |||||
| { | |||||
| return getComponentGroup().getChildWithProperty (idProperty, uid); | |||||
| } | } | ||||
| Component* ComponentDocument::createComponent (int index) | Component* ComponentDocument::createComponent (int index) | ||||
| @@ -301,8 +297,8 @@ Component* ComponentDocument::createComponent (int index) | |||||
| if (v.isValid()) | if (v.isValid()) | ||||
| { | { | ||||
| Component* c = ComponentTypeManager::getInstance()->createFromStoredType (*this, v); | Component* c = ComponentTypeManager::getInstance()->createFromStoredType (*this, v); | ||||
| c->getProperties().set (idProperty, v[idProperty]); | |||||
| jassert (c->getProperties()[idProperty].toString().isNotEmpty()); | |||||
| c->getProperties().set (jucerIDProperty, v[idProperty]); | |||||
| jassert (getJucerIDFor (c).isNotEmpty()); | |||||
| return c; | return c; | ||||
| } | } | ||||
| @@ -490,25 +486,11 @@ const ValueTree ComponentDocument::getComponentState (Component* comp) const | |||||
| return ValueTree::invalid; | return ValueTree::invalid; | ||||
| } | } | ||||
| void ComponentDocument::getComponentProperties (Array <PropertyComponent*>& props, Component* comp) | |||||
| { | |||||
| ValueTree v (getComponentState (comp)); | |||||
| if (v.isValid()) | |||||
| { | |||||
| ComponentTypeHandler* handler = ComponentTypeManager::getInstance()->getHandlerFor (v.getType()); | |||||
| jassert (handler != 0); | |||||
| if (handler != 0) | |||||
| handler->createPropertyEditors (*this, v, props); | |||||
| } | |||||
| } | |||||
| bool ComponentDocument::isStateForComponent (const ValueTree& storedState, Component* comp) const | bool ComponentDocument::isStateForComponent (const ValueTree& storedState, Component* comp) const | ||||
| { | { | ||||
| jassert (comp != 0); | jassert (comp != 0); | ||||
| jassert (! storedState [idProperty].isVoid()); | jassert (! storedState [idProperty].isVoid()); | ||||
| return storedState [idProperty] == comp->getProperties() [idProperty]; | |||||
| return storedState [idProperty] == getJucerIDFor (comp); | |||||
| } | } | ||||
| void ComponentDocument::removeComponent (const ValueTree& state) | void ComponentDocument::removeComponent (const ValueTree& state) | ||||
| @@ -594,6 +576,7 @@ void ComponentDocument::MarkerList::createMarker (const String& name, int positi | |||||
| ValueTree marker (markerTag); | ValueTree marker (markerTag); | ||||
| marker.setProperty (markerNameProperty, document.getNonexistentMarkerName (name), 0); | marker.setProperty (markerNameProperty, document.getNonexistentMarkerName (name), 0); | ||||
| marker.setProperty (markerPosProperty, Coordinate (position, isX).toString(), 0); | marker.setProperty (markerPosProperty, Coordinate (position, isX).toString(), 0); | ||||
| marker.setProperty (idProperty, createAlphaNumericUID(), 0); | |||||
| group.addChild (marker, -1, document.getUndoManager()); | group.addChild (marker, -1, document.getUndoManager()); | ||||
| } | } | ||||
| @@ -617,6 +600,24 @@ const Coordinate ComponentDocument::MarkerList::findMarker (const String& name, | |||||
| return Coordinate (isX); | return Coordinate (isX); | ||||
| } | } | ||||
| void ComponentDocument::MarkerList::createMarkerProperties (Array <PropertyComponent*>& props, ValueTree& marker) | |||||
| { | |||||
| props.add (new TextPropertyComponent (getNameAsValue (marker), "Marker Name", 256, false)); | |||||
| } | |||||
| bool ComponentDocument::MarkerList::createProperties (Array <PropertyComponent*>& props, const String& itemId) | |||||
| { | |||||
| ValueTree marker (group.getChildWithProperty (idProperty, itemId)); | |||||
| if (marker.isValid()) | |||||
| { | |||||
| createMarkerProperties (props, marker); | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| const String ComponentDocument::getNonexistentMarkerName (const String& name) | const String ComponentDocument::getNonexistentMarkerName (const String& name) | ||||
| { | { | ||||
| String n (makeValidCppIdentifier (name, false, true, false)); | String n (makeValidCppIdentifier (name, false, true, false)); | ||||
| @@ -628,12 +629,59 @@ const String ComponentDocument::getNonexistentMarkerName (const String& name) | |||||
| return n; | return n; | ||||
| } | } | ||||
| //============================================================================== | |||||
| bool ComponentDocument::createItemProperties (Array <PropertyComponent*>& props, const String& itemId) | |||||
| { | |||||
| ValueTree comp (getComponentWithID (itemId)); | |||||
| if (comp.isValid()) | |||||
| { | |||||
| ComponentTypeHandler* handler = ComponentTypeManager::getInstance()->getHandlerFor (comp.getType()); | |||||
| jassert (handler != 0); | |||||
| if (handler != 0) | |||||
| handler->createPropertyEditors (*this, comp, props); | |||||
| return true; | |||||
| } | |||||
| if (markersX->createProperties (props, itemId) | |||||
| || markersY->createProperties (props, itemId)) | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| void ComponentDocument::createItemProperties (Array <PropertyComponent*>& props, const StringArray& selectedItemIds) | |||||
| { | |||||
| if (selectedItemIds.size() != 1) | |||||
| return; //xxx | |||||
| for (int i = 0; i < selectedItemIds.size(); ++i) | |||||
| createItemProperties (props, selectedItemIds[i]); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| UndoManager* ComponentDocument::getUndoManager() const | UndoManager* ComponentDocument::getUndoManager() const | ||||
| { | { | ||||
| return &undoManager; | return &undoManager; | ||||
| } | } | ||||
| //============================================================================== | |||||
| const char* const ComponentDocument::jucerIDProperty = "jucerID"; | |||||
| const String ComponentDocument::getJucerIDFor (Component* c) | |||||
| { | |||||
| if (c == 0) | |||||
| { | |||||
| jassertfalse; | |||||
| return String::empty; | |||||
| } | |||||
| jassert (c->getProperties().contains (jucerIDProperty)); | |||||
| return c->getProperties() [jucerIDProperty]; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void ComponentDocument::createClassProperties (Array <PropertyComponent*>& props) | void ComponentDocument::createClassProperties (Array <PropertyComponent*>& props) | ||||
| { | { | ||||
| @@ -61,11 +61,11 @@ public: | |||||
| int getNumComponents() const; | int getNumComponents() const; | ||||
| const ValueTree getComponent (int index) const; | const ValueTree getComponent (int index) const; | ||||
| const ValueTree getComponentWithMemberName (const String& name) const; | const ValueTree getComponentWithMemberName (const String& name) const; | ||||
| const ValueTree getComponentWithID (const String& uid) const; | |||||
| Component* createComponent (int index); | Component* createComponent (int index); | ||||
| void updateComponent (Component* comp); | void updateComponent (Component* comp); | ||||
| bool containsComponent (Component* comp) const; | bool containsComponent (Component* comp) const; | ||||
| const ValueTree getComponentState (Component* comp) const; | const ValueTree getComponentState (Component* comp) const; | ||||
| void getComponentProperties (Array <PropertyComponent*>& props, Component* comp); | |||||
| bool isStateForComponent (const ValueTree& storedState, Component* comp) const; | bool isStateForComponent (const ValueTree& storedState, Component* comp) const; | ||||
| void removeComponent (const ValueTree& state); | void removeComponent (const ValueTree& state); | ||||
| const RectangleCoordinates getCoordsFor (const ValueTree& componentState) const; | const RectangleCoordinates getCoordsFor (const ValueTree& componentState) const; | ||||
| @@ -102,6 +102,9 @@ public: | |||||
| // for Coordinate::MarkerResolver: | // for Coordinate::MarkerResolver: | ||||
| const Coordinate findMarker (const String& name, bool isHorizontal) const; | const Coordinate findMarker (const String& name, bool isHorizontal) const; | ||||
| bool createProperties (Array <PropertyComponent*>& props, const String& itemId); | |||||
| void createMarkerProperties (Array <PropertyComponent*>& props, ValueTree& marker); | |||||
| private: | private: | ||||
| ComponentDocument& document; | ComponentDocument& document; | ||||
| ValueTree group; | ValueTree group; | ||||
| @@ -117,6 +120,9 @@ public: | |||||
| const String getNonexistentMarkerName (const String& name); | const String getNonexistentMarkerName (const String& name); | ||||
| //============================================================================== | |||||
| void createItemProperties (Array <PropertyComponent*>& props, const StringArray& selectedItemIds); | |||||
| //============================================================================== | //============================================================================== | ||||
| void beginDrag (const Array<Component*>& items, const MouseEvent& e, | void beginDrag (const Array<Component*>& items, const MouseEvent& e, | ||||
| Component* parentForOverlays, const ResizableBorderComponent::Zone& zone); | Component* parentForOverlays, const ResizableBorderComponent::Zone& zone); | ||||
| @@ -139,6 +145,9 @@ public: | |||||
| static const char* const markerNameProperty; | static const char* const markerNameProperty; | ||||
| static const char* const markerPosProperty; | static const char* const markerPosProperty; | ||||
| static const char* const jucerIDProperty; | |||||
| static const String getJucerIDFor (Component* c); | |||||
| private: | private: | ||||
| Project* project; | Project* project; | ||||
| File cppFile; | File cppFile; | ||||
| @@ -158,6 +167,8 @@ private: | |||||
| void writeCode (OutputStream& cpp, OutputStream& header); | void writeCode (OutputStream& cpp, OutputStream& header); | ||||
| void writeMetadata (OutputStream& out); | void writeMetadata (OutputStream& out); | ||||
| bool createItemProperties (Array <PropertyComponent*>& props, const String& itemId); | |||||
| }; | }; | ||||
| @@ -104,7 +104,7 @@ public: | |||||
| setBoundsInTargetSpace (component->getBounds().expanded (borderThickness, borderThickness)); | setBoundsInTargetSpace (component->getBounds().expanded (borderThickness, borderThickness)); | ||||
| } | } | ||||
| uint32 getTargetComponentUID() const { return component == 0 ? 0 : component->getComponentUID(); } | |||||
| const String getTargetComponentID() const { return component == 0 ? String::empty : ComponentDocument::getJucerIDFor (component); } | |||||
| //============================================================================== | //============================================================================== | ||||
| class SizeGuideComponent : public OverlayItemComponent, | class SizeGuideComponent : public OverlayItemComponent, | ||||
| @@ -300,6 +300,8 @@ public: | |||||
| toFront (false); | toFront (false); | ||||
| updateLabel(); | updateLabel(); | ||||
| canvas.getSelection().selectOnly (marker [ComponentDocument::idProperty]); | |||||
| if (e.mods.isPopupMenu()) | if (e.mods.isPopupMenu()) | ||||
| { | { | ||||
| isDragging = false; | isDragging = false; | ||||
| @@ -394,7 +396,7 @@ public: | |||||
| if (! doc.containsComponent (c)) | if (! doc.containsComponent (c)) | ||||
| { | { | ||||
| selection.deselect (c->getComponentUID()); | |||||
| selection.deselect (ComponentDocument::getJucerIDFor (c)); | |||||
| delete c; | delete c; | ||||
| } | } | ||||
| } | } | ||||
| @@ -418,11 +420,16 @@ public: | |||||
| } | } | ||||
| // Make sure the z-order is correct.. | // Make sure the z-order is correct.. | ||||
| for (i = 0; i < num - 1; ++i) | |||||
| componentsInOrder.getUnchecked(i)->toBehind (componentsInOrder.getUnchecked (i + 1)); | |||||
| if (num > 0) | |||||
| { | |||||
| componentsInOrder.getLast()->toFront (false); | |||||
| for (i = num - 1; --i >= 0;) | |||||
| componentsInOrder.getUnchecked(i)->toBehind (componentsInOrder.getUnchecked (i + 1)); | |||||
| } | |||||
| } | } | ||||
| Component* getComponentForState (ComponentDocument& doc, const ValueTree& state) | |||||
| Component* getComponentForState (ComponentDocument& doc, const ValueTree& state) const | |||||
| { | { | ||||
| for (int i = getNumChildComponents(); --i >= 0;) | for (int i = getNumChildComponents(); --i >= 0;) | ||||
| { | { | ||||
| @@ -435,6 +442,19 @@ public: | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| Component* findComponentWithID (const String& uid) const | |||||
| { | |||||
| for (int i = getNumChildComponents(); --i >= 0;) | |||||
| { | |||||
| Component* const c = getChildComponent(i); | |||||
| if (ComponentDocument::getJucerIDFor (c) == uid) | |||||
| return c; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| Component* findComponentAt (const Point<int>& pos) const | Component* findComponentAt (const Point<int>& pos) const | ||||
| { | { | ||||
| for (int i = getNumChildComponents(); --i >= 0;) | for (int i = getNumChildComponents(); --i >= 0;) | ||||
| @@ -453,7 +473,7 @@ public: | |||||
| { | { | ||||
| Component* c = getChildComponent(i); | Component* c = getChildComponent(i); | ||||
| if (c->getBounds().intersects (lassoArea)) | if (c->getBounds().intersects (lassoArea)) | ||||
| itemsFound.add (c->getComponentUID()); | |||||
| itemsFound.add (ComponentDocument::getJucerIDFor (c)); | |||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -493,7 +513,7 @@ public: | |||||
| void mouseDown (const MouseEvent& e) | void mouseDown (const MouseEvent& e) | ||||
| { | { | ||||
| lasso = 0; | lasso = 0; | ||||
| mouseDownCompUID = 0; | |||||
| mouseDownCompUID = String::empty; | |||||
| isDraggingClickedComp = false; | isDraggingClickedComp = false; | ||||
| Component* underMouse = canvas.getComponentHolder()->findComponentAt (e.getEventRelativeTo (canvas.getComponentHolder()).getPosition()); | Component* underMouse = canvas.getComponentHolder()->findComponentAt (e.getEventRelativeTo (canvas.getComponentHolder()).getPosition()); | ||||
| @@ -502,8 +522,8 @@ public: | |||||
| { | { | ||||
| if (underMouse != 0) | if (underMouse != 0) | ||||
| { | { | ||||
| if (! canvas.getSelection().isSelected (underMouse->getComponentUID())) | |||||
| canvas.getSelection().selectOnly (underMouse->getComponentUID()); | |||||
| if (! canvas.getSelection().isSelected (ComponentDocument::getJucerIDFor (underMouse))) | |||||
| canvas.getSelection().selectOnly (ComponentDocument::getJucerIDFor (underMouse)); | |||||
| } | } | ||||
| PopupMenu m; | PopupMenu m; | ||||
| @@ -528,12 +548,14 @@ public: | |||||
| { | { | ||||
| if (underMouse == 0 || e.mods.isAltDown()) | if (underMouse == 0 || e.mods.isAltDown()) | ||||
| { | { | ||||
| canvas.deselectNonComponents(); | |||||
| addAndMakeVisible (lasso = new LassoComponent <SelectedItems::ItemType>()); | addAndMakeVisible (lasso = new LassoComponent <SelectedItems::ItemType>()); | ||||
| lasso->beginLasso (e, this); | lasso->beginLasso (e, this); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| mouseDownCompUID = underMouse->getComponentUID(); | |||||
| mouseDownCompUID = ComponentDocument::getJucerIDFor (underMouse); | |||||
| canvas.deselectNonComponents(); | |||||
| mouseDownResult = canvas.getSelection().addToSelectionOnMouseDown (mouseDownCompUID, e.mods); | mouseDownResult = canvas.getSelection().addToSelectionOnMouseDown (mouseDownCompUID, e.mods); | ||||
| updateResizeFrames(); | updateResizeFrames(); | ||||
| @@ -549,7 +571,7 @@ public: | |||||
| { | { | ||||
| lasso->dragLasso (e); | lasso->dragLasso (e); | ||||
| } | } | ||||
| else if (mouseDownCompUID != 0 && (! e.mouseWasClicked()) && (! e.mods.isPopupMenu())) | |||||
| else if (mouseDownCompUID.isNotEmpty() && (! e.mouseWasClicked()) && (! e.mods.isPopupMenu())) | |||||
| { | { | ||||
| if (! isDraggingClickedComp) | if (! isDraggingClickedComp) | ||||
| { | { | ||||
| @@ -653,40 +675,24 @@ private: | |||||
| ValueTree markerRootX, markerRootY; | ValueTree markerRootX, markerRootY; | ||||
| ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso; | ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso; | ||||
| bool mouseDownResult, isDraggingClickedComp; | bool mouseDownResult, isDraggingClickedComp; | ||||
| uint32 mouseDownCompUID; | |||||
| SelectedItems::ItemType mouseDownCompUID; | |||||
| ComponentDocument& getDocument() { return canvas.getDocument(); } | ComponentDocument& getDocument() { return canvas.getDocument(); } | ||||
| Component* getComponentWithUID (const uint32 uid) const | |||||
| { | |||||
| for (int i = canvas.getComponentHolder()->getNumChildComponents(); --i >= 0;) | |||||
| { | |||||
| Component* c = canvas.getComponentHolder()->getChildComponent(i); | |||||
| if (c->getComponentUID() == uid) | |||||
| return c; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| void updateResizeFrames() | void updateResizeFrames() | ||||
| { | { | ||||
| SelectedItems& selection = canvas.getSelection(); | SelectedItems& selection = canvas.getSelection(); | ||||
| StringArray requiredIds (canvas.getSelectedIds()); | |||||
| Array<int> requiredIds; | |||||
| int i; | int i; | ||||
| for (i = selection.getNumSelected(); --i >= 0;) | |||||
| requiredIds.add (selection.getSelectedItem(i)); | |||||
| for (i = getNumChildComponents(); --i >= 0;) | for (i = getNumChildComponents(); --i >= 0;) | ||||
| { | { | ||||
| ComponentResizeFrame* resizer = dynamic_cast <ComponentResizeFrame*> (getChildComponent(i)); | ComponentResizeFrame* resizer = dynamic_cast <ComponentResizeFrame*> (getChildComponent(i)); | ||||
| if (resizer != 0) | if (resizer != 0) | ||||
| { | { | ||||
| if (selection.isSelected (resizer->getTargetComponentUID())) | |||||
| requiredIds.removeValue (resizer->getTargetComponentUID()); | |||||
| if (selection.isSelected (resizer->getTargetComponentID())) | |||||
| requiredIds.removeString (resizer->getTargetComponentID()); | |||||
| else | else | ||||
| delete resizer; | delete resizer; | ||||
| } | } | ||||
| @@ -694,7 +700,7 @@ private: | |||||
| for (i = requiredIds.size(); --i >= 0;) | for (i = requiredIds.size(); --i >= 0;) | ||||
| { | { | ||||
| Component* c = getComponentWithUID (requiredIds.getUnchecked(i)); | |||||
| Component* c = canvas.getComponentHolder()->findComponentWithID (requiredIds[i]); | |||||
| if (c != 0) | if (c != 0) | ||||
| { | { | ||||
| @@ -951,16 +957,19 @@ void ComponentEditorCanvas::updateComponents() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void ComponentEditorCanvas::getSelectedItemProperties (Array <PropertyComponent*>& props) | |||||
| const StringArray ComponentEditorCanvas::getSelectedIds() const | |||||
| { | { | ||||
| //xxx needs to handle multiple selections.. | |||||
| StringArray ids; | |||||
| const int num = selection.getNumSelected(); | |||||
| for (int i = 0; i < num; ++i) | |||||
| ids.add (selection.getSelectedItem(i)); | |||||
| if (selection.getNumSelected() == 1) | |||||
| { | |||||
| Component* c = getComponentForUID (selection.getSelectedItem (0)); | |||||
| jassert (c != 0); | |||||
| getDocument().getComponentProperties (props, c); | |||||
| } | |||||
| return ids; | |||||
| } | |||||
| void ComponentEditorCanvas::getSelectedItemProperties (Array <PropertyComponent*>& props) | |||||
| { | |||||
| getDocument().createItemProperties (props, getSelectedIds()); | |||||
| } | } | ||||
| void ComponentEditorCanvas::deleteSelection() | void ComponentEditorCanvas::deleteSelection() | ||||
| @@ -969,7 +978,7 @@ void ComponentEditorCanvas::deleteSelection() | |||||
| for (int i = selection.getNumSelected(); --i >= 0;) | for (int i = selection.getNumSelected(); --i >= 0;) | ||||
| { | { | ||||
| Component* c = getComponentForUID (selection.getSelectedItem (0)); | |||||
| Component* c = componentHolder->findComponentWithID (selection.getSelectedItem (0)); | |||||
| if (c != 0) | if (c != 0) | ||||
| getDocument().removeComponent (getDocument().getComponentState (c)); | getDocument().removeComponent (getDocument().getComponentState (c)); | ||||
| @@ -980,6 +989,13 @@ void ComponentEditorCanvas::deleteSelection() | |||||
| getDocument().beginNewTransaction(); | getDocument().beginNewTransaction(); | ||||
| } | } | ||||
| void ComponentEditorCanvas::deselectNonComponents() | |||||
| { | |||||
| for (int i = getSelection().getNumSelected(); --i >= 0;) | |||||
| if (! getDocument().getComponentWithID (getSelection().getSelectedItem (i)).isValid()) | |||||
| getSelection().deselect (getSelection().getSelectedItem (i)); | |||||
| } | |||||
| void ComponentEditorCanvas::selectionToFront() | void ComponentEditorCanvas::selectionToFront() | ||||
| { | { | ||||
| getDocument().beginNewTransaction(); | getDocument().beginNewTransaction(); | ||||
| @@ -990,11 +1006,10 @@ void ComponentEditorCanvas::selectionToFront() | |||||
| const ValueTree comp (getDocument().getComponent (index)); | const ValueTree comp (getDocument().getComponent (index)); | ||||
| Component* c = componentHolder->getComponentForState (getDocument(), comp); | Component* c = componentHolder->getComponentForState (getDocument(), comp); | ||||
| if (c != 0 && selection.isSelected (c->getComponentUID())) | |||||
| if (c != 0 && selection.isSelected (ComponentDocument::getJucerIDFor (c))) | |||||
| { | { | ||||
| ValueTree parent (comp.getParent()); | ValueTree parent (comp.getParent()); | ||||
| parent.removeChild (comp, getDocument().getUndoManager()); | |||||
| parent.addChild (comp, -1, getDocument().getUndoManager()); | |||||
| parent.moveChild (parent.indexOf (comp), -1, getDocument().getUndoManager()); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -1015,11 +1030,10 @@ void ComponentEditorCanvas::selectionToBack() | |||||
| const ValueTree comp (getDocument().getComponent (index)); | const ValueTree comp (getDocument().getComponent (index)); | ||||
| Component* c = componentHolder->getComponentForState (getDocument(), comp); | Component* c = componentHolder->getComponentForState (getDocument(), comp); | ||||
| if (c != 0 && selection.isSelected (c->getComponentUID())) | |||||
| if (c != 0 && selection.isSelected (ComponentDocument::getJucerIDFor (c))) | |||||
| { | { | ||||
| ValueTree parent (comp.getParent()); | ValueTree parent (comp.getParent()); | ||||
| parent.removeChild (comp, getDocument().getUndoManager()); | |||||
| parent.addChild (comp, 0, getDocument().getUndoManager()); | |||||
| parent.moveChild (parent.indexOf (comp), 0, getDocument().getUndoManager()); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -1036,22 +1050,13 @@ void ComponentEditorCanvas::hideSizeGuides() { overlay->hideSizeGuides(); } | |||||
| //============================================================================== | //============================================================================== | ||||
| Component* ComponentEditorCanvas::getComponentForUID (const uint32 uid) const | |||||
| { | |||||
| for (int i = componentHolder->getNumChildComponents(); --i >= 0;) | |||||
| if (componentHolder->getChildComponent (i)->getComponentUID() == uid) | |||||
| return componentHolder->getChildComponent (i); | |||||
| return 0; | |||||
| } | |||||
| const Array<Component*> ComponentEditorCanvas::getSelectedComps() const | const Array<Component*> ComponentEditorCanvas::getSelectedComps() const | ||||
| { | { | ||||
| Array<Component*> comps; | Array<Component*> comps; | ||||
| for (int i = 0; i < selection.getNumSelected(); ++i) | for (int i = 0; i < selection.getNumSelected(); ++i) | ||||
| { | { | ||||
| Component* c = getComponentForUID (selection.getSelectedItem (i)); | |||||
| Component* c = componentHolder->findComponentWithID (selection.getSelectedItem (i)); | |||||
| jassert (c != 0); | jassert (c != 0); | ||||
| if (c != 0) | if (c != 0) | ||||
| comps.add (c); | comps.add (c); | ||||
| @@ -1065,7 +1070,7 @@ const Array<Component*> ComponentEditorCanvas::getUnselectedComps() const | |||||
| Array<Component*> comps; | Array<Component*> comps; | ||||
| for (int i = componentHolder->getNumChildComponents(); --i >= 0;) | for (int i = componentHolder->getNumChildComponents(); --i >= 0;) | ||||
| if (! selection.isSelected (componentHolder->getChildComponent(i)->getComponentUID())) | |||||
| if (! selection.isSelected (ComponentDocument::getJucerIDFor (componentHolder->getChildComponent(i)))) | |||||
| comps.add (componentHolder->getChildComponent(i)); | comps.add (componentHolder->getChildComponent(i)); | ||||
| return comps; | return comps; | ||||
| @@ -45,7 +45,7 @@ public: | |||||
| ComponentEditor& getEditor(); | ComponentEditor& getEditor(); | ||||
| ComponentDocument& getDocument(); | ComponentDocument& getDocument(); | ||||
| typedef SelectedItemSet<uint32> SelectedItems; | |||||
| typedef SelectedItemSet<String> SelectedItems; | |||||
| SelectedItems& getSelection(); | SelectedItems& getSelection(); | ||||
| class ComponentHolder; | class ComponentHolder; | ||||
| @@ -67,8 +67,10 @@ public: | |||||
| void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} | void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} | ||||
| //============================================================================== | //============================================================================== | ||||
| const StringArray getSelectedIds() const; | |||||
| void getSelectedItemProperties (Array <PropertyComponent*>& props); | void getSelectedItemProperties (Array <PropertyComponent*>& props); | ||||
| void deleteSelection(); | void deleteSelection(); | ||||
| void deselectNonComponents(); | |||||
| void selectionToFront(); | void selectionToFront(); | ||||
| void selectionToBack(); | void selectionToBack(); | ||||
| @@ -114,7 +116,6 @@ private: | |||||
| WholeComponentResizer* resizeFrame; | WholeComponentResizer* resizeFrame; | ||||
| SelectedItems selection; | SelectedItems selection; | ||||
| Component* getComponentForUID (const uint32 uid) const; | |||||
| const Array<Component*> getSelectedComps() const; | const Array<Component*> getSelectedComps() const; | ||||
| const Array<Component*> getUnselectedComps() const; | const Array<Component*> getUnselectedComps() const; | ||||
| }; | }; | ||||
| @@ -654,7 +654,9 @@ public: | |||||
| juceFilter->prepareToPlay (GetSampleRate(), | juceFilter->prepareToPlay (GetSampleRate(), | ||||
| GetMaxFramesPerSlice()); | GetMaxFramesPerSlice()); | ||||
| midiEvents.ensureSize (2048); | |||||
| midiEvents.clear(); | midiEvents.clear(); | ||||
| incomingEvents.ensureSize (2048); | |||||
| incomingEvents.clear(); | incomingEvents.clear(); | ||||
| channels.calloc (jmax (juceFilter->getNumInputChannels(), | channels.calloc (jmax (juceFilter->getNumInputChannels(), | ||||
| @@ -506,6 +506,8 @@ protected: | |||||
| juceFilter->setPlayHead (this); | juceFilter->setPlayHead (this); | ||||
| juceFilter->addListener (this); | juceFilter->addListener (this); | ||||
| midiEvents.ensureSize (2048); | |||||
| } | } | ||||
| void handleAsyncUpdate() | void handleAsyncUpdate() | ||||
| @@ -779,6 +779,8 @@ public: | |||||
| deleteTempChannels(); | deleteTempChannels(); | ||||
| filter->prepareToPlay (rate, blockSize); | filter->prepareToPlay (rate, blockSize); | ||||
| midiEvents.ensureSize (2048); | |||||
| midiEvents.clear(); | midiEvents.clear(); | ||||
| setInitialDelay (filter->getLatencySamples()); | setInitialDelay (filter->getLatencySamples()); | ||||
| @@ -15704,11 +15704,11 @@ END_JUCE_NAMESPACE | |||||
| /*** Start of inlined file: juce_ValueTree.cpp ***/ | /*** Start of inlined file: juce_ValueTree.cpp ***/ | ||||
| BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
| class ValueTreeSetPropertyAction : public UndoableAction | |||||
| class ValueTree::SetPropertyAction : public UndoableAction | |||||
| { | { | ||||
| public: | public: | ||||
| ValueTreeSetPropertyAction (const ValueTree::SharedObjectPtr& target_, const var::identifier& name_, | |||||
| const var& newValue_, const bool isAddingNewProperty_, const bool isDeletingProperty_) | |||||
| SetPropertyAction (const SharedObjectPtr& target_, const var::identifier& name_, | |||||
| const var& newValue_, const bool isAddingNewProperty_, const bool isDeletingProperty_) | |||||
| : target (target_), name (name_), newValue (newValue_), | : target (target_), name (name_), newValue (newValue_), | ||||
| isAddingNewProperty (isAddingNewProperty_), | isAddingNewProperty (isAddingNewProperty_), | ||||
| isDeletingProperty (isDeletingProperty_) | isDeletingProperty (isDeletingProperty_) | ||||
| @@ -15717,7 +15717,7 @@ public: | |||||
| oldValue = target_->getProperty (name_); | oldValue = target_->getProperty (name_); | ||||
| } | } | ||||
| ~ValueTreeSetPropertyAction() {} | |||||
| ~SetPropertyAction() {} | |||||
| bool perform() | bool perform() | ||||
| { | { | ||||
| @@ -15747,21 +15747,21 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| const ValueTree::SharedObjectPtr target; | |||||
| const SharedObjectPtr target; | |||||
| const var::identifier name; | const var::identifier name; | ||||
| const var newValue; | const var newValue; | ||||
| var oldValue; | var oldValue; | ||||
| const bool isAddingNewProperty, isDeletingProperty; | const bool isAddingNewProperty, isDeletingProperty; | ||||
| ValueTreeSetPropertyAction (const ValueTreeSetPropertyAction&); | |||||
| ValueTreeSetPropertyAction& operator= (const ValueTreeSetPropertyAction&); | |||||
| SetPropertyAction (const SetPropertyAction&); | |||||
| SetPropertyAction& operator= (const SetPropertyAction&); | |||||
| }; | }; | ||||
| class ValueTreeChildChangeAction : public UndoableAction | |||||
| class ValueTree::AddOrRemoveChildAction : public UndoableAction | |||||
| { | { | ||||
| public: | public: | ||||
| ValueTreeChildChangeAction (const ValueTree::SharedObjectPtr& target_, const int childIndex_, | |||||
| const ValueTree::SharedObjectPtr& newChild_) | |||||
| AddOrRemoveChildAction (const SharedObjectPtr& target_, const int childIndex_, | |||||
| const SharedObjectPtr& newChild_) | |||||
| : target (target_), | : target (target_), | ||||
| child (newChild_ != 0 ? newChild_ : target_->children [childIndex_]), | child (newChild_ != 0 ? newChild_ : target_->children [childIndex_]), | ||||
| childIndex (childIndex_), | childIndex (childIndex_), | ||||
| @@ -15770,7 +15770,7 @@ public: | |||||
| jassert (child != 0); | jassert (child != 0); | ||||
| } | } | ||||
| ~ValueTreeChildChangeAction() {} | |||||
| ~AddOrRemoveChildAction() {} | |||||
| bool perform() | bool perform() | ||||
| { | { | ||||
| @@ -15805,12 +15805,50 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| const ValueTree::SharedObjectPtr target, child; | |||||
| const SharedObjectPtr target, child; | |||||
| const int childIndex; | const int childIndex; | ||||
| const bool isDeleting; | const bool isDeleting; | ||||
| ValueTreeChildChangeAction (const ValueTreeChildChangeAction&); | |||||
| ValueTreeChildChangeAction& operator= (const ValueTreeChildChangeAction&); | |||||
| AddOrRemoveChildAction (const AddOrRemoveChildAction&); | |||||
| AddOrRemoveChildAction& operator= (const AddOrRemoveChildAction&); | |||||
| }; | |||||
| class ValueTree::MoveChildAction : public UndoableAction | |||||
| { | |||||
| public: | |||||
| MoveChildAction (const SharedObjectPtr& target_, | |||||
| const int startIndex_, const int endIndex_) | |||||
| : target (target_), | |||||
| startIndex (startIndex_), | |||||
| endIndex (endIndex_) | |||||
| { | |||||
| } | |||||
| ~MoveChildAction() {} | |||||
| bool perform() | |||||
| { | |||||
| target->moveChild (startIndex, endIndex, 0); | |||||
| return true; | |||||
| } | |||||
| bool undo() | |||||
| { | |||||
| target->moveChild (endIndex, startIndex, 0); | |||||
| return true; | |||||
| } | |||||
| int getSizeInUnits() | |||||
| { | |||||
| return (int) sizeof (*this); //xxx should be more accurate | |||||
| } | |||||
| private: | |||||
| const SharedObjectPtr target, child; | |||||
| const int startIndex, endIndex; | |||||
| MoveChildAction (const MoveChildAction&); | |||||
| MoveChildAction& operator= (const MoveChildAction&); | |||||
| }; | }; | ||||
| ValueTree::SharedObject::SharedObject (const String& type_) | ValueTree::SharedObject::SharedObject (const String& type_) | ||||
| @@ -15926,11 +15964,11 @@ void ValueTree::SharedObject::setProperty (const var::identifier& name, const va | |||||
| if (existingValue != 0) | if (existingValue != 0) | ||||
| { | { | ||||
| if (*existingValue != newValue) | if (*existingValue != newValue) | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, name, newValue, false, false)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, newValue, false, false)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, name, newValue, true, false)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, newValue, true, false)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -15950,7 +15988,7 @@ void ValueTree::SharedObject::removeProperty (const var::identifier& name, UndoM | |||||
| else | else | ||||
| { | { | ||||
| if (properties.contains (name)) | if (properties.contains (name)) | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, name, var::null, false, true)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, var::null, false, true)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -15968,7 +16006,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage | |||||
| else | else | ||||
| { | { | ||||
| for (int i = properties.size(); --i >= 0;) | for (int i = properties.size(); --i >= 0;) | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, properties.getName(i), var::null, false, true)); | |||||
| undoManager->perform (new SetPropertyAction (this, properties.getName(i), var::null, false, true)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -16005,6 +16043,11 @@ bool ValueTree::SharedObject::isAChildOf (const SharedObject* const possiblePare | |||||
| return false; | return false; | ||||
| } | } | ||||
| int ValueTree::SharedObject::indexOf (const ValueTree& child) const | |||||
| { | |||||
| return children.indexOf (child.object); | |||||
| } | |||||
| void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoManager* const undoManager) | void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoManager* const undoManager) | ||||
| { | { | ||||
| if (child != 0 && child->parent != this) | if (child != 0 && child->parent != this) | ||||
| @@ -16034,7 +16077,7 @@ void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoMana | |||||
| if (index < 0) | if (index < 0) | ||||
| index = children.size(); | index = children.size(); | ||||
| undoManager->perform (new ValueTreeChildChangeAction (this, index, child)); | |||||
| undoManager->perform (new AddOrRemoveChildAction (this, index, child)); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -16061,7 +16104,7 @@ void ValueTree::SharedObject::removeChild (const int childIndex, UndoManager* co | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| undoManager->perform (new ValueTreeChildChangeAction (this, childIndex, 0)); | |||||
| undoManager->perform (new AddOrRemoveChildAction (this, childIndex, 0)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -16072,6 +16115,29 @@ void ValueTree::SharedObject::removeAllChildren (UndoManager* const undoManager) | |||||
| removeChild (children.size() - 1, undoManager); | removeChild (children.size() - 1, undoManager); | ||||
| } | } | ||||
| void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoManager* undoManager) | |||||
| { | |||||
| // The source index must be a valid index! | |||||
| jassert (((unsigned int) currentIndex) < (unsigned int) children.size()); | |||||
| if (currentIndex != newIndex | |||||
| && ((unsigned int) currentIndex) < (unsigned int) children.size()) | |||||
| { | |||||
| if (undoManager == 0) | |||||
| { | |||||
| children.move (currentIndex, newIndex); | |||||
| sendChildChangeMessage(); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (((unsigned int) newIndex) >= (unsigned int) children.size()) | |||||
| newIndex = children.size() - 1; | |||||
| undoManager->perform (new MoveChildAction (this, currentIndex, newIndex)); | |||||
| } | |||||
| } | |||||
| } | |||||
| ValueTree::ValueTree() throw() | ValueTree::ValueTree() throw() | ||||
| : object (0) | : object (0) | ||||
| { | { | ||||
| @@ -16274,6 +16340,11 @@ bool ValueTree::isAChildOf (const ValueTree& possibleParent) const | |||||
| return object != 0 && object->isAChildOf (possibleParent.object); | return object != 0 && object->isAChildOf (possibleParent.object); | ||||
| } | } | ||||
| int ValueTree::indexOf (const ValueTree& child) const | |||||
| { | |||||
| return object != 0 ? object->indexOf (child) : -1; | |||||
| } | |||||
| void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) | void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) | ||||
| { | { | ||||
| if (object != 0) | if (object != 0) | ||||
| @@ -16298,6 +16369,12 @@ void ValueTree::removeAllChildren (UndoManager* const undoManager) | |||||
| object->removeAllChildren (undoManager); | object->removeAllChildren (undoManager); | ||||
| } | } | ||||
| void ValueTree::moveChild (int currentIndex, int newIndex, UndoManager* undoManager) | |||||
| { | |||||
| if (object != 0) | |||||
| object->moveChild (currentIndex, newIndex, undoManager); | |||||
| } | |||||
| void ValueTree::addListener (Listener* listener) | void ValueTree::addListener (Listener* listener) | ||||
| { | { | ||||
| if (listener != 0) | if (listener != 0) | ||||
| @@ -26435,6 +26512,11 @@ void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | |||||
| } | } | ||||
| } | } | ||||
| void MidiBuffer::ensureSize (size_t minimumNumBytes) | |||||
| { | |||||
| data.ensureSize (minimumNumBytes); | |||||
| } | |||||
| bool MidiBuffer::isEmpty() const throw() | bool MidiBuffer::isEmpty() const throw() | ||||
| { | { | ||||
| return bytesUsed == 0; | return bytesUsed == 0; | ||||
| @@ -32340,7 +32422,7 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| // copy any incoming midi.. | // copy any incoming midi.. | ||||
| const ScopedLock sl (midiInLock); | const ScopedLock sl (midiInLock); | ||||
| midiMessages = incomingMidi; | |||||
| midiMessages.swapWith (incomingMidi); | |||||
| incomingMidi.clear(); | incomingMidi.clear(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -6726,19 +6726,19 @@ public: | |||||
| const var& operator[] (const var::identifier& name) const; | const var& operator[] (const var::identifier& name) const; | ||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager* undoManager); | |||||
| bool hasProperty (const var::identifier& name) const; | bool hasProperty (const var::identifier& name) const; | ||||
| void removeProperty (const var::identifier& name, UndoManager* const undoManager); | |||||
| void removeProperty (const var::identifier& name, UndoManager* undoManager); | |||||
| void removeAllProperties (UndoManager* const undoManager); | |||||
| void removeAllProperties (UndoManager* undoManager); | |||||
| int getNumProperties() const; | int getNumProperties() const; | ||||
| const var::identifier getPropertyName (int index) const; | const var::identifier getPropertyName (int index) const; | ||||
| Value getPropertyAsValue (const var::identifier& name, UndoManager* const undoManager) const; | |||||
| Value getPropertyAsValue (const var::identifier& name, UndoManager* undoManager) const; | |||||
| int getNumChildren() const; | int getNumChildren() const; | ||||
| @@ -6748,16 +6748,20 @@ public: | |||||
| ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; | ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; | ||||
| void addChild (ValueTree child, int index, UndoManager* const undoManager); | |||||
| void addChild (ValueTree child, int index, UndoManager* undoManager); | |||||
| void removeChild (const ValueTree& child, UndoManager* const undoManager); | |||||
| void removeChild (const ValueTree& child, UndoManager* undoManager); | |||||
| void removeChild (const int childIndex, UndoManager* const undoManager); | |||||
| void removeChild (int childIndex, UndoManager* undoManager); | |||||
| void removeAllChildren (UndoManager* const undoManager); | |||||
| void removeAllChildren (UndoManager* undoManager); | |||||
| void moveChild (int currentIndex, int newIndex, UndoManager* undoManager); | |||||
| bool isAChildOf (const ValueTree& possibleParent) const; | bool isAChildOf (const ValueTree& possibleParent) const; | ||||
| int indexOf (const ValueTree& child) const; | |||||
| ValueTree getParent() const; | ValueTree getParent() const; | ||||
| XmlElement* createXml() const; | XmlElement* createXml() const; | ||||
| @@ -6801,8 +6805,12 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| friend class ValueTreeSetPropertyAction; | |||||
| friend class ValueTreeChildChangeAction; | |||||
| class SetPropertyAction; | |||||
| friend class SetPropertyAction; | |||||
| class AddOrRemoveChildAction; | |||||
| friend class AddOrRemoveChildAction; | |||||
| class MoveChildAction; | |||||
| friend class MoveChildAction; | |||||
| class JUCE_API SharedObject : public ReferenceCountedObject | class JUCE_API SharedObject : public ReferenceCountedObject | ||||
| { | { | ||||
| @@ -6824,16 +6832,18 @@ private: | |||||
| void sendParentChangeMessage(); | void sendParentChangeMessage(); | ||||
| const var& getProperty (const var::identifier& name) const; | const var& getProperty (const var::identifier& name) const; | ||||
| const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | ||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager*); | |||||
| bool hasProperty (const var::identifier& name) const; | bool hasProperty (const var::identifier& name) const; | ||||
| void removeProperty (const var::identifier& name, UndoManager* const undoManager); | |||||
| void removeAllProperties (UndoManager* const undoManager); | |||||
| bool isAChildOf (const SharedObject* const possibleParent) const; | |||||
| void removeProperty (const var::identifier& name, UndoManager*); | |||||
| void removeAllProperties (UndoManager*); | |||||
| bool isAChildOf (const SharedObject* possibleParent) const; | |||||
| int indexOf (const ValueTree& child) const; | |||||
| ValueTree getChildWithName (const String& type) const; | ValueTree getChildWithName (const String& type) const; | ||||
| ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; | ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; | ||||
| void addChild (SharedObject* child, int index, UndoManager* const undoManager); | |||||
| void removeChild (const int childIndex, UndoManager* const undoManager); | |||||
| void removeAllChildren (UndoManager* const undoManager); | |||||
| void addChild (SharedObject* child, int index, UndoManager*); | |||||
| void removeChild (int childIndex, UndoManager*); | |||||
| void removeAllChildren (UndoManager*); | |||||
| void moveChild (int currentIndex, int newIndex, UndoManager*); | |||||
| XmlElement* createXml() const; | XmlElement* createXml() const; | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -6861,14 +6871,13 @@ private: | |||||
| }; | }; | ||||
| friend class SharedObject; | friend class SharedObject; | ||||
| typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | ||||
| ReferenceCountedObjectPtr <SharedObject> object; | |||||
| SharedObjectPtr object; | |||||
| ListenerList <Listener> listeners; | ListenerList <Listener> listeners; | ||||
| public: | public: | ||||
| explicit ValueTree (SharedObject* const object_); // (can be made private when VC6 support is finally dropped) | |||||
| explicit ValueTree (SharedObject*); // (can be made private when VC6 support is finally dropped) | |||||
| }; | }; | ||||
| #endif // __JUCE_VALUETREE_JUCEHEADER__ | #endif // __JUCE_VALUETREE_JUCEHEADER__ | ||||
| @@ -15723,6 +15732,8 @@ public: | |||||
| void swapWith (MidiBuffer& other); | void swapWith (MidiBuffer& other); | ||||
| void ensureSize (size_t minimumNumBytes); | |||||
| class Iterator | class Iterator | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -191,6 +191,11 @@ void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | |||||
| } | } | ||||
| } | } | ||||
| void MidiBuffer::ensureSize (size_t minimumNumBytes) | |||||
| { | |||||
| data.ensureSize (minimumNumBytes); | |||||
| } | |||||
| bool MidiBuffer::isEmpty() const throw() | bool MidiBuffer::isEmpty() const throw() | ||||
| { | { | ||||
| return bytesUsed == 0; | return bytesUsed == 0; | ||||
| @@ -157,6 +157,12 @@ public: | |||||
| */ | */ | ||||
| void swapWith (MidiBuffer& other); | void swapWith (MidiBuffer& other); | ||||
| /** Preallocates some memory for the buffer to use. | |||||
| This helps to avoid needing to reallocate space when the buffer has messages | |||||
| added to it. | |||||
| */ | |||||
| void ensureSize (size_t minimumNumBytes); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** | /** | ||||
| Used to iterate through the events in a MidiBuffer. | Used to iterate through the events in a MidiBuffer. | ||||
| @@ -1140,7 +1140,7 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| // copy any incoming midi.. | // copy any incoming midi.. | ||||
| const ScopedLock sl (midiInLock); | const ScopedLock sl (midiInLock); | ||||
| midiMessages = incomingMidi; | |||||
| midiMessages.swapWith (incomingMidi); | |||||
| incomingMidi.clear(); | incomingMidi.clear(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -31,11 +31,11 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| class ValueTreeSetPropertyAction : public UndoableAction | |||||
| class ValueTree::SetPropertyAction : public UndoableAction | |||||
| { | { | ||||
| public: | public: | ||||
| ValueTreeSetPropertyAction (const ValueTree::SharedObjectPtr& target_, const var::identifier& name_, | |||||
| const var& newValue_, const bool isAddingNewProperty_, const bool isDeletingProperty_) | |||||
| SetPropertyAction (const SharedObjectPtr& target_, const var::identifier& name_, | |||||
| const var& newValue_, const bool isAddingNewProperty_, const bool isDeletingProperty_) | |||||
| : target (target_), name (name_), newValue (newValue_), | : target (target_), name (name_), newValue (newValue_), | ||||
| isAddingNewProperty (isAddingNewProperty_), | isAddingNewProperty (isAddingNewProperty_), | ||||
| isDeletingProperty (isDeletingProperty_) | isDeletingProperty (isDeletingProperty_) | ||||
| @@ -44,7 +44,7 @@ public: | |||||
| oldValue = target_->getProperty (name_); | oldValue = target_->getProperty (name_); | ||||
| } | } | ||||
| ~ValueTreeSetPropertyAction() {} | |||||
| ~SetPropertyAction() {} | |||||
| bool perform() | bool perform() | ||||
| { | { | ||||
| @@ -74,22 +74,22 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| const ValueTree::SharedObjectPtr target; | |||||
| const SharedObjectPtr target; | |||||
| const var::identifier name; | const var::identifier name; | ||||
| const var newValue; | const var newValue; | ||||
| var oldValue; | var oldValue; | ||||
| const bool isAddingNewProperty, isDeletingProperty; | const bool isAddingNewProperty, isDeletingProperty; | ||||
| ValueTreeSetPropertyAction (const ValueTreeSetPropertyAction&); | |||||
| ValueTreeSetPropertyAction& operator= (const ValueTreeSetPropertyAction&); | |||||
| SetPropertyAction (const SetPropertyAction&); | |||||
| SetPropertyAction& operator= (const SetPropertyAction&); | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| class ValueTreeChildChangeAction : public UndoableAction | |||||
| class ValueTree::AddOrRemoveChildAction : public UndoableAction | |||||
| { | { | ||||
| public: | public: | ||||
| ValueTreeChildChangeAction (const ValueTree::SharedObjectPtr& target_, const int childIndex_, | |||||
| const ValueTree::SharedObjectPtr& newChild_) | |||||
| AddOrRemoveChildAction (const SharedObjectPtr& target_, const int childIndex_, | |||||
| const SharedObjectPtr& newChild_) | |||||
| : target (target_), | : target (target_), | ||||
| child (newChild_ != 0 ? newChild_ : target_->children [childIndex_]), | child (newChild_ != 0 ? newChild_ : target_->children [childIndex_]), | ||||
| childIndex (childIndex_), | childIndex (childIndex_), | ||||
| @@ -98,7 +98,7 @@ public: | |||||
| jassert (child != 0); | jassert (child != 0); | ||||
| } | } | ||||
| ~ValueTreeChildChangeAction() {} | |||||
| ~AddOrRemoveChildAction() {} | |||||
| bool perform() | bool perform() | ||||
| { | { | ||||
| @@ -133,12 +133,51 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| const ValueTree::SharedObjectPtr target, child; | |||||
| const SharedObjectPtr target, child; | |||||
| const int childIndex; | const int childIndex; | ||||
| const bool isDeleting; | const bool isDeleting; | ||||
| ValueTreeChildChangeAction (const ValueTreeChildChangeAction&); | |||||
| ValueTreeChildChangeAction& operator= (const ValueTreeChildChangeAction&); | |||||
| AddOrRemoveChildAction (const AddOrRemoveChildAction&); | |||||
| AddOrRemoveChildAction& operator= (const AddOrRemoveChildAction&); | |||||
| }; | |||||
| //============================================================================== | |||||
| class ValueTree::MoveChildAction : public UndoableAction | |||||
| { | |||||
| public: | |||||
| MoveChildAction (const SharedObjectPtr& target_, | |||||
| const int startIndex_, const int endIndex_) | |||||
| : target (target_), | |||||
| startIndex (startIndex_), | |||||
| endIndex (endIndex_) | |||||
| { | |||||
| } | |||||
| ~MoveChildAction() {} | |||||
| bool perform() | |||||
| { | |||||
| target->moveChild (startIndex, endIndex, 0); | |||||
| return true; | |||||
| } | |||||
| bool undo() | |||||
| { | |||||
| target->moveChild (endIndex, startIndex, 0); | |||||
| return true; | |||||
| } | |||||
| int getSizeInUnits() | |||||
| { | |||||
| return (int) sizeof (*this); //xxx should be more accurate | |||||
| } | |||||
| private: | |||||
| const SharedObjectPtr target, child; | |||||
| const int startIndex, endIndex; | |||||
| MoveChildAction (const MoveChildAction&); | |||||
| MoveChildAction& operator= (const MoveChildAction&); | |||||
| }; | }; | ||||
| @@ -258,11 +297,11 @@ void ValueTree::SharedObject::setProperty (const var::identifier& name, const va | |||||
| if (existingValue != 0) | if (existingValue != 0) | ||||
| { | { | ||||
| if (*existingValue != newValue) | if (*existingValue != newValue) | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, name, newValue, false, false)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, newValue, false, false)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, name, newValue, true, false)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, newValue, true, false)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -282,7 +321,7 @@ void ValueTree::SharedObject::removeProperty (const var::identifier& name, UndoM | |||||
| else | else | ||||
| { | { | ||||
| if (properties.contains (name)) | if (properties.contains (name)) | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, name, var::null, false, true)); | |||||
| undoManager->perform (new SetPropertyAction (this, name, var::null, false, true)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -300,7 +339,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage | |||||
| else | else | ||||
| { | { | ||||
| for (int i = properties.size(); --i >= 0;) | for (int i = properties.size(); --i >= 0;) | ||||
| undoManager->perform (new ValueTreeSetPropertyAction (this, properties.getName(i), var::null, false, true)); | |||||
| undoManager->perform (new SetPropertyAction (this, properties.getName(i), var::null, false, true)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -337,6 +376,11 @@ bool ValueTree::SharedObject::isAChildOf (const SharedObject* const possiblePare | |||||
| return false; | return false; | ||||
| } | } | ||||
| int ValueTree::SharedObject::indexOf (const ValueTree& child) const | |||||
| { | |||||
| return children.indexOf (child.object); | |||||
| } | |||||
| void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoManager* const undoManager) | void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoManager* const undoManager) | ||||
| { | { | ||||
| if (child != 0 && child->parent != this) | if (child != 0 && child->parent != this) | ||||
| @@ -366,7 +410,7 @@ void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoMana | |||||
| if (index < 0) | if (index < 0) | ||||
| index = children.size(); | index = children.size(); | ||||
| undoManager->perform (new ValueTreeChildChangeAction (this, index, child)); | |||||
| undoManager->perform (new AddOrRemoveChildAction (this, index, child)); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -393,7 +437,7 @@ void ValueTree::SharedObject::removeChild (const int childIndex, UndoManager* co | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| undoManager->perform (new ValueTreeChildChangeAction (this, childIndex, 0)); | |||||
| undoManager->perform (new AddOrRemoveChildAction (this, childIndex, 0)); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -404,6 +448,28 @@ void ValueTree::SharedObject::removeAllChildren (UndoManager* const undoManager) | |||||
| removeChild (children.size() - 1, undoManager); | removeChild (children.size() - 1, undoManager); | ||||
| } | } | ||||
| void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoManager* undoManager) | |||||
| { | |||||
| // The source index must be a valid index! | |||||
| jassert (((unsigned int) currentIndex) < (unsigned int) children.size()); | |||||
| if (currentIndex != newIndex | |||||
| && ((unsigned int) currentIndex) < (unsigned int) children.size()) | |||||
| { | |||||
| if (undoManager == 0) | |||||
| { | |||||
| children.move (currentIndex, newIndex); | |||||
| sendChildChangeMessage(); | |||||
| } | |||||
| else | |||||
| { | |||||
| if (((unsigned int) newIndex) >= (unsigned int) children.size()) | |||||
| newIndex = children.size() - 1; | |||||
| undoManager->perform (new MoveChildAction (this, currentIndex, newIndex)); | |||||
| } | |||||
| } | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| ValueTree::ValueTree() throw() | ValueTree::ValueTree() throw() | ||||
| @@ -610,6 +676,11 @@ bool ValueTree::isAChildOf (const ValueTree& possibleParent) const | |||||
| return object != 0 && object->isAChildOf (possibleParent.object); | return object != 0 && object->isAChildOf (possibleParent.object); | ||||
| } | } | ||||
| int ValueTree::indexOf (const ValueTree& child) const | |||||
| { | |||||
| return object != 0 ? object->indexOf (child) : -1; | |||||
| } | |||||
| void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) | void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) | ||||
| { | { | ||||
| if (object != 0) | if (object != 0) | ||||
| @@ -634,6 +705,12 @@ void ValueTree::removeAllChildren (UndoManager* const undoManager) | |||||
| object->removeAllChildren (undoManager); | object->removeAllChildren (undoManager); | ||||
| } | } | ||||
| void ValueTree::moveChild (int currentIndex, int newIndex, UndoManager* undoManager) | |||||
| { | |||||
| if (object != 0) | |||||
| object->moveChild (currentIndex, newIndex, undoManager); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void ValueTree::addListener (Listener* listener) | void ValueTree::addListener (Listener* listener) | ||||
| { | { | ||||
| @@ -159,7 +159,7 @@ public: | |||||
| so that this change can be undone. | so that this change can be undone. | ||||
| @see var, getProperty, removeProperty | @see var, getProperty, removeProperty | ||||
| */ | */ | ||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager* undoManager); | |||||
| /** Returns true if the node contains a named property. */ | /** Returns true if the node contains a named property. */ | ||||
| bool hasProperty (const var::identifier& name) const; | bool hasProperty (const var::identifier& name) const; | ||||
| @@ -168,13 +168,13 @@ public: | |||||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
| so that this change can be undone. | so that this change can be undone. | ||||
| */ | */ | ||||
| void removeProperty (const var::identifier& name, UndoManager* const undoManager); | |||||
| void removeProperty (const var::identifier& name, UndoManager* undoManager); | |||||
| /** Removes all properties from the node. | /** Removes all properties from the node. | ||||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
| so that this change can be undone. | so that this change can be undone. | ||||
| */ | */ | ||||
| void removeAllProperties (UndoManager* const undoManager); | |||||
| void removeAllProperties (UndoManager* undoManager); | |||||
| /** Returns the total number of properties that the node contains. | /** Returns the total number of properties that the node contains. | ||||
| @see getProperty. | @see getProperty. | ||||
| @@ -192,7 +192,7 @@ public: | |||||
| it needs to change the value. Attaching a Value::Listener to the value object will provide | it needs to change the value. Attaching a Value::Listener to the value object will provide | ||||
| callbacks whenever the property changes. | callbacks whenever the property changes. | ||||
| */ | */ | ||||
| Value getPropertyAsValue (const var::identifier& name, UndoManager* const undoManager) const; | |||||
| Value getPropertyAsValue (const var::identifier& name, UndoManager* undoManager) const; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the number of child nodes belonging to this one. | /** Returns the number of child nodes belonging to this one. | ||||
| @@ -233,31 +233,50 @@ public: | |||||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
| so that this change can be undone. | so that this change can be undone. | ||||
| */ | */ | ||||
| void addChild (ValueTree child, int index, UndoManager* const undoManager); | |||||
| void addChild (ValueTree child, int index, UndoManager* undoManager); | |||||
| /** Removes the specified child from this node's child-list. | /** Removes the specified child from this node's child-list. | ||||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
| so that this change can be undone. | so that this change can be undone. | ||||
| */ | */ | ||||
| void removeChild (const ValueTree& child, UndoManager* const undoManager); | |||||
| void removeChild (const ValueTree& child, UndoManager* undoManager); | |||||
| /** Removes a child from this node's child-list. | /** Removes a child from this node's child-list. | ||||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
| so that this change can be undone. | so that this change can be undone. | ||||
| */ | */ | ||||
| void removeChild (const int childIndex, UndoManager* const undoManager); | |||||
| void removeChild (int childIndex, UndoManager* undoManager); | |||||
| /** Removes all child-nodes from this node. | /** Removes all child-nodes from this node. | ||||
| If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | If the undoManager parameter is non-null, its UndoManager::perform() method will be used, | ||||
| so that this change can be undone. | so that this change can be undone. | ||||
| */ | */ | ||||
| void removeAllChildren (UndoManager* const undoManager); | |||||
| void removeAllChildren (UndoManager* undoManager); | |||||
| /** Moves one of the children to a different index. | |||||
| This will move the child to a specified index, shuffling along any intervening | |||||
| items as required. So for example, if you have a list of { 0, 1, 2, 3, 4, 5 }, then | |||||
| calling move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. | |||||
| @param currentIndex the index of the item to be moved. If this isn't a | |||||
| valid index, then nothing will be done | |||||
| @param newIndex the index at which you'd like this item to end up. If this | |||||
| is less than zero, the value will be moved to the end | |||||
| of the list | |||||
| */ | |||||
| void moveChild (int currentIndex, int newIndex, UndoManager* undoManager); | |||||
| /** Returns true if this node is anywhere below the specified parent node. | /** Returns true if this node is anywhere below the specified parent node. | ||||
| This returns true if the node is a child-of-a-child, as well as a direct child. | This returns true if the node is a child-of-a-child, as well as a direct child. | ||||
| */ | */ | ||||
| bool isAChildOf (const ValueTree& possibleParent) const; | bool isAChildOf (const ValueTree& possibleParent) const; | ||||
| /** Returns the index of a child item in this parent. | |||||
| If the child isn't found, this returns -1. | |||||
| */ | |||||
| int indexOf (const ValueTree& child) const; | |||||
| /** Returns the parent node that contains this one. | /** Returns the parent node that contains this one. | ||||
| If the node has no parent, this will return an invalid node. (See isValid() to find out | If the node has no parent, this will return an invalid node. (See isValid() to find out | ||||
| whether a node is valid). | whether a node is valid). | ||||
| @@ -403,8 +422,12 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| friend class ValueTreeSetPropertyAction; | |||||
| friend class ValueTreeChildChangeAction; | |||||
| class SetPropertyAction; | |||||
| friend class SetPropertyAction; | |||||
| class AddOrRemoveChildAction; | |||||
| friend class AddOrRemoveChildAction; | |||||
| class MoveChildAction; | |||||
| friend class MoveChildAction; | |||||
| class JUCE_API SharedObject : public ReferenceCountedObject | class JUCE_API SharedObject : public ReferenceCountedObject | ||||
| { | { | ||||
| @@ -426,16 +449,18 @@ private: | |||||
| void sendParentChangeMessage(); | void sendParentChangeMessage(); | ||||
| const var& getProperty (const var::identifier& name) const; | const var& getProperty (const var::identifier& name) const; | ||||
| const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | ||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||||
| void setProperty (const var::identifier& name, const var& newValue, UndoManager*); | |||||
| bool hasProperty (const var::identifier& name) const; | bool hasProperty (const var::identifier& name) const; | ||||
| void removeProperty (const var::identifier& name, UndoManager* const undoManager); | |||||
| void removeAllProperties (UndoManager* const undoManager); | |||||
| bool isAChildOf (const SharedObject* const possibleParent) const; | |||||
| void removeProperty (const var::identifier& name, UndoManager*); | |||||
| void removeAllProperties (UndoManager*); | |||||
| bool isAChildOf (const SharedObject* possibleParent) const; | |||||
| int indexOf (const ValueTree& child) const; | |||||
| ValueTree getChildWithName (const String& type) const; | ValueTree getChildWithName (const String& type) const; | ||||
| ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; | ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const; | ||||
| void addChild (SharedObject* child, int index, UndoManager* const undoManager); | |||||
| void removeChild (const int childIndex, UndoManager* const undoManager); | |||||
| void removeAllChildren (UndoManager* const undoManager); | |||||
| void addChild (SharedObject* child, int index, UndoManager*); | |||||
| void removeChild (int childIndex, UndoManager*); | |||||
| void removeAllChildren (UndoManager*); | |||||
| void moveChild (int currentIndex, int newIndex, UndoManager*); | |||||
| XmlElement* createXml() const; | XmlElement* createXml() const; | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -463,15 +488,14 @@ private: | |||||
| }; | }; | ||||
| friend class SharedObject; | friend class SharedObject; | ||||
| typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | typedef ReferenceCountedObjectPtr <SharedObject> SharedObjectPtr; | ||||
| ReferenceCountedObjectPtr <SharedObject> object; | |||||
| SharedObjectPtr object; | |||||
| ListenerList <Listener> listeners; | ListenerList <Listener> listeners; | ||||
| public: | public: | ||||
| /** @internal */ | /** @internal */ | ||||
| explicit ValueTree (SharedObject* const object_); // (can be made private when VC6 support is finally dropped) | |||||
| explicit ValueTree (SharedObject*); // (can be made private when VC6 support is finally dropped) | |||||
| }; | }; | ||||