7

Coming from making single-page applications with the visual WYSISWYG editor in JUCE, I'm having a bit of trouble figuring out how to invoke new windows (outside of the main GUI window). I made a test application that just has a small minimal main GUI that I created with the visual editor. It has a button "Make New Window." My goal is to be able to click that button and have a new window pop up and that this new window is a JUCE "GUI component," (AKA, the graphical / visual GUI editor file). Now, I actually have sort of achieved this, however, its throwing errors and assertions, so it would be great to get a very simple, step-by-step tutorial.

I studied the main.cpp file that the Projucer automatically created in order to get a feel for how they are creating a window. Here's what I did.

1) In my project, I added a new GUI Component (which becomes a class) and called it "InvokedWindow." 2) In my main GUI component class header, I added a new scoped pointer of type InvokedWindow: ScopedPointer<InvokedWindow> invokedWindow; 3) I created a new button in the main GUI editor called "Make New Window" and added this to the handler code: newWindowPtr = new InvokedWindow; so that any time the button is hit, a new object of type InvokedWindow is created. 4) In the InvokedWindow class, in the constructor, on top of the automatically generated code, I added:

setUsingNativeTitleBar (true);
setCentrePosition(400, 400);
setVisible (true);
setResizable(false, false);

Which I sort of got from the main file of the JUCE application.

I also added a slider to this new window just to add functionality to it.

5) I added an overloaded function to let me close the window:

void InvokedWindow::closeButtonPressed()
{
    delete this;
}

So, now when I run the app and click the make new window button, a new window does pop up, but I get an assertion:

/* Agh! You shouldn't add components directly to a ResizableWindow - this class
   manages its child components automatically, and if you add your own it'll cause
   trouble. Instead, use setContentComponent() to give it a component which
   will be automatically resized and kept in the right place - then you can add
   subcomponents to the content comp. See the notes for the ResizableWindow class
   for more info.

   If you really know what you're doing and want to avoid this assertion, just call
   Component::addAndMakeVisible directly.
*/

Also, I'm able to close the window once and hit the button in the main GUI to create another instance of a newWindow, but closing it a second time leads to an error:

template <typename ObjectType>
struct ContainerDeletePolicy
{
    static void destroy (ObjectType* object)
    {
        // If the line below triggers a compiler error, it means that you are using
        // an incomplete type for ObjectType (for example, a type that is declared
        // but not defined). This is a problem because then the following delete is
        // undefined behaviour. The purpose of the sizeof is to capture this situation.
        // If this was caused by a ScopedPointer to a forward-declared type, move the
        // implementation of all methods trying to use the ScopedPointer (e.g. the destructor
        // of the class owning it) into cpp files where they can see to the definition
        // of ObjectType. This should fix the error.
        ignoreUnused (sizeof (ObjectType));

        delete object;
    }
};

This is all a bit over my head. I was figuring it wouldn't be too bad to be able to create a new window, via a button. A new window that I could edit with the graphical GUI editor, but I'm not able to fully figure it out all on my own, through I did try. Could anyone post a step-by-step guide to doing this the correct way? I did post this at the JUCE forums, but due to my lack of GUI programming, I was unable to understand the solutions posted (my own fault), so I'm hoping to get a very simple guide to this. It would be very much appreciated. Thank you.

JosephTLyons
  • 2,075
  • 16
  • 39
  • I'm assuming this post is being downvoted for the length of it, but I feel it needed to be this long to accurately describe my situation and question. Nothing worse than providing too little information, then getting solutions that don't apply to your problem because your problem was misinterpreted or lacking vital information. – JosephTLyons May 04 '17 at 01:06
  • 1
    there's nothing wrong with your question, you did a great job of explaining what you want +1 plus if you are looking for a guide, maybe you could try this: https://www.juce.com/doc/tutorial_main_window I personally haven't done this before, but am very curious of how to do it. – King Reload May 06 '17 at 07:59
  • 1
    @KingReload, thanks for the reassurance. I often get down voted for my post lengths. Also, I've been through that tutorial and it is fairly good, however, I believe that it only lets you add a window that you have to hand-code everything (meaning, if you want to add to that new window a slider, knob, label, text editor, etc... you can't insert it via the graphical editor in JUCE, you must hand-code its placement, parameters, etc.). I would like to know how to open a new window, but that window be editable through the graphical JUCE editor. – JosephTLyons May 06 '17 at 08:04
  • I did find this: https://forum.juce.com/t/new-to-projucer-cant-find-how-to-edit-gui/20686/2 but don't know if that would be of any use, I really hope the answer will be found for this question very soon! And post length doesn't matter, only a better explenation, just try to cut different topics with `-------` or use `1.` instead of `1)`, cuz then those sections get split better and it will be more easy to read :) – King Reload May 06 '17 at 08:24
  • Oh yes, I know how to add a graphic GUI Component window to a Projucer project. However, I don't know how to invoke that new window to pop up during program runtime. All of my apps have been single page apps. I'm able to easily add a GUI component graphical editor for the main GUI of my app, as I only need to change a 2 things in the main.cpp (all the other code is already made) to get the main GUI to work, but adding a second window that pops up from a button click on the first window is what I'm trying to do. I've already built the window entirely graphically, just can't invoke it. – JosephTLyons May 06 '17 at 08:29

1 Answers1

6

I figured it out. I needed to create:

  1. A new GUI component (Remember, this is the visual editor in JUCE)
  2. A class (I called it BasicWindow, based on the JUCE demo code) that acts as a shell to run this new window and holds the GUI component.
  3. A JUCE SafePointer that makes a new object of type BasicWindow whenever the button is clicked and sets the attributes to that window.

Here is my code:

Referring to line 3) Inside the handler section of the button to create the new window:

basicWindow = new BasicWindow("Information", Colours::grey, DocumentWindow::allButtons);

basicWindow->setUsingNativeTitleBar(true);
basicWindow->setContentOwned(new InformationComponent(), true);// InformationComponent is my GUI editor component (the visual editor of JUCE)

basicWindow->centreWithSize(basicWindow->getWidth(), basicWindow->getHeight());
basicWindow->setVisible(true);

Referring to line 2) A .cpp file that defines what the BasicWindow is:

#include "../JuceLibraryCode/JuceHeader.h"

class BasicWindow : public DocumentWindow
{
private:
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BasicWindow)

public:
    BasicWindow (const String& name, Colour backgroundColour, int buttonsNeeded)
    : DocumentWindow (name, backgroundColour, buttonsNeeded)
    {
    }

    void closeButtonPressed() override
    {
        delete this;
    }
};

And referring to line 1) Make the GUI editor component, which this is easy to do. You just right add a new file in the JUCE file manager. "Add New GUI Component," then visually add all your elements and handler code.

My biggest issue was that I was using a JUCE ScopedPointer, so after deleting the object, the pointer pointing to it wasn't being set back to NULL. The SafePointer does this. If any more explanation is needed, I'm happy to help, as this was terrible for someone with not much GUI development "under his belt."

JosephTLyons
  • 2,075
  • 16
  • 39