The Red Penguin

Creating a DeckGUI class


Monday 3 August 2020

1. We need to go to Projucer - when you load it up it should load up the current project. Click + to add a new class. For this we are going to add a Component class. What this does is set out some boilerplate code in the new .h and .cpp files which is pretty handy. Then don't forget to go to File and Save Project in Projucer.

2. Open up the project in the IDE.

3. Now we need to get started on the code for the DeckGUI component by adding all of the different widgets that we need, those buttons and sliders, and then getting it to display correctly on the main component interface.

4. We need to move the buttons and sliders from MainComponent.h into DeckGUI.h. So we cut and paste these out of MC and into DG:
    juce::TextButton playButton{ "PLAY" };
juce::TextButton stopButton{ "STOP" };
juce::TextButton loadButton{ "LOAD" };

juce::Slider volSlider;
juce::Slider speedSlider;
juce::Slider posSlider;

5.We need to deal with AddAndMakeVisible. So we need to move this code from MainComponent.cpp to DeckGUI.cpp. This goes into DeckGUI::DeckGUI():
    addAndMakeVisible(playButton);
addAndMakeVisible(stopButton);
addAndMakeVisible(loadButton);
addAndMakeVisible(volSlider);
addAndMakeVisible(speedSlider);
addAndMakeVisible(posSlider);

6. We need to deal with Set Bounds. Go to resized() in MainComponent.cpp and copy to resized() in DeckGUI.cpp:
    double rowH = getHeight() / 6;
playButton.setBounds(0, 0, getWidth(), rowH);
stopButton.setBounds(0, rowH, getWidth(), rowH);
volSlider.setBounds(0, rowH *2, getWidth(), rowH);
speedSlider.setBounds(0, rowH * 3, getWidth(), rowH);
posSlider.setBounds(0, rowH * 4, getWidth(), rowH);
loadButton.setBounds(0, rowH * 5, getWidth(), rowH);

7. We now need to add an instance of DeckGUI to the MainComponent. We can go to MainComponent.h and add this:
#include "DeckGUI.h"

8. In private: in MainComponent.h we can add:
DeckGUI deckGUI1;

9. Having deleted all the text buttons and sliders from the private section in MainComponent.h, we need to remove any reference to these fields in the MainComponent. So we need to go to MainComponent.cpp. We've already removed the code from resized() in 6 above. We need to remove this code from MainComponent::buttonClicked
    //if (button == &playButton)
//{
// DBG("Play button was clicked");
// player1.start();
//}
//if (button == &stopButton)
//{
// DBG("Stop button was clicked");
// player1.stop();
//}
//if (button == &loadButton)
//{
// juce::FileChooser chooser{ "select file" };
// if (chooser.browseForFileToOpen())
// {
// player1.loadURL(juce::URL{ chooser.getResult() });
// }
//}

We comment this out for now. CTRL+K+C comments code, CTRL+K+U uncomments it.

10. We do the same with the slider listener code and comment it out:
    //if (slider == &volSlider)
//{
// player1.setGain(slider->getValue());
//}
//if (slider == &speedSlider)
//{
// player1.setSpeed(slider->getValue());
//}
//if (slider == &posSlider)
//{
// player1.setPositionRelative(slider->getValue());
//}

11. We also remove this from the MainComponent function in MainComponent.cpp:
    playButton.addListener(this);
stopButton.addListener(this);
loadButton.addListener(this);
volSlider.addListener(this);
speedSlider.addListener(this);
posSlider.addListener(this);

volSlider.setRange(0.0, 1.0);
posSlider.setRange(0.0, 1.0);

11. Inside the resized() function in MainComponent.cpp we need to set the bounds on the DeckGUI component. To do this we add:
deckGUI1.setBounds(0, 0, getWidth()/2, getHeight());

12. In MainComponent.cpp we need to add and make visible the DeckGUI component. To do this we add:
addAndMakeVisible(deckGUI1);

13. Now if we compile and build we can see the DeckGUI taking up one half of the screen. To illustrate how easy it is to add a new DeckGUI component we do this:

In MainComponent.h:
DeckGUI deckGUI2;

In MainComponent.cpp:
addAndMakeVisible(deckGUI2);

In MainComponent.cpp:
deckGUI2.setBounds(getWidth() / 2, 0, getWidth() / 2, getHeight());

When you run and build again, you see two decks side by side.