I am fairly new to C++ and JUCE and frankly am finding C++ to be one of the more difficult languages I’ve practiced. I am creating a simple DJ deck type application using JUCE and Visual Studio on Windows. I have been researching how to implement a playlist that gets and displays audio files, and file meta data from a directory. So far I have created a table to display the tracks but am having trouble understanding how to display the directory contents. I have seen in this forum thread that I can use DirectoryContentsList to do this however I have tried to implement it but only receive the error “no defult constructor exists for class ‘juce::DisplayContentsList’”. Can anyone tell me how to implement this in more detail and help me by providing any further advice for displaying the audio files and their meta data, adding more files and adding a search feature?
ee my code so far below:
PlaylistComponent.h
#pragma once
#include <vector>
#include <string>
#include <JuceHeader.h>
#include "DeckGUI.h"
using namespace juce;
class PlaylistComponent : public Component,
public TableListBoxModel,
public DirectoryContentsList,
public Button::Listener
{
public:
PlaylistComponent();
~PlaylistComponent() override;
void paint (Graphics&) override;
void resized() override;
int getNumRows () override;
void paintRowBackground (Graphics &, int rowNumber,
int width, int height,
bool rowIsSelected) override;
void paintCell (Graphics &, int rowNumber,
int columnId, int width,
int height, bool rowIsSelected) override;
Component* refreshComponentForCell(int rowNumber,
int columnId,
bool isRowSelected,
Component* existingComponentToUpdate) override;
void buttonClicked(Button* button) override;
private:
TableListBox tableComponent;
DirectoryContentsList trackPlaylist;
std::vector<std::string> trackTitles;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PlaylistComponent)
};
PlaylistComponent.cpp
#include <JuceHeader.h>
#include "PlaylistComponent.h"
PlaylistComponent::PlaylistComponent()
{
// In your constructor, you should add any child components, and
// initialise any special settings that your component needs.
trackTitles.push_back("Track 1");
trackTitles.push_back("Track 2");
trackTitles.push_back("Track 3");
tableComponent.getHeader().addColumn("Track Title", 1, 400);
tableComponent.getHeader().addColumn(" ", 2, 200);
tableComponent.setModel(this);
addAndMakeVisible(tableComponent);
}
PlaylistComponent::~PlaylistComponent()
{
}
void PlaylistComponent::paint (juce::Graphics& g)
{
/* This demo code just fills the component's background and
draws some placeholder text to get you started.
You should replace everything in this method with your own
drawing code..
*/
g.fillAll (getLookAndFeel().findColour (juce::ResizableWindow::backgroundColourId)); // clear the background
g.setColour (juce::Colours::grey);
g.drawRect (getLocalBounds(), 1); // draw an outline around the component
g.setColour (juce::Colours::white);
g.setFont (14.0f);
g.drawText ("PlaylistComponent", getLocalBounds(),
juce::Justification::centred, true); // draw some placeholder text
}
void PlaylistComponent::resized()
{
// This method is where you should set the bounds of any child
// components that your component contains..
tableComponent.setBounds(0, 0, getWidth(), getHeight());
}
int PlaylistComponent::getNumRows()
{
return trackTitles.size();
}
void PlaylistComponent::paintRowBackground(Graphics & g, int rowNumber, int width, int height, bool rowIsSelected)
{
if (rowIsSelected)
{
g.fillAll(Colours::turquoise);
}
else {
g.fillAll(Colours::darkgrey);
}
}
void PlaylistComponent::paintCell(Graphics & g, int rowNumber, int columnId, int width, int height, bool rowIsSelected)
{
g.drawText(trackTitles[rowNumber],
2, 0,
width - 4, height,
Justification::centredLeft, true);
}
Component* PlaylistComponent::refreshComponentForCell(int rowNumber, int columnId, bool isRowSelected, Component* existingComponentToUpdate)
{
if (columnId == 2)
{
if (existingComponentToUpdate == nullptr)
{
TextButton* btn = new TextButton{ "Play" };
String id{ std::to_string(rowNumber) };
btn->setComponentID(id);
btn->addListener(this);
existingComponentToUpdate = btn;
}
}
return existingComponentToUpdate;
}
void PlaylistComponent::buttonClicked(Button* button)
{
int id = std::stoi(button->getComponentID().toStdString());
DBG("PlaylistComponent::buttonClicked " << trackTitles[id]);
}