| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2020 - Raw Material Software Limited
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
 -    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
 - 
 -    End User License Agreement: www.juce.com/juce-6-licence
 -    Privacy Policy: www.juce.com/juce-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #pragma once
 - 
 - 
 - //==============================================================================
 - class TabbedComponentHandler  : public ComponentTypeHandler
 - {
 - public:
 -     TabbedComponentHandler()
 -         : ComponentTypeHandler ("Tabbed Component", "juce::TabbedComponent", typeid (TabbedComponent), 200, 150)
 -     {}
 - 
 -     Component* createNewComponent (JucerDocument*) override
 -     {
 -         TabbedComponent* const t = new TabbedComponent (TabbedButtonBar::TabsAtTop);
 -         t->setName ("new tabbed component");
 - 
 -         for (int i = 3; --i >= 0;)
 -             addNewTab (t);
 - 
 -         return t;
 -     }
 - 
 -     XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout) override
 -     {
 -         TabbedComponent* const t = dynamic_cast<TabbedComponent*> (comp);
 -         XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout);
 - 
 -         if (t->getOrientation() == TabbedButtonBar::TabsAtTop)           e->setAttribute ("orientation", "top");
 -         else if (t->getOrientation() == TabbedButtonBar::TabsAtBottom)   e->setAttribute ("orientation", "bottom");
 -         else if (t->getOrientation() == TabbedButtonBar::TabsAtLeft)     e->setAttribute ("orientation", "left");
 -         else if (t->getOrientation() == TabbedButtonBar::TabsAtRight)    e->setAttribute ("orientation", "right");
 - 
 -         e->setAttribute ("tabBarDepth", t->getTabBarDepth());
 -         e->setAttribute ("initialTab", t->getCurrentTabIndex());
 - 
 -         for (int i = 0; i < t->getNumTabs(); ++i)
 -             e->addChildElement (getTabState (t, i).release());
 - 
 -         return e;
 -     }
 - 
 -     bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout) override
 -     {
 -         if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
 -             return false;
 - 
 -         TabbedComponent* const t = dynamic_cast<TabbedComponent*> (comp);
 - 
 -         if (xml.getStringAttribute ("orientation") == "top")          t->setOrientation (TabbedButtonBar::TabsAtTop);
 -         else if (xml.getStringAttribute ("orientation") == "bottom")  t->setOrientation (TabbedButtonBar::TabsAtBottom);
 -         else if (xml.getStringAttribute ("orientation") == "left")    t->setOrientation (TabbedButtonBar::TabsAtLeft);
 -         else if (xml.getStringAttribute ("orientation") == "right")   t->setOrientation (TabbedButtonBar::TabsAtRight);
 - 
 -         TabbedComponent defaultTabComp (TabbedButtonBar::TabsAtTop);
 - 
 -         t->setTabBarDepth (xml.getIntAttribute ("tabBarDepth", defaultTabComp.getTabBarDepth()));
 - 
 -         t->clearTabs();
 - 
 -         for (auto* e : xml.getChildIterator())
 -         {
 -             addNewTab (t);
 -             restoreTabState (t, t->getNumTabs() - 1, *e);
 -         }
 - 
 -         t->setCurrentTabIndex (xml.getIntAttribute ("initialTab", 0));
 - 
 -         return true;
 -     }
 - 
 -     void getEditableProperties (Component* component, JucerDocument& doc,
 -                                 Array<PropertyComponent*>& props, bool multipleSelected) override
 -     {
 -         ComponentTypeHandler::getEditableProperties (component, doc, props, multipleSelected);
 - 
 -         if (multipleSelected)
 -             return;
 - 
 -         if (auto* t = dynamic_cast<TabbedComponent*> (component))
 -         {
 -             props.add (new TabOrientationProperty (t, doc));
 -             props.add (new TabDepthProperty (t, doc));
 - 
 -             if (t->getNumTabs() > 0)
 -                 props.add (new TabInitialTabProperty (t, doc));
 - 
 -             props.add (new TabAddTabProperty (t, doc));
 - 
 -             if (t->getNumTabs() > 0)
 -                 props.add (new TabRemoveTabProperty (t, doc));
 -         }
 -     }
 - 
 -     void addPropertiesToPropertyPanel (Component* comp, JucerDocument& doc,
 -                                        PropertyPanel& panel, bool multipleSelected) override
 -     {
 -         ComponentTypeHandler::addPropertiesToPropertyPanel (comp, doc, panel, multipleSelected);
 - 
 -         TabbedComponent* const t = dynamic_cast<TabbedComponent*> (comp);
 - 
 -         for (int i = 0; i < t->getNumTabs(); ++i)
 -         {
 -             Array<PropertyComponent*> properties;
 - 
 -             properties.add (new TabNameProperty (t, doc, i));
 -             properties.add (new TabColourProperty (t, doc, i));
 - 
 -             properties.add (new TabContentTypeProperty (t, doc, i));
 - 
 -             if (isTabUsingJucerComp (t, i))
 -                 properties.add (new TabJucerFileProperty (t, doc, i));
 -             else
 -                 properties.add (new TabContentClassProperty (t, doc, i));
 - 
 -             properties.add (new TabContentConstructorParamsProperty (t, doc, i));
 - 
 -             properties.add (new TabMoveProperty (t, doc, i, t->getNumTabs()));
 - 
 -             panel.addSection ("Tab " + String (i), properties);
 -         }
 -     }
 - 
 -     String getCreationParameters (GeneratedCode&, Component* comp) override
 -     {
 -         TabbedComponent* const t = dynamic_cast<TabbedComponent*> (comp);
 - 
 -         switch (t->getOrientation())
 -         {
 -             case TabbedButtonBar::TabsAtTop:        return "juce::TabbedButtonBar::TabsAtTop";
 -             case TabbedButtonBar::TabsAtBottom:     return "juce::TabbedButtonBar::TabsAtBottom";
 -             case TabbedButtonBar::TabsAtLeft:       return "juce::TabbedButtonBar::TabsAtLeft";
 -             case TabbedButtonBar::TabsAtRight:      return "juce::TabbedButtonBar::TabsAtRight";
 -             default:                                jassertfalse; break;
 -         }
 - 
 -         return {};
 -     }
 - 
 -     void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName) override
 -     {
 -         TabbedComponent* const t = dynamic_cast<TabbedComponent*> (component);
 - 
 -         ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
 - 
 -         code.constructorCode
 -             << memberVariableName << "->setTabBarDepth (" << t->getTabBarDepth() << ");\n";
 - 
 -         for (int i = 0; i < t->getNumTabs(); ++i)
 -         {
 -             String contentClassName;
 - 
 -             if (isTabUsingJucerComp (t, i))
 -             {
 -                 File jucerCpp = code.document->getCppFile().getSiblingFile (getTabJucerFile (t, i));
 - 
 -                 std::unique_ptr<JucerDocument> doc (JucerDocument::createForCppFile (nullptr, jucerCpp));
 - 
 -                 if (doc != nullptr)
 -                 {
 -                     code.includeFilesCPP.add (jucerCpp.withFileExtension (".h"));
 -                     contentClassName = doc->getClassName();
 -                 }
 -             }
 -             else
 -             {
 -                 contentClassName = getTabClassName (t, i);
 -             }
 - 
 -             code.constructorCode
 -                 << memberVariableName
 -                 << "->addTab ("
 -                 << quotedString (t->getTabNames() [i], code.shouldUseTransMacro())
 -                 << ", "
 -                 << CodeHelpers::colourToCode (t->getTabBackgroundColour (i));
 - 
 -             if (contentClassName.isNotEmpty())
 -             {
 -                 code.constructorCode << ", new " << contentClassName;
 - 
 -                 if (getTabConstructorParams (t, i).trim().isNotEmpty())
 -                     code.constructorCode << " ";
 - 
 -                 code.constructorCode << "(" << getTabConstructorParams (t, i).trim() << "), true);\n";
 -             }
 -             else
 -             {
 -                 code.constructorCode << ", 0, false);\n";
 -             }
 -         }
 - 
 -         code.constructorCode
 -             << memberVariableName << "->setCurrentTabIndex (" << t->getCurrentTabIndex() << ");\n";
 - 
 -         code.constructorCode << "\n";
 -     }
 - 
 -     //==============================================================================
 -     static void addNewTab (TabbedComponent* tc, const int insertIndex = -1)
 -     {
 -         tc->addTab ("Tab " + String (tc->getNumTabs()), Colours::lightgrey,
 -                     new TabDemoContentComp(), true, insertIndex);
 -     }
 - 
 -     //==============================================================================
 -     static std::unique_ptr<XmlElement> getTabState (TabbedComponent* tc, int tabIndex)
 -     {
 -         auto xml = std::make_unique<XmlElement> ("TAB");
 -         xml->setAttribute ("name", tc->getTabNames() [tabIndex]);
 -         xml->setAttribute ("colour", tc->getTabBackgroundColour (tabIndex).toString());
 - 
 -         if (TabDemoContentComp* const tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex)))
 -         {
 -             xml->setAttribute ("useJucerComp", tdc->isUsingJucerComp);
 -             xml->setAttribute ("contentClassName", tdc->contentClassName);
 -             xml->setAttribute ("constructorParams", tdc->constructorParams);
 -             xml->setAttribute ("jucerComponentFile", tdc->jucerComponentFile);
 -         }
 - 
 -         return xml;
 -     }
 - 
 -     static void restoreTabState (TabbedComponent* tc, int tabIndex, const XmlElement& xml)
 -     {
 -         tc->setTabName (tabIndex, xml.getStringAttribute ("name", "Tab"));
 -         tc->setTabBackgroundColour (tabIndex, Colour::fromString (xml.getStringAttribute ("colour", Colours::lightgrey.toString())));
 - 
 -         if (TabDemoContentComp* const tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex)))
 -         {
 -             tdc->isUsingJucerComp   = xml.getBoolAttribute ("useJucerComp", false);
 -             tdc->contentClassName   = xml.getStringAttribute ("contentClassName");
 -             tdc->constructorParams  = xml.getStringAttribute ("constructorParams");
 -             tdc->jucerComponentFile = xml.getStringAttribute ("jucerComponentFile");
 - 
 -             tdc->updateContent();
 -         }
 -     }
 - 
 -     //==============================================================================
 -     static bool isTabUsingJucerComp (TabbedComponent* tc, int tabIndex)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         return tdc != nullptr && tdc->isUsingJucerComp;
 -     }
 - 
 -     static void setTabUsingJucerComp (TabbedComponent* tc, int tabIndex, const bool b)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         if (tdc != nullptr)
 -         {
 -             tdc->isUsingJucerComp = b;
 -             tdc->updateContent();
 -         }
 -     }
 - 
 -     static String getTabClassName (TabbedComponent* tc, int tabIndex)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         return tdc != nullptr ? tdc->contentClassName : String();
 -     }
 - 
 -     static void setTabClassName (TabbedComponent* tc, int tabIndex, const String& newName)
 -     {
 -         TabDemoContentComp* const tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         if (tdc != nullptr)
 -         {
 -             tdc->contentClassName = newName;
 -             tdc->updateContent();
 -         }
 -     }
 - 
 -     static String getTabConstructorParams (TabbedComponent* tc, int tabIndex)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         return tdc != nullptr ? tdc->constructorParams : String();
 -     }
 - 
 -     static void setTabConstructorParams (TabbedComponent* tc, int tabIndex, const String& newParams)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         if (tdc != nullptr)
 -         {
 -             tdc->constructorParams = newParams;
 -             tdc->updateContent();
 -         }
 -     }
 - 
 -     static String getTabJucerFile (TabbedComponent* tc, int tabIndex)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         return tdc != nullptr ? tdc->jucerComponentFile : String();
 -     }
 - 
 -     static void setTabJucerFile (TabbedComponent* tc, int tabIndex, const String& newFile)
 -     {
 -         auto tdc = dynamic_cast<TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
 -         jassert (tdc != nullptr);
 - 
 -         if (tdc != nullptr)
 -         {
 -             tdc->jucerComponentFile = newFile;
 -             tdc->updateContent();
 -         }
 -     }
 - 
 - private:
 -     //==============================================================================
 -     class TabDemoContentComp : public Component
 -     {
 -     public:
 -         TabDemoContentComp()
 -             : isUsingJucerComp (false)
 -         {
 -             setSize (2048, 2048);
 -         }
 - 
 -         void paint (Graphics& g) override
 -         {
 -             if (jucerComp == nullptr)
 -                 g.fillCheckerBoard (getLocalBounds().toFloat(), 50.0f, 50.0f,
 -                                     Colour::greyLevel (0.9f).withAlpha (0.4f),
 -                                     Colour::greyLevel (0.8f).withAlpha (0.4f));
 -         }
 - 
 -         void resized() override
 -         {
 -             if (jucerComp != nullptr)
 -             {
 -                 jucerComp->setBounds (getLocalBounds());
 -                 setOpaque (jucerComp->isOpaque());
 -             }
 -         }
 - 
 -         void updateContent()
 -         {
 -             if (isUsingJucerComp)
 -             {
 -                 if (jucerComp == nullptr
 -                     || jucerComp->getOwnerDocument() == nullptr
 -                     || jucerComp->getFilename() != jucerComponentFile)
 -                 {
 -                     jucerComp.reset();
 - 
 -                     jucerComp.reset (new TestComponent (ComponentTypeHandler::findParentDocument (this), nullptr, false));
 -                     jucerComp->setFilename (jucerComponentFile);
 -                     jucerComp->setToInitialSize();
 - 
 -                     addAndMakeVisible (jucerComp.get());
 -                 }
 -             }
 -             else
 -             {
 -                 jucerComp.reset();
 -             }
 - 
 -             resized();
 -         }
 - 
 -         void parentHierarchyChanged() override
 -         {
 -             updateContent();
 -         }
 - 
 -         bool isUsingJucerComp;
 -         String contentClassName, constructorParams;
 -         String jucerComponentFile;
 -         std::unique_ptr<TestComponent> jucerComp;
 -     };
 - 
 -     //==============================================================================
 -     class TabOrientationProperty  : public ComponentChoiceProperty<TabbedComponent>
 -     {
 -     public:
 -         TabOrientationProperty (TabbedComponent* comp, JucerDocument& doc)
 -             : ComponentChoiceProperty<TabbedComponent> ("tab position", comp, doc)
 -         {
 -             choices.add ("Tabs at top");
 -             choices.add ("Tabs at bottom");
 -             choices.add ("Tabs at left");
 -             choices.add ("Tabs at right");
 -         }
 - 
 -         void setIndex (int newIndex)
 -         {
 -             const TabbedButtonBar::Orientation orientations[] = { TabbedButtonBar::TabsAtTop,
 -                                                                   TabbedButtonBar::TabsAtBottom,
 -                                                                   TabbedButtonBar::TabsAtLeft,
 -                                                                   TabbedButtonBar::TabsAtRight };
 - 
 -             document.perform (new TabOrienationChangeAction (component, *document.getComponentLayout(), orientations [newIndex]),
 -                               "Change TabComponent orientation");
 -         }
 - 
 -         int getIndex() const
 -         {
 -             switch (component->getOrientation())
 -             {
 -                 case TabbedButtonBar::TabsAtTop:    return 0;
 -                 case TabbedButtonBar::TabsAtBottom: return 1;
 -                 case TabbedButtonBar::TabsAtLeft:   return 2;
 -                 case TabbedButtonBar::TabsAtRight:  return 3;
 -                 default:                            jassertfalse; break;
 -             }
 - 
 -             return 0;
 -         }
 - 
 -     private:
 -         class TabOrienationChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabOrienationChangeAction (TabbedComponent* const comp, ComponentLayout& l, const TabbedButtonBar::Orientation newState_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   newState (newState_)
 -             {
 -                 oldState = comp->getOrientation();
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setOrientation (newState);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setOrientation (oldState);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             TabbedButtonBar::Orientation newState, oldState;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabInitialTabProperty  : public ComponentChoiceProperty<TabbedComponent>
 -     {
 -     public:
 -         TabInitialTabProperty (TabbedComponent* comp, JucerDocument& doc)
 -             : ComponentChoiceProperty<TabbedComponent> ("initial tab", comp, doc)
 -         {
 -             for (int i = 0; i < comp->getNumTabs(); ++i)
 -                 choices.add ("Tab " + String (i) + ": \"" + comp->getTabNames() [i] + "\"");
 -         }
 - 
 -         void setIndex (int newIndex)
 -         {
 -             document.perform (new InitialTabChangeAction (component, *document.getComponentLayout(), newIndex),
 -                               "Change initial tab");
 -         }
 - 
 -         int getIndex() const
 -         {
 -             return component->getCurrentTabIndex();
 -         }
 - 
 -     private:
 -         class InitialTabChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             InitialTabChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int newValue_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   newValue (newValue_)
 -             {
 -                 oldValue = comp->getCurrentTabIndex();
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setCurrentTabIndex (newValue);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setCurrentTabIndex (oldValue);
 -                 changed();
 -                 return true;
 -             }
 - 
 -         private:
 -             int newValue, oldValue;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabDepthProperty  : public SliderPropertyComponent,
 -                               private ChangeListener
 -     {
 -     public:
 -         TabDepthProperty (TabbedComponent* comp, JucerDocument& doc)
 -             : SliderPropertyComponent ("tab depth", 10.0, 80.0, 1.0, 1.0),
 -               component (comp),
 -               document (doc)
 -         {
 -             document.addChangeListener (this);
 -         }
 - 
 -         ~TabDepthProperty() override
 -         {
 -             document.removeChangeListener (this);
 -         }
 - 
 -         void setValue (double newValue) override
 -         {
 -             document.getUndoManager().undoCurrentTransactionOnly();
 - 
 -             document.perform (new TabDepthChangeAction (component, *document.getComponentLayout(), roundToInt (newValue)),
 -                               "Change TabComponent tab depth");
 -         }
 - 
 -         double getValue() const override
 -         {
 -             return component->getTabBarDepth();
 -         }
 - 
 -         TabbedComponent* const component;
 -         JucerDocument& document;
 - 
 -     private:
 -         void changeListenerCallback (ChangeBroadcaster*) override
 -         {
 -             refresh();
 -         }
 - 
 -         class TabDepthChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabDepthChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int newState_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   newState (newState_)
 -             {
 -                 oldState = comp->getTabBarDepth();
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setTabBarDepth (newState);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setTabBarDepth (oldState);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             int newState, oldState;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabAddTabProperty  : public ButtonPropertyComponent
 -     {
 -     public:
 -         TabAddTabProperty (TabbedComponent* comp, JucerDocument& doc)
 -             : ButtonPropertyComponent ("add tab", false),
 -               component (comp),
 -               document (doc)
 -         {
 -         }
 - 
 -         void buttonClicked()
 -         {
 -             document.perform (new AddTabAction (component, *document.getComponentLayout()),
 -                               "Add a new tab");
 -         }
 - 
 -         String getButtonText() const
 -         {
 -             return "Create a new tab";
 -         }
 - 
 -         TabbedComponent* const component;
 -         JucerDocument& document;
 - 
 -     private:
 -         class AddTabAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             AddTabAction (TabbedComponent* const comp, ComponentLayout& l)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l)
 -             {
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 addNewTab (getComponent());
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->removeTab (getComponent()->getNumTabs() - 1);
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -                 return true;
 -             }
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabRemoveTabProperty  : public ButtonPropertyComponent
 -     {
 -     public:
 -         TabRemoveTabProperty (TabbedComponent* comp, JucerDocument& doc)
 -             : ButtonPropertyComponent ("remove tab", true),
 -               component (comp),
 -               document (doc)
 -         {
 -         }
 - 
 -         void buttonClicked()
 -         {
 -             const StringArray names (component->getTabNames());
 - 
 -             PopupMenu m;
 -             for (int i = 0; i < component->getNumTabs(); ++i)
 -                 m.addItem (i + 1, "Delete tab " + String (i)
 -                                     + ": \"" + names[i] + "\"");
 - 
 -             const int r = m.showAt (this);
 - 
 -             if (r > 0)
 -             {
 -                 document.perform (new RemoveTabAction (component, *document.getComponentLayout(), r - 1),
 -                                   "Remove a tab");
 -             }
 -         }
 - 
 -         String getButtonText() const
 -         {
 -             return "Delete a tab...";
 -         }
 - 
 -         TabbedComponent* const component;
 -         JucerDocument& document;
 - 
 -     private:
 -         class RemoveTabAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             RemoveTabAction (TabbedComponent* const comp, ComponentLayout& l, int indexToRemove_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   indexToRemove (indexToRemove_)
 -             {
 -                 previousState = getTabState (comp, indexToRemove);
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 - 
 -                 getComponent()->removeTab (indexToRemove);
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 addNewTab (getComponent(), indexToRemove);
 -                 restoreTabState (getComponent(), indexToRemove, *previousState);
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -                 return true;
 -             }
 - 
 -         private:
 -             int indexToRemove;
 -             std::unique_ptr<XmlElement> previousState;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabNameProperty  : public ComponentTextProperty<TabbedComponent>
 -     {
 -     public:
 -         TabNameProperty (TabbedComponent* comp, JucerDocument& doc, const int tabIndex_)
 -             : ComponentTextProperty<TabbedComponent> ("name", 200, false, comp, doc),
 -               tabIndex (tabIndex_)
 -         {
 -         }
 - 
 -         void setText (const String& newText) override
 -         {
 -             document.perform (new TabNameChangeAction (component, *document.getComponentLayout(), tabIndex, newText),
 -                               "Change tab name");
 -         }
 - 
 -         String getText() const override
 -         {
 -             return component->getTabNames() [tabIndex];
 -         }
 - 
 -     private:
 -         int tabIndex;
 - 
 -         class TabNameChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabNameChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int tabIndex_, const String& newValue_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   tabIndex (tabIndex_),
 -                   newValue (newValue_)
 -             {
 -                 oldValue = comp->getTabNames() [tabIndex];
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setTabName (tabIndex, newValue);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setTabName (tabIndex, oldValue);
 -                 changed();
 -                 return true;
 -             }
 - 
 -         private:
 -             const int tabIndex;
 -             String newValue, oldValue;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabColourProperty  : public JucerColourPropertyComponent,
 -                                private ChangeListener
 -     {
 -     public:
 -         TabColourProperty (TabbedComponent* comp, JucerDocument& doc, const int tabIndex_)
 -             : JucerColourPropertyComponent ("colour", false),
 -               component (comp),
 -               document (doc),
 -               tabIndex (tabIndex_)
 -         {
 -             document.addChangeListener (this);
 -         }
 - 
 -         ~TabColourProperty() override
 -         {
 -             document.removeChangeListener (this);
 -         }
 - 
 -         void setColour (Colour newColour) override
 -         {
 -             document.getUndoManager().undoCurrentTransactionOnly();
 - 
 -             document.perform (new TabColourChangeAction (component, *document.getComponentLayout(), tabIndex, newColour),
 -                               "Change tab colour");
 -         }
 - 
 -         Colour getColour() const override
 -         {
 -             return component->getTabBackgroundColour (tabIndex);
 -         }
 - 
 -         void resetToDefault() override
 -         {
 -             jassertfalse; // shouldn't get called
 -         }
 - 
 -         void changeListenerCallback (ChangeBroadcaster*) override     { refresh(); }
 - 
 -     private:
 -         TabbedComponent* component;
 -         JucerDocument& document;
 -         int tabIndex;
 - 
 -         class TabColourChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabColourChangeAction (TabbedComponent* comp, ComponentLayout& l,
 -                                    int tabIndex_, Colour newValue_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   tabIndex (tabIndex_),
 -                   newValue (newValue_)
 -             {
 -                 oldValue = comp->getTabBackgroundColour (tabIndex);
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setTabBackgroundColour (tabIndex, newValue);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 getComponent()->setTabBackgroundColour (tabIndex, oldValue);
 -                 changed();
 -                 return true;
 -             }
 - 
 -         private:
 -             const int tabIndex;
 -             Colour newValue, oldValue;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabContentTypeProperty  : public ComponentChoiceProperty<TabbedComponent>
 -     {
 -     public:
 -         TabContentTypeProperty (TabbedComponent* comp, JucerDocument& doc, const int tabIndex_)
 -             : ComponentChoiceProperty<TabbedComponent> ("content type", comp, doc),
 -               tabIndex (tabIndex_)
 -         {
 -             choices.add ("Jucer content component");
 -             choices.add ("Named content component");
 -         }
 - 
 -         void setIndex (int newIndex)
 -         {
 -             document.perform (new TabContentTypeChangeAction (component, *document.getComponentLayout(), tabIndex, newIndex == 0),
 -                               "Change tab content type");
 -         }
 - 
 -         int getIndex() const
 -         {
 -             return isTabUsingJucerComp (component, tabIndex) ? 0 : 1;
 -         }
 - 
 -     private:
 -         int tabIndex;
 - 
 -         class TabContentTypeChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabContentTypeChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int tabIndex_, const bool newValue_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   tabIndex (tabIndex_),
 -                   newValue (newValue_)
 -             {
 -                 oldValue = isTabUsingJucerComp (comp, tabIndex);
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 setTabUsingJucerComp (getComponent(), tabIndex, newValue);
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 setTabUsingJucerComp (getComponent(), tabIndex, oldValue);
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -                 return true;
 -             }
 - 
 -         private:
 -             int tabIndex;
 -             bool newValue, oldValue;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabJucerFileProperty   : public FilePropertyComponent,
 -                                    private ChangeListener
 -     {
 -     public:
 -         TabJucerFileProperty (TabbedComponent* const comp, JucerDocument& doc, const int tabIndex_)
 -             : FilePropertyComponent ("jucer file", false, true),
 -               component (comp),
 -               document (doc),
 -               tabIndex (tabIndex_)
 -         {
 -             document.addChangeListener (this);
 -         }
 - 
 -         ~TabJucerFileProperty() override
 -         {
 -             document.removeChangeListener (this);
 -         }
 - 
 -         //==============================================================================
 -         void setFile (const File& newFile) override
 -         {
 -             document.perform (new JucerCompFileChangeAction (component, *document.getComponentLayout(), tabIndex,
 -                                                              newFile.getRelativePathFrom (document.getCppFile().getParentDirectory())
 -                                                                     .replaceCharacter ('\\', '/')),
 -                               "Change tab component file");
 -         }
 - 
 -         File getFile() const override
 -         {
 -             return document.getCppFile().getSiblingFile (getTabJucerFile (component, tabIndex));
 -         }
 - 
 -     private:
 -         void changeListenerCallback (ChangeBroadcaster*) override { refresh(); }
 - 
 -         TabbedComponent* const component;
 -         JucerDocument& document;
 -         int tabIndex;
 - 
 -         class JucerCompFileChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             JucerCompFileChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int tabIndex_, const String& newState_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   tabIndex (tabIndex_),
 -                   newState (newState_)
 -             {
 -                 oldState = getTabJucerFile (comp, tabIndex);
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 setTabJucerFile (getComponent(), tabIndex, newState);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 setTabJucerFile (getComponent(), tabIndex, oldState);
 -                 changed();
 -                 return true;
 -             }
 - 
 -             int tabIndex;
 -             String newState, oldState;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabContentClassProperty   : public ComponentTextProperty<TabbedComponent>
 -     {
 -     public:
 -         TabContentClassProperty (TabbedComponent* comp, JucerDocument& doc, const int tabIndex_)
 -             : ComponentTextProperty<TabbedComponent> ("content class", 256, false, comp, doc),
 -               tabIndex (tabIndex_)
 -         {
 -         }
 - 
 -         void setText (const String& newText) override
 -         {
 -             document.perform (new TabClassNameChangeAction (component, *document.getComponentLayout(), tabIndex, newText),
 -                               "Change TabbedComponent content class");
 -         }
 - 
 -         String getText() const override
 -         {
 -             return getTabClassName (component, tabIndex);
 -         }
 - 
 -     private:
 -         int tabIndex;
 - 
 -         class TabClassNameChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabClassNameChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int tabIndex_, const String& newValue_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   tabIndex (tabIndex_),
 -                   newValue (newValue_)
 -             {
 -                 oldValue = getTabClassName (comp, tabIndex);
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 setTabClassName (getComponent(), tabIndex, newValue);
 -                 changed();
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 setTabClassName (getComponent(), tabIndex, oldValue);
 -                 changed();
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 return true;
 -             }
 - 
 -             int tabIndex;
 -             String newValue, oldValue;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabContentConstructorParamsProperty   : public ComponentTextProperty<TabbedComponent>
 -     {
 -     public:
 -         TabContentConstructorParamsProperty (TabbedComponent* comp, JucerDocument& doc, const int tabIndex_)
 -             : ComponentTextProperty<TabbedComponent> ("constructor params", 512, false, comp, doc),
 -               tabIndex (tabIndex_)
 -         {
 -         }
 - 
 -         void setText (const String& newText) override
 -         {
 -             document.perform (new TabConstructorParamChangeAction (component, *document.getComponentLayout(), tabIndex, newText),
 -                               "Change TabbedComponent content constructor param");
 -         }
 - 
 -         String getText() const override
 -         {
 -             return getTabConstructorParams (component, tabIndex);
 -         }
 - 
 -     private:
 -         int tabIndex;
 - 
 -         class TabConstructorParamChangeAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             TabConstructorParamChangeAction (TabbedComponent* const comp, ComponentLayout& l, const int tabIndex_, const String& newValue_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   tabIndex (tabIndex_),
 -                   newValue (newValue_)
 -             {
 -                 oldValue = getTabConstructorParams (comp, tabIndex);
 -             }
 - 
 -             bool perform()
 -             {
 -                 showCorrectTab();
 -                 setTabConstructorParams (getComponent(), tabIndex, newValue);
 -                 changed();
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 showCorrectTab();
 -                 setTabConstructorParams (getComponent(), tabIndex, oldValue);
 -                 changed();
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 return true;
 -             }
 - 
 -             int tabIndex;
 -             String newValue, oldValue;
 -         };
 -     };
 - 
 -     //==============================================================================
 -     class TabMoveProperty   : public ButtonPropertyComponent
 -     {
 -     public:
 -         TabMoveProperty (TabbedComponent* comp, JucerDocument& doc,
 -                          const int tabIndex_, const int totalNumTabs_)
 -             : ButtonPropertyComponent ("move tab", false),
 -               component (comp),
 -               document (doc),
 -               tabIndex (tabIndex_),
 -               totalNumTabs (totalNumTabs_)
 -         {
 - 
 -         }
 - 
 -         void buttonClicked()
 -         {
 -             PopupMenu m;
 -             m.addItem (1, "Move this tab up", tabIndex > 0);
 -             m.addItem (2, "Move this tab down", tabIndex < totalNumTabs - 1);
 - 
 -             const int r = m.showAt (this);
 - 
 -             if (r != 0)
 -                 document.perform (new MoveTabAction (component, *document.getComponentLayout(), tabIndex, tabIndex + (r == 2 ? 1 : -1)),
 -                                   "Move a tab");
 -         }
 - 
 -         String getButtonText() const
 -         {
 -             return "Move this tab...";
 -         }
 - 
 -         TabbedComponent* const component;
 -         JucerDocument& document;
 -         const int tabIndex, totalNumTabs;
 - 
 -     private:
 -         class MoveTabAction  : public ComponentUndoableAction<TabbedComponent>
 -         {
 -         public:
 -             MoveTabAction (TabbedComponent* const comp, ComponentLayout& l,
 -                            const int oldIndex_, const int newIndex_)
 -                 : ComponentUndoableAction<TabbedComponent> (comp, l),
 -                   oldIndex (oldIndex_),
 -                   newIndex (newIndex_)
 -             {
 -             }
 - 
 -             void move (int from, int to)
 -             {
 -                 showCorrectTab();
 - 
 -                 auto state = getTabState (getComponent(), from);
 - 
 -                 getComponent()->removeTab (from);
 -                 addNewTab (getComponent(), to);
 - 
 -                 restoreTabState (getComponent(), to, *state);
 - 
 -                 layout.getDocument()->refreshAllPropertyComps();
 -                 changed();
 -             }
 - 
 -             bool perform()
 -             {
 -                 move (oldIndex, newIndex);
 -                 return true;
 -             }
 - 
 -             bool undo()
 -             {
 -                 move (newIndex, oldIndex);
 -                 return true;
 -             }
 - 
 -         private:
 -             const int oldIndex, newIndex;
 -         };
 -     };
 - };
 
 
  |