Why are ListBox so difficult?


#1

So I am fairly new to c++ and juce. I am trying to change one of the rotary sliders on the JuceDemoPlugin to a ListBox I have been at this scrawling the internet for examples for about 4 days now and still I have got no where and it's killing me.

I am able to draw the ListBox but how on earth do you fill it with any information - text - numbers - anything?? There seems to be no methods in the Juce Api for doing so. Why not?? Or am I missing somthing. 

So I create a ListBox in the PluginEditor.h

ListBox tempramentListbox;

I then instansiate it in the PluginEditor.cpp  JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemoPluginAudioProcessor* ownerFilter) function

tempramentListbox ("temprament"),

Then I make it visible

addAndMakeVisible (&tempramentListbox);

I have tried to understand this example:

http://www.juce.com/forum/topic/listbox-example

However it assumes a higher level of knowledge then I have unfortunatly. 

Where do the override functions go? Do you add them to the juce_ListBox.cpp or juce_ListBox.h files in the widgets folder of the library. Do I have to call these override functions from the PluginEditor.cpp file

I would share more code but I have none other then what is given in the above and in the forum example.

Any help would be greatly recieved. Please please please I am at my wits end. 

Thanks 

Richard


#2

You can't just add content to a ListBox as it has no way of knowing how to display the data and in what form it will be. You need to create a subclass of ListBoxModel which overrides the getNumRows and paintListBoxItem methods.

Once you have created your LstBoxModel subclass you can pass it to a ListBox to use.

 

About the simplest example of this is in the JuceDemo DragAndDropDemo.cpp file. Look at the top class, DragAndDropDemoSource. This actually subclasses both ListBox and ListBoxModel so you can just add it as you would a normal Component. You should just be able to copy this class into your own app and modify it to suit your needs.


#3

You need to create a model and implement some functions there which populate the listbox.


#4

Thanks for the speedy reply. 

So I took your advice and had a play with the ListBox in the DragAndDropDemo.cpp in JuceDemo and stripped away the drag and drop functionality so that what appeard was a simple ListBox. 

I then placed my edited DragAndDropDemo.cpp into a new file called ListBoxBuild.cpp and included this file in my workspace. 

#include "PluginEditor.h"

class ListBoxSource  :  public ListBox,
                        public ListBoxModel
{

public:
    ListBoxSource()
        : ListBox ("d+d source", 0)
    {
        // tells the ListBox that this object supplies the info about its rows.

        setModel (this);
        setMultipleSelectionEnabled (false);
    }
    
    //==============================================================================

    // The following methods implement the necessary virtual functions from ListBoxModel,
    // telling the listbox how many rows there are, painting them, etc.

    int getNumRows()
    {
        std::cout << "There are 5 rows";
        return 5;
    }
    
    void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
    {
        if (rowIsSelected)
            g.fillAll (Colours::lightblue);        

        g.setColour (Colours::black);
        g.setFont (height * 0.7f);
       
        g.drawText ("Row Number " + String (rowNumber + 1), 5, 0, width, height,
                    Justification::centredLeft, true);
    }
    
    //==============================================================================
    // this just fills in the background of the listbox

    void paint (Graphics& g)
    {
        g.fillAll (Colours::white.withAlpha (0.7f));
    }
};


//==============================================================================

class ListBoxBuild  : public Component
{
public:
    ListBoxBuild()
    {
        setName ("Temprament");
        addAndMakeVisible (&source);
    }
    
    ~ListBoxBuild()
    {
    }
    
    void resized()
    {
        source.setBounds (10, 10, 250, 150);
    }

    
private:
    ListBoxSource source;
};

//==============================================================================
Component* createListBox()
{
    return new ListBoxBuild();
}

Do I need to make a header file for my new ListBoxBuild.cpp file? 

I attempted to create a ListBox object in the JuceDemoPluginAudioProcessorEditor class of PluginEditor.h (this is where the components for the gui are created) using the ListBoxSource class 

private:

    String str;
    MidiKeyboardComponent midiKeyboard;
    Label infoLabel, midiNoteLabel, tempramentLabel, delayLengthLabel;
    Slider midiNoteSlider;
    ListBoxSource testListBox; // LISTBOX!!!!!!!!!!!!
    Slider delayLengthSlider;
    ScopedPointer<ResizableCornerComponent> resizer;
    ComponentBoundsConstrainer resizeLimits;

However this doesnt work as I am doing it wrong. How do I use the ListBoxSource class in my code?

Thanks