Hello,
I want to create a symply application because i am a beginner with JUCE, i use the Demo project to help me to code my first component.
I have create an application who display Tabbedcomponent with MenuBar, i want to add a tab by my menu.
Mainwindow.cpp
class ContentComp : public Component, public MenuBarModel, public ApplicationCommandTarget { public: ContentComp (MainAppWindow& mainWindow_) : mainWindow (mainWindow_), currentDemoId (0) { setOpaque (true); invokeDirectly (showWidgets, true); } ~ContentComp() { deleteAllChildren(); } void paint (Graphics& g) { g.fillAll (Colours::grey); } void resized() { if (currentDemo != nullptr) { currentDemo->setBounds (getLocalBounds()); } } void showTab(Component* tabComp) { currentDemo = tabComp; addAndMakeVisible (currentDemo); resized(); } StringArray getMenuBarNames() { const char* const names[] = { "menu", nullptr }; return StringArray (names); } PopupMenu getMenuForIndex (int menuIndex, const String& /*menuName*/) { //liaison entre la vue et le controleur ApplicationCommandManager* commandManager = &(mainWindow.commandManager); PopupMenu menu; if (menuIndex == 0) { menu.addCommandItem (commandManager, showWidgets); menu.addCommandItem (commandManager, showAudio); menu.addSeparator(); menu.addCommandItem (commandManager, newFile); } return menu; } void menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/) { // most of our menu items are invoked automatically as commands, but we can handle the // other special cases here.. if (menuItemID >= 5001 && menuItemID < 5010) { const int engineIndex = menuItemID - 5001; #if JUCE_OPENGL if (engineIndex >= getPeer()->getAvailableRenderingEngines().size()) { setUsingOpenGLRenderer (true); return; } #endif setUsingOpenGLRenderer (false); getPeer()->setCurrentRenderingEngine (engineIndex); } } void setUsingOpenGLRenderer (bool shouldUseOpenGL) { } //============================================================================== // The following methods implement the ApplicationCommandTarget interface, allowing // this window to publish a set of actions it can perform, and which can be mapped // onto menus, keypresses, etc. ApplicationCommandTarget* getNextCommandTarget() { // this will return the next parent component that is an ApplicationCommandTarget (in this // case, there probably isn't one, but it's best to use this method in your own apps). return findFirstTargetParentComponent(); } void getAllCommands (Array <CommandID>& commands) { // this returns the set of all commands that this target can perform.. const CommandID ids[] = { showAudio, newFile, showWidgets }; commands.addArray (ids, numElementsInArray (ids)); } // This method is used when something needs to find out the details about one of the commands // that this object can perform.. void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result) { const String generalCategory ("General"); const String demosCategory ("Demos"); switch (commandID) { case newFile: result.setInfo ("New", String::empty, demosCategory, 0); result.setTicked (currentDemoId == newFile); result.addDefaultKeypress ('n', ModifierKeys::commandModifier); break; case showAudio: result.setInfo ("Audio", "Shows Audio selector", demosCategory, 0); result.setTicked (currentDemoId == showAudio); result.addDefaultKeypress ('.', ModifierKeys::commandModifier); break; case showWidgets: result.setInfo ("Widgets", "Shows the widgets demo", demosCategory, 0); result.setTicked (currentDemoId == showWidgets); result.addDefaultKeypress ('1', ModifierKeys::commandModifier); break; default: break; }; } bool perform (const InvocationInfo& info) { Component* comp = createTab(); switch (info.commandID) { case showWidgets: //showTab (createTab()); currentDemoId = showWidgets; break; case showAudio: AlertWindow::showMessageBox(AlertWindow::NoIcon, "Message","Ouvrir fichier"); break; case newFile: ((DemoTabbedComponent*) comp)->addNewTabb(); ((DemoTabbedComponent*) comp)->repaint(); showTab (createTab()); //test->postCommandMessage(10); AlertWindow::showMessageBox(AlertWindow::NoIcon, "Message","New fichier"); break; default: return false; }; return true; } private: MainAppWindow& mainWindow; ScopedPointer<Component> currentDemo; int currentDemoId; #if JUCE_OPENGL OpenGLContext openGLContext; #endif TooltipWindow tooltipWindow; // to add tooltips to an application, you // just need to create one of these and leave it // there to do its work.. //============================================================================== StringArray getRenderingEngines() { StringArray renderingEngines (getPeer()->getAvailableRenderingEngines()); #if JUCE_OPENGL renderingEngines.add ("Use OpenGL Renderer"); #endif return renderingEngines; } //============================================================================== enum CommandIDs { showAudio = 0x1000, showWidgets = 0x2000, newFile = 0x2006 }; //JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentComp) }; static ScopedPointer<ApplicationCommandManager> applicationCommandManager; static ScopedPointer<AudioDeviceManager> sharedAudioDeviceManager; //============================================================================== MainAppWindow::MainAppWindow() : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colours::lightgrey, DocumentWindow::allButtons) { setResizable (true, false); // resizability is a property of ResizableWindow setResizeLimits (805, 700, 8192, 8192); centreWithSize (805, 700); setVisible (true); contentComp = new ContentComp (*this); //permet de recuper les commandes que le composant recoit commandManager.registerAllCommandsForTarget (contentComp); commandManager.registerAllCommandsForTarget (JUCEApplication::getInstance()); addKeyListener (commandManager.getKeyMappings()); // sets the main content component for the window to be this tabbed // panel. This will be deleted when the window is deleted. setContentOwned (contentComp, false); // this tells the DocumentWindow to automatically create and manage a MenuBarComponent // which uses our contentComp as its MenuBarModel setMenuBar (contentComp); // tells our menu bar model that it should watch this command manager for // changes, and send change messages accordingly. contentComp->setApplicationCommandManagerToWatch (&commandManager); setVisible (true); } MainAppWindow::~MainAppWindow() { deleteAllChildren(); delete contentComp; } void MainAppWindow::closeButtonPressed() { JUCEApplication::getInstance()->systemRequestedQuit(); }
and TabComponent.cpp
#include "TabComponent.h" DemoTabbedComponent::DemoTabbedComponent() : TabbedComponent (TabbedButtonBar::TabsAtTop) { //ajout d'un onglet qui contient un composant addTab ("Projet 0", Colours::darkgrey, NULL, true); } DemoTabbedComponent::~DemoTabbedComponent() { //deleteAllChildren(); } // methode obligatoire à implémeter : ButtonListener void DemoTabbedComponent::buttonClicked (Button* button) { } void DemoTabbedComponent::addNewTabb() { printf("added !"); addTab ("test", Colours::darkgrey, NULL, true); } Component* createTab() { return new DemoTabbedComponent(); }
I try to add a new tab in my component with :
bool perform (const InvocationInfo& info) { Component* comp = createTab(); switch (info.commandID) { case newFile: ((DemoTabbedComponent*) comp)->addNewTabb(); ((DemoTabbedComponent*) comp)->repaint(); showTab (createTab()); AlertWindow::showMessageBox(AlertWindow::NoIcon, "Message","New fichier"); break; ....
But nothing change in my component... any idee ?
Also, when i close my application it crash (ContainerDeletePolicy 0