Ok, Jason. There’s a number of shennanigans in your code. I’ll point you the ones that jump out at me, but I suspect you should take a good look at some more C++ books and try to really get your head around object oriented programming. Please excuse me amusing myself as I write this.
OK, so, from the top.
test is a pointer to a drawable. I hope this is there just to test compilation? In your code, that pointer doesn’t get initialized. Consider using a stack object, like:
Drawable test();
That will be safer - even for tests - especially for tests, since pointer problems don’t help track things down.
Then you’re declaring a class DemoToolbarItemFactory, subclassed from ToolbarItemFactory. ToolbarItemFactory doesn’t inherit anything, as far as I can tell. So, your new class will be able to call methods:
it declares,
that ToolbarItemFactory declares.
You’ve declared a ‘buttonClicked’ method. That is not a method of ToolbarItemFactory, so it exists only in DemoToolbarItemFactory. Only other code that knows about (has included the header for) your class will ever be able to call that. In essence, that means your code only.
You’ve overriden getAllToolbarItemIds, getDefaultItemSet and createItem. Any code that knows about ToolbarItemFactory’s (most of juce) will able to call them.
But the code in createItem gets a bit wiggy.
Here’s the usual structure of a switch"
switch (int blahBlah)
{
case 1:
dostuff
break;
case 2:
{
do stuff in a sub-section so you can use local variables
}
break;
case 3:
do more stuff
// Caution - fall-through. Mark well, since we drop down and also do the case 4 stuff
case 4:
do even more stuff
break;
case 5:
case 6:
apparently, there’s stuff left to do
break;
default:
stuff
break;
}
Note - every case has a break. In the one case I chose to not to break right after, I understand it will fall through. In your code, you chose to return right from the case. That’s OK, I suppose. I tend not to do that - I would put a toolbarbutton into a pointer and return it at the end - then I can also check if it worked/caught any cases and do something if it didn’t.
Returning early isn’t wrong, but not putting a break could well screw up the compiler and is bad juju.
But that case is also where it goes off the other rail.
return new ToolbarButton (itemId, T(“info”), test, 0);
This creates a Toolbar button with an unitialized pointer for a drawable. That’s not a blank pointer, that’s some random bits, left over from whatever else you’ve been doing on your computer. It might be (worst case) a memory address in your program’s legal space, but more likely it’s be cruft. Your commented out alternative:
return new ToolbarButton (itemId, T(“info”), Drawable::createFromImageData (BinaryData::letterI_png, BinaryData::letterI_pngSize), 0);
Is more likely to be happy. In that line, you have returned a button from the function. The function is now gone, kaput, shuffled off this mortal coil etc.
That means your coup-de-grace never even takes the stage. Most compilers would probably optimize is out, if they were willing to compile it.
test->addButtonListener (this);
OK, so this says:
using the instance pointed to be the pointer ‘test’, which is an object of type ‘Drawable’, execute the method addButtonListener, with the parameter of ‘this’, to whit a pointer to an instance of DemoToolbarItemFactory.
C++ is silly isn’t it? I’m not dim, but C++ was the hardest thing I ever had to learn.
So, putting aside the fact that test may well be an unitialized pointer, and the worst thing it could do then would be to try to actually do it:
- Drawable is not a button, so doesn’t have an addButtonListener method.
- DemoToolbarItemFactory is not a buttonlistener, so a pointer to one can’t be used as a parameter to addButtonListener anyway.
This is all the C++ compiler protecting you.
So, deep breath. Let me try to guess at what you actually need.
Pick a class to be your ‘controller’. That class should be able to access your data, or send a command to a class about the button press. Make that class - it could be one you already have, like the window, or your app inherit from buttonlistener.
When you make the factory, make sure it can access the controller class. Do, maybe, something like this:
[code]ToolbarItemComponent* createItem (const int itemId)
{
ToolbarItemComponent* newItem = NULL;
switch (itemID)
{
case 1:
newItem = new ToolbarButton (itemId, T(“info”), Drawable::createFromImageData (BinaryData::letterI_png, BinaryData::letterI_pngSize), 0);
break;
etc
}
if (newItem)
{
newItem-> addButtonListener (jController);
}
return newItem;
}[/code]
Now in your controller class, implement a buttonClicked method. In fact, if you don’t, since it inherits from buttonListener, the compiler will throw an error.
C++, believe it or not, is your friend.
Hope that helps,
Bruce