Altering content components on the same main window


#1

Hi all,

In the last few days I am thinking about the following JUCE-design issue :
Consider we have :
- only one main window and,
- many content components.
The issue is, what is the propper way to switch between content components, or to show some of them consecutively, according to user needs.

So far I have think about the following two designing patterns :

1. I use a singleton class with a data structure within (public around the application), in which I keep the main window pointer and a stack for the sequential appearance of the components. The last stored component is always the current shown one. In the constructor of each component I store it into the stack and in the destructor remove it from stack, so the previous one in the stack, is shown.

2. I have only one MAIN content component. When I need to use any other component, it is added to the MAIN one as a child and, removed from MAIN component, when it became out of use. By this way, there is no need to have a singleton class as in solution 1.

Solution 1 : It is a centralized procedure and every process can be an appropriate function into the singleton class(make the current component the contentOwned one, adjust the size and bounds of mainwindow according to component's size, shows current component, e.t.c.).

Solution 2 : Each component, is responsible to add itself as a child into the MAIN component, allows any user activity only on its elements, and at last restore the MAIN component's initial status when it goes out of scope.

Actually, I have no idea which of these designing patterns is the proper one, or if there is another better approache.

So, any suggestion on this issue is very appreciated.

Thanks in advance

George


#2

about 1): I would not use a singleton, as it is considered weak design and should be avoided. Instead I would add a backlink in a Component::SafePointer https://www.juce.com/doc/classComponent_1_1SafePointer to the main component and set it in the constructor.

Alternative a)

I have implemented switching guis inside a component in my project like this, it works without backlinks:

void MyAudioProcessorEditor::buttonClicked (Button* b)
{
    for (int i=0; i<processor.getNumMatrixPrograms(); ++i) {
        MatrixProgram* matrix = processor.getMatrixProgram (i);
        if (matrix && matrix->getMatrixName() == b->getComponentID()) {
            Component* matrixGUI = dynamic_cast<Component*> (processor.getMatrixProgram());
            removeChildComponent (matrixGUI);
            processor.setCurrentProgram (i);
            matrixGUI = dynamic_cast<Component*> (processor.getMatrixProgram());
            if (matrixGUI) {
                addAndMakeVisible (matrixGUI);
                matrixGUI->setBounds (getLocalBounds()); // or whatever space is reserved for it...
            }
            matrix->activate (this);
            return;
        }
    }
}

...just as an inspiration, MatrixProgram inherits Component* and provides it's gui together with the processing code (yes, that's not MVC, but kept it simple). And activate was the chance for the program to do some updates...

Alternative b)

Have a look at TabbedComponent: https://www.juce.com/doc/classTabbedComponent and set the tabBarDepth to 0, if you don't want the tab bar to be shown (eventually also the setOutline and setIndent). It provides all functionality to add several components and show only one of them at a time.

HTH

 


#3


The Alternative b, I think it is not a sufficient solution, because it requires that I will construct all content-componets at the app's start-up and it does not seem as a good design practice.
The second one, looks fine. Personally, I allways appling  carefully (or  to scrupulously?) the MVC model,  but the proposed alternative b, does not prevent me from it.
Thanks for your advice
 
George