Open a new window?

Hello

i’m pretty new to all this and have been getting along pretty well with the tutorials and demo projects. I have however run in to a problem and I was hoping someone could point me in the right direction?

Basically I want to create a preferences window for an audio application. I have looked at the demo projects like widgets and windows demo but i cant work out how to create a show a simple empty box, opened with a button, that i can then fill with buttons and combo boxes.

could someone point me to where i might look for a step by step on this?

You create a Component and call

  • setBounds() or setSize()
  • addToDesktop()
  • setVisible()

Depending on what decorations you want, there are various subclasses like

Hi daniel

Thanks very much for your reply. You have been very helpful in the past.

Do I add this in the same way as any other component in the main component? And add attributes in the main component constructor?

The Component can be owned by your MainComponent, but doesn’t have to. You also don’t need addAndMakeVisible, since that would add it as sub component.

The Component itself doesn’t take attributes, but the ResizableWindow does.
There is an overload that takes the window flags, like maximiseButton etc…

Have a look at the reference of addToDesktop(), probably best to use at least TopLevelWindow

Hi Daniel

im sorry im afraid im really showing my ignorance. i attempted to add a component and then do as you said :

  • setBounds() or setSize()
  • addToDesktop()
  • setVisible()

in the main component constructor and i ended up with only one window.

im sure all this comes from a simple failure of understanding on my part. where should i be putting the code for this?

You add a member to your MainWindow class and a method to open:

class MainWindow : public Component
{
public:
    MainWindow()
    {
        addAndMakeVisible (openWindow);
        openWindow.onClick = [&]
        {
            if (window)
                window->bringToFront();
            else
            {
                window = new TopLevelWindow();
                window->addToDesktop ();
                window->centreWithSize (600, 400);
                window->setVisible (true);
            }
    }
    ~MainWindow()
    {
        // there are probably nicer ways using RAII, but this copes with the window being closed and destroyed
        if (window)
            delete window;
    }

    void resized() override
    {
        openWindow.setBounds (10, 10, 70, 25);
    }
private:
    TextButton openWindow { {}, "Window" };
    Component::SafePointer<TopLevelWindow> window;
};

something along those lines, untested code…

hi

thanks very much for this. it getting there.

i created then components and then this is my .cpp file

MainComponent::MainComponent()
{
addAndMakeVisible (openWindow);
openWindow.onClick = [&]
{
if (window)
window->toFront(true);
else
{
window = new TopLevelWindow(“Window”,true);
window->addToDesktop ();
window->centreWithSize (600, 400);
window->setVisible (true);
}
};

setSize (600, 400);

}

MainComponent::~MainComponent()
{
if (window)
delete window;
}

//==============================================================================
void MainComponent::paint (Graphics& g)
{
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));

g.setFont (Font (16.0f));
g.setColour (Colours::white);
g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);

}

void MainComponent::resized()
{
openWindow.setBounds (10, 10, 70, 25);
}

this compiles but crashes when i try to open a window. the break point is:

void Component::paint (Graphics&)
{
// if your component is marked as opaque, you must implement a paint
// method and ensure that its entire area is completely painted.
jassert (getBounds().isEmpty() || ! isOpaque());
}

do i need to add some more code to tell juce what the window should look like?

I see, this is not a crash but a heads-up by juce.
jassert (condition) means wait here if that condition is not met, so the developer can read the advise given in the code:

// if your component is marked as opaque, you must implement a paint
// method and ensure that its entire area is completely painted.
jassert (getBounds().isEmpty() || ! isOpaque());

TopLevelComponent is a default component, that you should inherit and override paint().
Otherwise it is not painting anything inside that new window.

You can click on “continue” and this jassert will be skipped, but it will be called again on every paint() call, so you will need to fix that by actually adding some content to the new TopLevelWindow.

ahhhhh ok

thanks so much for your help. i have changed the top-level window to a document window and no longer get the break point (i guess because the document window is initiated with some content as default?)

one last question i have is. how do i now add content to my new window. i get that i need to create components in the normal way but os t7her a flag i should use to tell them that they belong to the new window and not the main window?

You create a specific window, i.e. inheriting the DocumentWindow, just like you (or the Projucer boilerplate) created the MainComponent.

You inherit the DocumentWindow and add the components as members there. And you call setContentNonOwned(component), just like your main window in main.cpp does, just in the child window.

great. so do i need to create a new component class in producer to do this?

IT WORKS !!!

hi Daniel. i worked it out based on your advice and a bit of hard work and trial and error. Thanks very much for helping and thanks even more for stoping helping and forcing me to work it out. All the info was there.

for anyone struggling in future. i created a new GUI component in producer that added most of the code i needed for me. then i created a NewWindow class (i just copied the main window class and changed the names) at the top of my mainComponent.cpp and set its setContentOwned to my new GUI component. probably not the cleanest way of doing it but i now have a new window with a label in it that say “Congratulations Rob!!” :grinning:

1 Like

Any chance you could elaborate on how you changed to the Document Window? I was following along and got all the up to the above jassert. Now I’m a bit stuck.

hello. sorry this project was some time ago and never actually came to anything. the way i created a new window was actually using producer using the GUI editor menu, create new GUI element. i then copied my main window class from my main.ccp and pasted it at the top of my mainComponent.ccp. i changed at name “mainWindow” to the name of my new window (in my case PrefWindow) in all of the pasted txt and i added the line

setContentOwned (new PreferencesComponent(), true);

note that PreferencesComponent is the name of the GUI element i made in producer and could be anything you like.

now i can open that window with

NewWindow = new PrefWindow(“Preferances”);