New Button: GuiBitmapButtonSimpleCtrl
by Chris Jorgensen · 04/20/2009 (10:16 pm) · 4 comments
I've been meaning to post this for a while. This is a simple button class that requires a single image. It also can have its image changed dynamically. I don't believe such an object exists by default in TGB, so I've added it. Ideally, this class would be in a new file. But for simplicity I appended existing files.
In guiBitmapButtonCtrl.h, go to the end of the file and add this:
In guiBitmapButtonCtrl.cc, go to the end of the file and add this:
That's it! Now you can change your button's image any time by doind a %id.bitmap = "image.png" type call. It also cuts down on button art requirements.
In guiBitmapButtonCtrl.h, go to the end of the file and add this:
//----------------------------------------
// NEW: a simplified button that can have its image changed
// Author: Chris Jorgensen
//----------------------------------------
class GuiBitmapButtonSimpleCtrl : public GuiButtonCtrl
{
private:
typedef GuiButtonCtrl Parent;
protected:
StringTableEntry mBitmapName;
TextureHandle mTextureHandle;
static bool setBitmapName( void *obj, const char *data );
void renderButton(TextureHandle &texture, Point2I &offset, const RectI& updateRect);
public:
DECLARE_CONOBJECT(GuiBitmapButtonSimpleCtrl);
GuiBitmapButtonSimpleCtrl();
static void initPersistFields();
//Parent methods
bool onWake();
void onSleep();
void inspectPostApply();
void setBitmap(const char *name,bool resize = false);
void onRender(Point2I offset, const RectI &updateRect);
};In guiBitmapButtonCtrl.cc, go to the end of the file and add this:
//----------------------------------------
// NEW: a simplified button that can have its image changed
// Author: Chris Jorgensen
//----------------------------------------
IMPLEMENT_CONOBJECT(GuiBitmapButtonSimpleCtrl);
//-------------------------------------
GuiBitmapButtonSimpleCtrl::GuiBitmapButtonSimpleCtrl()
{
mBitmapName = StringTable->insert("");
mBounds.extent.set(140, 30);
}
//-------------------------------------
void GuiBitmapButtonSimpleCtrl::initPersistFields()
{
Parent::initPersistFields();
addProtectedField( "bitmap", TypeFilename, Offset( mBitmapName, GuiBitmapButtonSimpleCtrl ), &setBitmapName, &defaultProtectedGetFn, "" );
}
//-------------------------------------
bool GuiBitmapButtonSimpleCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive(true);
setBitmap(mBitmapName);
return true;
}
//-------------------------------------
void GuiBitmapButtonSimpleCtrl::onSleep()
{
mTextureHandle = NULL;
Parent::onSleep();
}
//-------------------------------------
ConsoleMethod( GuiBitmapButtonSimpleCtrl, setBitmap, void, 3, 3, "(filepath name)")
{
object->setBitmap(argv[2]);
}
//-------------------------------------
void GuiBitmapButtonSimpleCtrl::inspectPostApply()
{
// if the extent is set to (0,0) in the gui editor and appy hit, this control will
// set it's extent to be exactly the size of the normal bitmap (if present)
Parent::inspectPostApply();
if ((mBounds.extent.x == 0) && (mBounds.extent.y == 0) && mTextureHandle)
{
TextureObject *texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
}
}
//-------------------------------------
void GuiBitmapButtonSimpleCtrl::setBitmap(const char *name, bool resize)
{
mBitmapName = StringTable->insert(name);
if (*mBitmapName) {
mTextureHandle = TextureHandle(mBitmapName, BitmapTexture, true);
if(resize)
{
// Resize the control to fit the bitmap
TextureObject* texture = (TextureObject *) mTextureHandle;
mBounds.extent.x = texture->bitmapWidth;
mBounds.extent.y = texture->bitmapHeight;
Point2I extent = getParent()->getExtent();
parentResized(extent,extent);
}
}
else
mTextureHandle = NULL;
setUpdate();
}
//-------------------------------------
void GuiBitmapButtonSimpleCtrl::onRender(Point2I offset, const RectI& updateRect)
{
renderButton(mTextureHandle, offset, updateRect);
}
//------------------------------------------------------------------------------
void GuiBitmapButtonSimpleCtrl::renderButton(TextureHandle &texture, Point2I &offset, const RectI& updateRect)
{
if (texture)
{
RectI rect(offset, mBounds.extent);
dglClearBitmapModulation();
dglDrawBitmapStretch(texture, rect);
renderChildControls( offset, updateRect);
}
else
Parent::onRender(offset, updateRect);
}
bool GuiBitmapButtonSimpleCtrl::setBitmapName( void *obj, const char *data )
{
// Prior to this, you couldn't do bitmap.bitmap = "foo.jpg" and have it work.
// With protected console types you can now call the setBitmap function and
// make it load the image.
static_cast<GuiBitmapButtonSimpleCtrl *>( obj )->setBitmap( data );
// Return false because the setBitmap method will assign 'mBitmapName' to the
// argument we are specifying in the call.
return false;
}That's it! Now you can change your button's image any time by doind a %id.bitmap = "image.png" type call. It also cuts down on button art requirements.
About the author
Owner of Cascadia Games LLC
#2
04/21/2009 (8:47 am)
It should still have all callbacks like onMouseDown. It actually works super handy. I finally had to cave and add it to my iTGB source. It's just too handy.
#3
04/21/2009 (8:50 am)
gotcha, i guess i mean what does the user see when they mouse-over the button ? ie, does it highlight ?
#4
04/21/2009 (8:59 am)
Correct. No highlight. No _n _h _u _d states. It's basically more like an image that doubles as a button. 
Associate Orion Elenzil
Real Life Plus
How does the button react to mouse-over, mouse-down, etc ?
In the past when i've wanted a button with a single dynamic bitmap i've put the bitmap on a GuiBitmapCtrl, and fitted a mostly-transparent four-state GuiBitmapButtonCtrl over it with generic images to handle mouse-over, click, etc.