Example Toolbar with buttons and popup menu


#1

Juce Friends,

I wanted to share with you my working Toolbar that I created, in the hopes that it will help save others time, pain, and frustration. Many thanks to Bruce Wheaton for his help. If you see any suggestions for the way I have implemented this, I’m all open. My next task will be to take a break, and then try the same implementation of this with an ApplicationCommandManager.

The goal was to create a Toolbar that can be added to different components with minimal effort. I’ve tested it and added the toolbar to two different component windows, and it works. The Toolbar has two buttons that can do different things.

In the main component that you want to add the Toolbar as a child, you add a ToolbarWorker class object in the constructor of your main component. A ToolbarWorker is just a class name that I came up for representing a toolbar object that does all of the work for you:

// Create ToolbarWorker object in constructor for main component window where you want to add the toolbar
addAndMakeVisible(tb = new ToolbarWorker());

You also have to declare the tb object and set the bounds for it in resized():
tb->setBounds(0,0,getWidth(), 30);

In the main component, I have one include file, “ToolbarWorker.h”. This is ToolbarWorker.h:

#ifndef TOOLBARWORKER_H
#define TOOLBARWORKER_H
#include "includes.h"

class ToolbarWorker  : public Component,
		       public ButtonListener
{
public:
	ToolbarWorker();
	~ToolbarWorker();

	void resized();
	void buttonClicked (Button* buttonThatWasClicked);

private:
	Toolbar* toolbar;
};
#endif

I also compile a separate cpp file, ToolbarWorker.cpp. This file adds the toolbar, making it visible, adds the button listeners for the toolbar buttons, and handles the action for when the buttons are clicked :

#include "ToolbarWorker.h"
#include "ToolbarItemFactory.h"
#include "Toolbar.h"
#include "ThemeComponent.h"
#include "MainWindow.h"

extern MainWindow* theMainWindow;

ToolbarWorker::ToolbarWorker()
	: toolbar(0)
{

	addAndMakeVisible(toolbar = new Toolbar());
	toolbar->addDefaultItems(factory);

	button1Info->addButtonListener(this);
	button2Logout->addButtonListener(this);

}

ToolbarWorker::~ToolbarWorker()
{
	deleteAndZero(toolbar);

}

void ToolbarWorker::resized()
{

	toolbar->setBounds(0,0,getWidth(), 30);

}

void ToolbarWorker::buttonClicked (Button* buttonThatWasClicked)
{

	if (buttonThatWasClicked == button2Logout)	
	{
        	AuthComponent* theauth;
        	theauth = new AuthComponent();
        	addAndMakeVisible(theauth);

        	theMainWindow->setName(T("Application Login Screen"));
        	theMainWindow->setContentComponent(theauth);
        	theMainWindow->setFullScreen(false);

    	}

	if (buttonThatWasClicked == button1Info)
	{
	        PopupMenu m;
        	m.addItem (1, T("About Application"));
        	m.addSeparator();
        	m.addItem (2, T("Themes"));
        	m.addSeparator();
        	m.addItem (3, T("Video Tutorials"));

        	int result = m.show();

		if (result == 0) {

		} else if (result == 1) {

			// user picked 'About Application'	
			AlertWindow::showMessageBox(AlertWindow::NoIcon, T("About Application"),T("Application version 1.00 Beta\nDeveloped by:  Unit, Company"
));
		} else if (result == 2) {

			ThemeComponent* themes;
			themes = new ThemeComponent();
			addAndMakeVisible(themes);

		} else if (result == 3) {

			// user picked video tutorials

		}

	}

}

ToolbarItemFactory.h handles the default items for creation of the Toolbar:

#include "includes.h"
#include "BinaryData.h"
#include "Toolbar.h"

class ApplicationToolbarItemFactory   : public ToolbarItemFactory
{
        public:
        ApplicationToolbarItemFactory() {}
        ~ApplicationToolbarItemFactory() {}

        enum DemoToolbarItemIds
        {
            infoButton = 1,
            logoutButton = 2,
        };

        void getAllToolbarItemIds (Array <int>& ids)
        {
            ids.add (infoButton);
            ids.add (logoutButton);
            ids.add (separatorBarId);
            ids.add (spacerId);
            ids.add (flexibleSpacerId);
        }

        void getDefaultItemSet (Array <int>& ids)
        {
            ids.add (separatorBarId);
            ids.add (flexibleSpacerId);
            ids.add (flexibleSpacerId);
            ids.add (separatorBarId);
            ids.add (infoButton);
            ids.add (separatorBarId);
            ids.add (logoutButton);
            ids.add (separatorBarId);
        }

        ToolbarItemComponent* createItem (const int itemId)
        {
            switch (itemId)
            {
            case infoButton:
		button1Info = new ToolbarButton (itemId, T("info"), Drawable::createFromImageData (BinaryData::letterI_png, BinaryData::letterI_pngSize), 0);
		return button1Info;

            case logoutButton:
		button2Logout = new ToolbarButton (itemId, T("logout"), Drawable::createFromImageData (BinaryData::letterL_png, BinaryData::letterL_pngSize),
 0);
		return button2Logout;

            default:
                break;
            }

            return 0;
        }
    private:

};

ApplicationToolbarItemFactory factory;

Last, the Toolbar.h declares a couple of variables that are shared between the classes (implemented just because I know how to do this in C and don’t know so easily how to share variables between classes in C++):

#ifndef TOOLBAR_H
#define TOOLBAR_H
ToolbarButton* button1Info;
ToolbarButton* button2Logout;
#endif