FileTreeComponent


#1

Hi everyone, what's up ?

I'm new in Juce and a noob in programming too (but I understand a lot...) cheeky.

I'm trying to create a FileTreeComponent just like the one in JuceDemo "AudioPlaybackDemo.cpp", but no result at all and only errors. I would appreciate a lot if someone told me an example of it...

I saw the documentation of juce classes for a FileTreeComponent, DirectoryContentsList and TimeSliceThread but i got a bit confused with them so i really need help from you.

Waiting for anyones reply....coolsmiley

 


#2

Why don't you pop up what you have so far?  

FileTreeComponent isn't the easiest place to start.  If you are just starting and you want to do file selection you might want to look at FileChooser and see if it'll do. 

 


#3

Otherwise, here's an example. Note that the construction/destruction order of the objects is important, and controlled by the order in which they are defined in the class (not the order they are called in the constructor...)

 

/** A design support class that displays a small square in the top left

 of a component. When clicked it displays a pop up font selection menu.

 When a font it selected it calls repaint on it's parent. */

class DesignerUserFontSelector

:

public Component,

public Button::Listener,

public FileBrowserListener

{

public:

    DesignerUserFontSelector(Component & componentToRepaint,

                             Font & fontToControl)

    :

    comp(componentToRepaint),

    fileChooser("Select a folder"),

    thread("Directory Contents Scanning Thread"),

    directoryContentsList(nullptr, thread),

    tree(directoryContentsList),

    openButton("Open Folder"),

    font(fontToControl)

    {

        thread.startThread();

        addAndMakeVisible(tree);

        addAndMakeVisible(openButton);


        openButton.addListener(this);

        tree.addListener(this);

    }


    void resized()

    {

        tree        .setBounds(getLocalBounds().withTrimmedBottom(20));

        openButton  .setBounds(getLocalBounds().withTop(getHeight()-20));

    }


    void updateFont(const Typeface::Ptr & typefaceToUse)

    {

        float h = font.getHeight();

        font = Font(newTypeface);

        font.setHeight(h);

        comp.repaint();

    }


    void buttonClicked(Button *)

    {

        bool success = fileChooser.browseForDirectory();


        if (success)

        {

            directoryContentsList.setDirectory(fileChooser.getResult(), true, true);

            tree.refresh();

        }

    }



    void fileClicked(const File & newFile, const MouseEvent &) override

    {

        MemoryBlock mb;

        bool success = newFile.loadFileAsData(mb);


        if (! success)

            return;


        if ( !(newFile.hasFileExtension("ttf") || newFile.hasFileExtension("otf")))

            return;


        newTypeface = Typeface::createSystemTypefaceFor(mb.getData(), mb.getSize());


        updateFont(newTypeface);

    }


    /* Unused overrides from FileBrowserListener. */

    void selectionChanged() override {}

    void fileDoubleClicked(const File &) override {}

    void browserRootChanged(const File &) override {}


private:

    Component & comp;

    FileChooser fileChooser;


    /* Order matters. */

    TimeSliceThread thread;

    DirectoryContentsList directoryContentsList;

    FileTreeComponent tree;

    /* Order ceases to matter. */


    TextButton openButton;

    Typeface::Ptr newTypeface;

    Font & font;

};

#4

Thanks Bazrush for the reply...I saw your example and i used it but again I got an error like this " error C2512: 'CustomComponent2' : no appropriate default constructor available ".

Here is my header file codes.


#ifndef CUSTOMCOMPONENT2_H_INCLUDED
#define CUSTOMCOMPONENT2_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
/*
*/
class CustomComponent2    : public Component,
                            public Button::Listener,
                            public FileBrowserListener
{
public:
    CustomComponent2(Component & componentToRepaint, Font & fontToControl);
    ~CustomComponent2();
    void paint (Graphics&);
    void resized();
     void updateFont(const Typeface::Ptr & typefaceToUse);
     void buttonClicked(Button *);
     void fileClicked(const File & newFile, const MouseEvent &) override;
     void selectionChanged() override;
     void fileDoubleClicked(const File &) override;
     void browserRootChanged(const File &) override;
private:
    Component & comp;
    FileChooser fileChooser;

    /* Order matters. */
    TimeSliceThread thread;
    DirectoryContentsList directoryContentsList;
    FileTreeComponent tree;
    /* Order ceases to matter. */

    TextButton openButton;
    Typeface::Ptr newTypeface;
    Font & font;
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CustomComponent2)
};

#endif  // CUSTOMCOMPONENT2_H_INCLUDED


And here is the cpp file code:


#include "../JuceLibraryCode/JuceHeader.h"
#include "CustomComponent2.h"
//==============================================================================
CustomComponent2::CustomComponent2(Component & componentToRepaint, Font & fontToControl)
    : comp(componentToRepaint),
    fileChooser("Select a folder"),
    thread("Directory Contents Scanning Thread"),
    directoryContentsList(nullptr, thread),
    tree(directoryContentsList),
    openButton("Open Folder"),
    font(fontToControl)
{
    thread.startThread();
        addAndMakeVisible(tree);
        addAndMakeVisible(openButton);

        openButton.addListener(this);
        tree.addListener(this);
    // In your constructor, you should add any child components, and
    setBounds(10, 150, 300, 500);
    // initialise any special settings that your component needs.
}
CustomComponent2::~CustomComponent2()
{
    
}
void CustomComponent2::paint (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 (Colours::white);   // clear the background
    
}
void CustomComponent2::resized()
{
    // This method is where you should set the bounds of any child
    tree.setBounds(15, 190, 200, 400);
    openButton.setBounds(15, 160, 80, 25);
    // components that your component contains..
}
void CustomComponent2::updateFont(const Typeface::Ptr & typefaceToUse)
    {
        float h = font.getHeight();
        font = Font(newTypeface);
        font.setHeight(h);
        comp.repaint();
    }
void CustomComponent2::buttonClicked(Button *)
    {
        bool success = fileChooser.browseForDirectory();

        if (success)
        {
            directoryContentsList.setDirectory(fileChooser.getResult(), true, true);
            tree.refresh();
        }
    }
void CustomComponent2::fileClicked(const File & newFile, const MouseEvent &) override
    {
        MemoryBlock mb;
        bool success = newFile.loadFileAsData(mb);

        if (! success)
            return;

        if ( !(newFile.hasFileExtension("ttf") || newFile.hasFileExtension("otf")))
            return;

        newTypeface = Typeface::createSystemTypefaceFor(mb.getData(), mb.getSize());

        updateFont(newTypeface);
    }
/* Unused overrides from FileBrowserListener. */
    void CustomComponent2::selectionChanged() override {}
    void CustomComponent2::fileDoubleClicked(const File &) override {}
    void CustomComponent2::browserRootChanged(const File &) override {}

 


#5

I forgot to say that I have a main component window where CustomComponent2 class is shown.

Here is the header and cpp of MainComponent Class.

Header:


#ifndef MAINCOMPONENT_H_INCLUDED
#define MAINCOMPONENT_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
#include "CustomComponent.h"
#include "CustomComponent2.h"
//==============================================================================
/*
    This component lives inside our window, and this is where you should put all
    your controls and content.
*/
class MainContentComponent   : public Component
{
public:
    //==============================================================================
    MainContentComponent();
    ~MainContentComponent();
    void paint (Graphics&);
    void resized();
private:
    CustomComponent custom;
    CustomComponent2 custom2;
    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

#endif  // MAINCOMPONENT_H_INCLUDED

Cpp:


#include "MainComponent.h"

//==============================================================================
MainContentComponent::MainContentComponent()
{
    addAndMakeVisible(&custom2);
    setSize (custom2.getWidth(), custom2.getHeight());
    addAndMakeVisible(&custom);
    setSize (custom.getWidth(), custom.getHeight());
    setSize(600, 400);
}
MainContentComponent::~MainContentComponent()
{
}
void MainContentComponent::paint (Graphics& g)
{
    g.fillAll (Colour (0xff001F36));
    g.setFont (Font (16.0f));
    g.setColour (Colours::white);
    g.drawText ("Hello World!", getLocalBounds(), Justification::centred, true);
}
void MainContentComponent::resized()
{
    // This is called when the MainContentComponent is resized.
    // If you add any child components, this is where you should
    // update their positions.
}

I have another CustomComponent class where i have created some buttons, a slider and a text editor to open files and save txt files and it works just fine.

Don't forget that i am a begginner in juce platform :P and my background in programming isn't very good, so i may have write something bad.


#6

Yeah - you've left in lots of my stuff which you didn't need.  You need to remove the stuff about fonts and the componentToRepaint which was my original application. 

I think maybe a gentle introduction to C++ guide might be good too ;-) 

http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list

 

If a constructor looks like: 

class SomeClass { SomeClass(int someParameter) {} };

Then you can't do:

main () 

{ 

SomeClass someInstanceOfTheClass;

}

Because you need a parameter for the constructor (someParameter).  You can have multiple constructors to choose from.  But this is going to get way more complicated that can be explained here :)


#7

Thanks again for the first reply ( i mean the example) laugh.

I took the codes one by one and i found where the problem was...Actually the problem was at the FileBrowserListener so I removed that and now it works fine...I wanted to show a FileTreeComponent without a filechoser button, but for now its ok...maybe later I will try again to make it without a button so the files of a directory are shown directly in the tree component.

Thanks a lot for your help man. yeswink