Engine directory for ticket #1

This commit is contained in:
DavidWyand-GG 2012-09-19 11:15:01 -04:00
parent 352279af7a
commit 7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions

View file

@ -0,0 +1,552 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/buttons/guiBitmapButtonCtrl.h"
#include "core/util/path.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "console/engineAPI.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiDefaultControlRender.h"
#include "gfx/gfxDrawUtil.h"
ImplementEnumType( GuiBitmapMode,
"Rendering behavior when placing bitmaps in controls.\n\n"
"@ingroup GuiImages" )
{ GuiBitmapButtonCtrl::BitmapStretched, "Stretched", "Stretch bitmap to fit control extents." },
{ GuiBitmapButtonCtrl::BitmapCentered, "Centered", "Center bitmap in control." },
EndImplementEnumType;
//=============================================================================
// GuiBitmapButtonCtrl
//=============================================================================
IMPLEMENT_CONOBJECT(GuiBitmapButtonCtrl);
ConsoleDocClass( GuiBitmapButtonCtrl,
"@brief A button that renders its various states (mouse over, pushed, etc.) from separate bitmaps.\n\n"
"A bitmapped button is a push button that uses one or more texture images for rendering its individual states.\n\n"
"To find the individual textures associated with the button, a naming scheme is used. For each state "
"a suffix is appended to the texture file name given in the GuiBitmapButtonCtrl::bitmap field:\n"
"- \"_n\": Normal state. This one will be active when no other state applies.\n"
"- \"_h\": Highlighted state. This applies when the mouse is hovering over the button.\n"
"- \"_d\": Depressed state. This applies when the left mouse button has been clicked on the button but not yet released.\n"
"- \"_i\": Inactive state. This applies when the button control has been deactivated (GuiControl::setActive())\n\n"
"If a bitmap for a particular state cannot be found, the default bitmap will be used. To disable all state-based "
"bitmap functionality, set useStates to false which will make the control solely render from the bitmap specified "
"in the bitmap field.\n\n"
"@section guibitmapbutton_modifiers Per-Modifier Button Actions\n"
"If GuiBitmapButtonCtrl::useModifiers is set to true, per-modifier button actions and textures are enabled. This functionality "
"allows to associate different images and different actions with a button depending on which modifiers are pressed "
"on the keyboard by the user.\n\n"
"When enabled, this functionality alters the texture lookup above by prepending the following strings to the "
"suffixes listed above:\n"
"- \"\": Default. No modifier is pressed.\n"
"- \"_ctrl\": Image to use when CTRL/CMD is down.\n"
"- \"_alt\": Image to use when ALT is down.\n"
"- \"_shift\": Image to use when SHIFT is down\n\n"
"When this functionality is enabled, a new set of callbacks is used:\n"
"- onDefaultClick: Button was clicked without a modifier being presssed.\n"
"- onCtrlClick: Button was clicked with the CTRL/CMD key down.\n"
"- onAltClick: Button was clicked with the ALT key down.\n"
"- onShiftClick: Button was clicked with the SHIFT key down.\n\n"
"GuiControl::command or GuiControl::onAction() still work as before when per-modifier functionality is enabled.\n\n"
"Note that modifiers cannot be mixed. If two or more modifiers are pressed, a single one will take precedence over "
"the remaining modifiers. The order of precedence corresponds to the order listed above.\n\n"
"@tsexample\n"
"// Create an OK button that will trigger an onOk() call on its parent when clicked:\n"
"%okButton = new GuiBitmapButtonCtrl()\n"
"{\n"
" bitmap = \"art/gui/okButton\";\n"
" autoFitExtents = true;\n"
" command = \"$ThisControl.getParent().onOk();\";\n"
"};\n"
"@endtsexample\n\n"
"@ingroup GuiButtons"
);
IMPLEMENT_CALLBACK( GuiBitmapButtonCtrl, onDefaultClick, void, (), (),
"Called when per-modifier functionality is enabled and the user clicks on the button without any modifier pressed.\n"
"@ref guibitmapbutton_modifiers" );
IMPLEMENT_CALLBACK( GuiBitmapButtonCtrl, onCtrlClick, void, (), (),
"Called when per-modifier functionality is enabled and the user clicks on the button with the CTRL key pressed.\n"
"@ref guibitmapbutton_modifiers" );
IMPLEMENT_CALLBACK( GuiBitmapButtonCtrl, onAltClick, void, (), (),
"Called when per-modifier functionality is enabled and the user clicks on the button with the ALT key pressed.\n"
"@ref guibitmapbutton_modifiers" );
IMPLEMENT_CALLBACK( GuiBitmapButtonCtrl, onShiftClick, void, (), (),
"Called when per-modifier functionality is enabled and the user clicks on the button with the SHIFT key pressed.\n"
"@ref guibitmapbutton_modifiers" );
//-----------------------------------------------------------------------------
GuiBitmapButtonCtrl::GuiBitmapButtonCtrl()
{
mBitmapMode = BitmapStretched;
mAutoFitExtents = false;
mUseModifiers = false;
mUseStates = true;
setExtent( 140, 30 );
}
//-----------------------------------------------------------------------------
void GuiBitmapButtonCtrl::initPersistFields()
{
addGroup( "Bitmap" );
addProtectedField( "bitmap", TypeStringFilename, Offset( mBitmapName, GuiBitmapButtonCtrl ),
&_setBitmap, &defaultProtectedGetFn,
"Texture file to display on this button.\n"
"If useStates is false, this will be the file that renders on the control. Otherwise, this will "
"specify the default texture name to which the various state and modifier suffixes are appended "
"to find the per-state and per-modifier (if enabled) textures." );
addField( "bitmapMode", TYPEID< BitmapMode >(), Offset( mBitmapMode, GuiBitmapButtonCtrl ),
"Behavior for fitting the bitmap to the control extents.\n"
"If set to 'Stretched', the bitmap will be stretched both verticall and horizontally to fit inside "
"the control's extents.\n\n"
"If set to 'Centered', the bitmap will stay at its original resolution centered in the control's "
"rectangle (getting clipped if the control is smaller than the texture)." );
addProtectedField( "autoFitExtents", TypeBool, Offset( mAutoFitExtents, GuiBitmapButtonCtrl ),
&_setAutoFitExtents, &defaultProtectedGetFn,
"If true, the control's extents will be set to match the bitmap's extents when setting the bitmap.\n"
"The bitmap extents will always be taken from the default/normal bitmap (in case the extents of the various "
"bitmaps do not match up.)" );
addField( "useModifiers", TypeBool, Offset( mUseModifiers, GuiBitmapButtonCtrl ),
"If true, per-modifier button functionality is enabled.\n"
"@ref guibitmapbutton_modifiers" );
addField( "useStates", TypeBool, Offset( mUseStates, GuiBitmapButtonCtrl ),
"If true, per-mouse state button functionality is enabled.\n"
"Defaults to true.\n\n"
"If you do not use per-state images on this button set this to false to speed up the loading process "
"by inhibiting searches for the individual images." );
endGroup( "Bitmap" );
Parent::initPersistFields();
}
//-----------------------------------------------------------------------------
bool GuiBitmapButtonCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive( true );
setBitmap( mBitmapName );
return true;
}
//-----------------------------------------------------------------------------
void GuiBitmapButtonCtrl::onSleep()
{
if( dStricmp(mBitmapName, "texhandle") != 0 )
for( U32 i = 0; i < NumModifiers; ++ i )
{
mTextures[ i ].mTextureNormal = NULL;
mTextures[ i ].mTextureHilight = NULL;
mTextures[ i ].mTextureDepressed = NULL;
mTextures[ i ].mTextureInactive = NULL;
}
Parent::onSleep();
}
//-----------------------------------------------------------------------------
bool GuiBitmapButtonCtrl::_setAutoFitExtents( void *object, const char *index, const char *data )
{
GuiBitmapButtonCtrl* ctrl = reinterpret_cast< GuiBitmapButtonCtrl* >( object );
ctrl->setAutoFitExtents( dAtob( data ) );
return false;
}
//-----------------------------------------------------------------------------
bool GuiBitmapButtonCtrl::_setBitmap( void *object, const char *index, const char *data )
{
GuiBitmapButtonCtrl* ctrl = reinterpret_cast< GuiBitmapButtonCtrl* >( object );
ctrl->setBitmap( data );
return false;
}
//-----------------------------------------------------------------------------
// Legacy method. Can just assign to bitmap field.
DefineEngineMethod( GuiBitmapButtonCtrl, setBitmap, void, ( const char* path ),,
"Set the bitmap to show on the button.\n"
"@param path Path to the texture file in any of the supported formats.\n" )
{
object->setBitmap( path );
}
//-----------------------------------------------------------------------------
void GuiBitmapButtonCtrl::inspectPostApply()
{
Parent::inspectPostApply();
Torque::Path path( mBitmapName );
const String& fileName = path.getFileName();
if( mUseStates )
{
// If the filename points to a single state, automatically
// cut off the state part. Makes it easy to select files in
// the editor without having to go in and manually cut off the
// state parts all the time.
static String s_n = "_n";
static String s_d = "_d";
static String s_h = "_h";
static String s_i = "_i";
if( fileName.endsWith( s_n )
|| fileName.endsWith( s_d )
|| fileName.endsWith( s_h )
|| fileName.endsWith( s_i ) )
{
path.setFileName( fileName.substr( 0, fileName.length() - 2 ) );
path.setExtension( String::EmptyString );
}
}
setBitmap( path.getFullPath() );
// 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)
if ((getWidth() == 0) && (getHeight() == 0) && mTextures[ 0 ].mTextureNormal)
{
setExtent( mTextures[ 0 ].mTextureNormal->getWidth(), mTextures[ 0 ].mTextureNormal->getHeight());
}
}
//-----------------------------------------------------------------------------
void GuiBitmapButtonCtrl::setAutoFitExtents( bool state )
{
mAutoFitExtents = state;
if( mAutoFitExtents )
setBitmap( mBitmapName );
}
//-----------------------------------------------------------------------------
void GuiBitmapButtonCtrl::setBitmap( const String& name )
{
PROFILE_SCOPE( GuiBitmapButtonCtrl_setBitmap );
mBitmapName = name;
if( !isAwake() )
return;
if( !mBitmapName.isEmpty() )
{
if( dStricmp( mBitmapName, "texhandle" ) != 0 )
{
const U32 count = mUseModifiers ? NumModifiers : 1;
for( U32 i = 0; i < count; ++ i )
{
static String modifiers[] =
{
"",
"_ctrl",
"_alt",
"_shift"
};
static String s_n = "_n";
static String s_d = "_d";
static String s_h = "_h";
static String s_i = "_i";
String baseName = mBitmapName;
if( mUseModifiers )
baseName += modifiers[ i ];
mTextures[ i ].mTextureNormal = GFXTexHandle( baseName, &GFXDefaultPersistentProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
if( mUseStates )
{
if( !mTextures[ i ].mTextureNormal )
mTextures[ i ].mTextureNormal = GFXTexHandle( baseName + s_n, &GFXDefaultPersistentProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
mTextures[ i ].mTextureHilight = GFXTexHandle( baseName + s_h, &GFXDefaultPersistentProfile, avar("%s() - mTextureHighlight (line %d)", __FUNCTION__, __LINE__));
if( !mTextures[ i ].mTextureHilight )
mTextures[ i ].mTextureHilight = mTextures[ i ].mTextureNormal;
mTextures[ i ].mTextureDepressed = GFXTexHandle( baseName + s_d, &GFXDefaultPersistentProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__));
if( !mTextures[ i ].mTextureDepressed )
mTextures[ i ].mTextureDepressed = mTextures[ i ].mTextureHilight;
mTextures[ i ].mTextureInactive = GFXTexHandle( baseName + s_i, &GFXDefaultPersistentProfile, avar("%s() - mTextureInactive (line %d)", __FUNCTION__, __LINE__));
if( !mTextures[ i ].mTextureInactive )
mTextures[ i ].mTextureInactive = mTextures[ i ].mTextureNormal;
}
if( i == 0 && mTextures[ i ].mTextureNormal.isNull() && mTextures[ i ].mTextureHilight.isNull() && mTextures[ i ].mTextureDepressed.isNull() && mTextures[ i ].mTextureInactive.isNull() )
{
Con::warnf( "GuiBitmapButtonCtrl::setBitmap - Unable to load texture: %s", mBitmapName.c_str() );
this->setBitmap( "core/art/unavailable" );
return;
}
}
}
if( mAutoFitExtents && !mTextures[ 0 ].mTextureNormal.isNull() )
setExtent( mTextures[ 0 ].mTextureNormal.getWidth(), mTextures[ 0 ].mTextureNormal.getHeight() );
}
else
{
for( U32 i = 0; i < NumModifiers; ++ i )
{
mTextures[ i ].mTextureNormal = NULL;
mTextures[ i ].mTextureHilight = NULL;
mTextures[ i ].mTextureDepressed = NULL;
mTextures[ i ].mTextureInactive = NULL;
}
}
setUpdate();
}
//-----------------------------------------------------------------------------
void GuiBitmapButtonCtrl::setBitmapHandles(GFXTexHandle normal, GFXTexHandle highlighted, GFXTexHandle depressed, GFXTexHandle inactive)
{
const U32 count = mUseModifiers ? NumModifiers : 1;
for( U32 i = 0; i < count; ++ i )
{
mTextures[ i ].mTextureNormal = normal;
mTextures[ i ].mTextureHilight = highlighted;
mTextures[ i ].mTextureDepressed = depressed;
mTextures[ i ].mTextureInactive = inactive;
if (!mTextures[ i ].mTextureHilight)
mTextures[ i ].mTextureHilight = mTextures[ i ].mTextureNormal;
if (!mTextures[ i ].mTextureDepressed)
mTextures[ i ].mTextureDepressed = mTextures[ i ].mTextureHilight;
if (!mTextures[ i ].mTextureInactive)
mTextures[ i ].mTextureInactive = mTextures[ i ].mTextureNormal;
if (mTextures[ i ].mTextureNormal.isNull() && mTextures[ i ].mTextureHilight.isNull() && mTextures[ i ].mTextureDepressed.isNull() && mTextures[ i ].mTextureInactive.isNull())
{
Con::warnf("GuiBitmapButtonCtrl::setBitmapHandles() - Invalid texture handles");
setBitmap("core/art/unavailable");
return;
}
}
mBitmapName = "texhandle";
}
//------------------------------------------------------------------------------
GuiBitmapButtonCtrl::Modifier GuiBitmapButtonCtrl::getCurrentModifier()
{
U8 modifierKeys = Input::getModifierKeys();
if( modifierKeys & SI_PRIMARY_CTRL )
return ModifierCtrl;
else if( modifierKeys & SI_PRIMARY_ALT )
return ModifierAlt;
else if( modifierKeys & SI_SHIFT )
return ModifierShift;
return ModifierNone;
}
//------------------------------------------------------------------------------
GFXTexHandle& GuiBitmapButtonCtrl::getTextureForCurrentState()
{
U32 index = ModifierNone;
if( mUseModifiers )
index = getCurrentModifier();
if( !mUseStates )
{
if( mTextures[ index ].mTextureNormal )
return mTextures[ 0 ].mTextureNormal;
else
return mTextures[ index ].mTextureNormal;
}
switch( getState() )
{
case NORMAL:
if( !mTextures[ index ].mTextureNormal )
return mTextures[ 0 ].mTextureNormal;
else
return mTextures[ index ].mTextureNormal;
case HILIGHT:
if( !mTextures[ index ].mTextureHilight )
return mTextures[ 0 ].mTextureHilight;
else
return mTextures[ index ].mTextureHilight;
case DEPRESSED:
if( !mTextures[ index ].mTextureDepressed )
return mTextures[ 0 ].mTextureDepressed;
else
return mTextures[ index ].mTextureDepressed;
default:
if( !mTextures[ index ].mTextureInactive )
return mTextures[ 0 ].mTextureInactive;
else
return mTextures[ index ].mTextureInactive;
}
}
//------------------------------------------------------------------------------
void GuiBitmapButtonCtrl::onAction()
{
Parent::onAction();
if( mUseModifiers )
{
switch( getCurrentModifier() )
{
case ModifierNone:
onDefaultClick_callback();
break;
case ModifierCtrl:
onCtrlClick_callback();
break;
case ModifierAlt:
onAltClick_callback();
break;
case ModifierShift:
onShiftClick_callback();
break;
default:
break;
}
}
}
//------------------------------------------------------------------------------
void GuiBitmapButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
{
GFXTexHandle& texture = getTextureForCurrentState();
if( texture )
{
renderButton( texture, offset, updateRect );
renderChildControls( offset, updateRect );
}
else
Parent::onRender(offset, updateRect);
}
//------------------------------------------------------------------------------
void GuiBitmapButtonCtrl::renderButton( GFXTexHandle &texture, const Point2I &offset, const RectI& updateRect )
{
GFX->getDrawUtil()->clearBitmapModulation();
switch( mBitmapMode )
{
case BitmapStretched:
{
RectI rect( offset, getExtent() );
GFX->getDrawUtil()->drawBitmapStretch( texture, rect );
break;
}
case BitmapCentered:
{
Point2I p = offset;
p.x += getExtent().x / 2 - texture.getWidth() / 2;
p.y += getExtent().y / 2 - texture.getHeight() / 2;
GFX->getDrawUtil()->drawBitmap( texture, p );
break;
}
}
}
//=============================================================================
// GuiBitmapButtonTextCtrl.
//=============================================================================
IMPLEMENT_CONOBJECT( GuiBitmapButtonTextCtrl);
ConsoleDocClass( GuiBitmapButtonTextCtrl,
"@brief An extension of GuiBitmapButtonCtrl that additionally renders a text label on the bitmapped button.\n\n"
"The text for the label is taken from the GuiButtonBaseCtrl::text property.\n\n"
"For rendering, the label is placed, relative to the control's upper left corner, at the text offset specified in the "
"control's profile (GuiControlProfile::textOffset) and justified according to the profile's setting (GuiControlProfile::justify).\n\n"
"@see GuiControlProfile::textOffset\n"
"@see GuiControlProfile::justify\n"
"@ingroup GuiButtons"
);
//-----------------------------------------------------------------------------
void GuiBitmapButtonTextCtrl::renderButton( GFXTexHandle &texture, const Point2I &offset, const RectI& updateRect )
{
Parent::renderButton( texture, offset, updateRect );
Point2I textPos = offset;
if(mDepressed)
textPos += Point2I(1,1);
// Make sure we take the profile's textOffset into account.
textPos += mProfile->mTextOffset;
GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor );
renderJustifiedText(textPos, getExtent(), mButtonText);
}

View file

@ -0,0 +1,193 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUIBITMAPBUTTON_H_
#define _GUIBITMAPBUTTON_H_
#ifndef _GUIBUTTONCTRL_H_
#include "gui/buttons/guiButtonCtrl.h"
#endif
#ifndef _GFXTEXTUREMANAGER_H_
#include "gfx/gfxTextureManager.h"
#endif
/// A button control that uses bitmaps as its different button states.
///
/// Set 'bitmap' console field to base name of bitmaps to use. This control will
///
/// append '_n' for normal
/// append '_h' for highlighted
/// append '_d' for depressed
/// append '_i' for inactive
///
/// If a bitmap cannot be found it will use the default bitmap to render.
///
/// Additionally, a bitmap button can be made to react to keyboard modifiers. These can be
/// either CTRL/CMD, ALT, or SHIFT (but no combination of them.) To assign a different bitmap
/// for a modifier state, prepend "_ctrl", _"alt", or "_shift" to the state postfix.
///
/// To implement different handlers for the modifier states, use the "onDefaultClick",
/// "onCtrlClick", "onAltClick", and "onShiftClick" methods.
///
class GuiBitmapButtonCtrl : public GuiButtonCtrl
{
public:
typedef GuiButtonCtrl Parent;
enum BitmapMode
{
BitmapStretched,
BitmapCentered,
};
protected:
enum Modifier
{
ModifierNone,
ModifierCtrl,
ModifierAlt,
ModifierShift,
NumModifiers
};
enum State
{
NORMAL,
HILIGHT,
DEPRESSED,
INACTIVE
};
struct Textures
{
/// Texture for normal state.
GFXTexHandle mTextureNormal;
/// Texture for highlight state.
GFXTexHandle mTextureHilight;
/// Texture for depressed state.
GFXTexHandle mTextureDepressed;
/// Texture for inactive state.
GFXTexHandle mTextureInactive;
};
/// Make control extents equal to bitmap size.
bool mAutoFitExtents;
/// Allow switching out images according to modifier presses.
bool mUseModifiers;
/// Allow switching images according to mouse states. On by default.
/// Switch off when not needed as it otherwise results in a lot of costly
/// texture loads.
bool mUseStates;
///
BitmapMode mBitmapMode;
/// File name for bitmap.
String mBitmapName;
///
Textures mTextures[ NumModifiers ];
virtual void renderButton( GFXTexHandle &texture, const Point2I& offset, const RectI& updateRect );
static bool _setAutoFitExtents( void *object, const char *index, const char *data );
static bool _setBitmap( void *object, const char *index, const char *data );
State getState() const
{
if( mActive )
{
if( mDepressed || mStateOn ) return DEPRESSED;
if( mMouseOver ) return HILIGHT;
return NORMAL;
}
else
return INACTIVE;
}
Modifier getCurrentModifier();
GFXTexHandle& getTextureForCurrentState();
/// @name Callbacks
/// @{
DECLARE_CALLBACK( void, onDefaultClick, () );
DECLARE_CALLBACK( void, onCtrlClick, () );
DECLARE_CALLBACK( void, onAltClick, () );
DECLARE_CALLBACK( void, onShiftClick, () );
/// @}
public:
GuiBitmapButtonCtrl();
void setAutoFitExtents( bool state );
void setBitmap( const String& name );
void setBitmapHandles( GFXTexHandle normal, GFXTexHandle highlighted, GFXTexHandle depressed, GFXTexHandle inactive );
//Parent methods
virtual bool onWake();
virtual void onSleep();
virtual void onAction();
virtual void inspectPostApply();
virtual void onRender(Point2I offset, const RectI &updateRect);
static void initPersistFields();
DECLARE_CONOBJECT(GuiBitmapButtonCtrl);
DECLARE_DESCRIPTION( "A button control rendered entirely from bitmaps.\n"
"The individual button states are represented with separate bitmaps." );
};
typedef GuiBitmapButtonCtrl::BitmapMode GuiBitmapMode;
DefineEnumType( GuiBitmapMode );
/// Extension of GuiBitmapButtonCtrl that also display a text label on the button.
class GuiBitmapButtonTextCtrl : public GuiBitmapButtonCtrl
{
public:
typedef GuiBitmapButtonCtrl Parent;
protected:
virtual void renderButton( GFXTexHandle &texture, const Point2I& offset, const RectI& updateRect );
public:
DECLARE_CONOBJECT( GuiBitmapButtonTextCtrl );
DECLARE_DESCRIPTION( "An extension of GuiBitmapButtonCtrl that also renders a text\n"
"label on the button." );
};
#endif //_GUI_BITMAP_BUTTON_CTRL_H

View file

@ -0,0 +1,95 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "gui/core/guiCanvas.h"
#include "gui/buttons/guiButtonBaseCtrl.h"
#include "gui/core/guiDefaultControlRender.h"
class GuiBorderButtonCtrl : public GuiButtonBaseCtrl
{
typedef GuiButtonBaseCtrl Parent;
protected:
public:
DECLARE_CONOBJECT(GuiBorderButtonCtrl);
void onRender(Point2I offset, const RectI &updateRect);
};
IMPLEMENT_CONOBJECT(GuiBorderButtonCtrl);
ConsoleDocClass( GuiBorderButtonCtrl,
"@brief A push button that renders only a border.\n\n"
"A border button consists of a border rendered along its extents according to the border thickness defined in its profile "
"(GuiControlProfile::border). For the border color, a color is selected from the profile according to current button state:\n"
"- Default state: GuiControlProfile::borderColor\n"
"- Highlighted (mouse is over the button): GuiControlProfile::fontColorHL\n"
"- Depressed (mouse button down but not yet released): GuiControlProfile::fontColorSEL\n"
"@ingroup GuiButtons\n"
);
void GuiBorderButtonCtrl::onRender(Point2I offset, const RectI &updateRect)
{
if ( mProfile->mBorder > 0 )
{
RectI bounds( offset, getExtent() );
for ( S32 i=0; i < mProfile->mBorderThickness; i++ )
{
GFX->getDrawUtil()->drawRect( bounds, mProfile->mBorderColor );
bounds.inset( 1, 1 );
}
}
if ( mActive )
{
if ( mStateOn || mDepressed )
{
RectI bounds( offset, getExtent() );
for ( S32 i=0; i < mProfile->mBorderThickness; i++ )
{
GFX->getDrawUtil()->drawRect( bounds, mProfile->mFontColorSEL );
bounds.inset( 1, 1 );
}
}
if ( mMouseOver )
{
RectI bounds( offset, getExtent() );
for ( S32 i=0; i < mProfile->mBorderThickness; i++ )
{
GFX->getDrawUtil()->drawRect( bounds, mProfile->mFontColorHL );
bounds.inset( 1, 1 );
}
}
}
renderChildControls( offset, updateRect );
}

View file

@ -0,0 +1,544 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/buttons/guiButtonBaseCtrl.h"
#include "console/console.h"
#include "console/engineAPI.h"
#include "gfx/gfxDevice.h"
#include "gui/core/guiCanvas.h"
#include "i18n/lang.h"
#include "sfx/sfxSystem.h"
#include "sfx/sfxTrack.h"
IMPLEMENT_CONOBJECT( GuiButtonBaseCtrl );
ConsoleDocClass( GuiButtonBaseCtrl,
"@brief The base class for the various button controls.\n\n"
"This is the base class for the various types of button controls. If no more specific functionality is required than "
"offered by this class, then it can be instantiated and used directly. Otherwise, its subclasses should be used:\n"
"- GuiRadioCtrl (radio buttons)\n"
"- GuiCheckBoxCtrl (checkboxes)\n"
"- GuiButtonCtrl (push buttons with text labels)\n"
"- GuiBitmapButtonCtrl (bitmapped buttons)\n"
"- GuiBitmapButtonTextCtrl (bitmapped buttons with a text label)\n"
"- GuiToggleButtonCtrl (toggle buttons, i.e. push buttons with \"sticky\" behavior)\n"
"- GuiSwatchButtonCtrl (color swatch buttons)\n"
"- GuiBorderButtonCtrl (push buttons for surrounding child controls)\n\n"
"@ingroup GuiButtons"
);
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onMouseDown, void, (), (),
"If #useMouseEvents is true, this is called when the left mouse button is pressed on an (active) "
"button." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onMouseUp, void, (), (),
"If #useMouseEvents is true, this is called when the left mouse button is release over an (active) "
"button.\n\n"
"@note To trigger actions, better use onClick() since onMouseUp() will also be called when the mouse was "
"not originally pressed on the button." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onClick, void, (), (),
"Called when the primary action of the button is triggered (e.g. by a left mouse click)." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onDoubleClick, void, (), (),
"Called when the left mouse button is double-clicked on the button." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onRightClick, void, (), (),
"Called when the right mouse button is clicked on the button." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onMouseEnter, void, (), (),
"If #useMouseEvents is true, this is called when the mouse cursor moves over the button (only if the button "
"is the front-most visible control, though)." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onMouseLeave, void, (), (),
"If #useMouseEvents is true, this is called when the mouse cursor moves off the button (only if the button "
"had previously received an onMouseEvent() event)." );
IMPLEMENT_CALLBACK( GuiButtonBaseCtrl, onMouseDragged, void, (), (),
"If #useMouseEvents is true, this is called when a left mouse button drag is detected, i.e. when the user "
"pressed the left mouse button on the control and then moves the mouse over a certain distance threshold with "
"the mouse button still pressed." );
ImplementEnumType( GuiButtonType,
"Type of button control.\n\n"
"@ingroup GuiButtons" )
{ GuiButtonBaseCtrl::ButtonTypePush, "PushButton", "A button that triggers an action when clicked." },
{ GuiButtonBaseCtrl::ButtonTypeCheck, "ToggleButton", "A button that is toggled between on and off state." },
{ GuiButtonBaseCtrl::ButtonTypeRadio, "RadioButton", "A button placed in groups for presenting choices." },
EndImplementEnumType;
//-----------------------------------------------------------------------------
GuiButtonBaseCtrl::GuiButtonBaseCtrl()
{
mDepressed = false;
mMouseOver = false;
mActive = true;
static StringTableEntry sButton = StringTable->insert( "Button" );
mButtonText = sButton;
mButtonTextID = StringTable->EmptyString();
mStateOn = false;
mRadioGroup = -1;
mButtonType = ButtonTypePush;
mUseMouseEvents = false;
mMouseDragged = false;
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::initPersistFields()
{
addGroup( "Button" );
addField( "text", TypeCaseString, Offset(mButtonText, GuiButtonBaseCtrl),
"Text label to display on button (if button class supports text labels)." );
addField( "textID", TypeString, Offset(mButtonTextID, GuiButtonBaseCtrl),
"ID of string in string table to use for text label on button.\n\n"
"@see setTextID\n"
"@see GuiControl::langTableMod\n"
"@see LangTable\n\n" );
addField( "groupNum", TypeS32, Offset(mRadioGroup, GuiButtonBaseCtrl),
"Radio button toggle group number. All radio buttons that are assigned the same #groupNum and that "
"are parented to the same control will synchronize their toggle state, i.e. if one radio button is toggled on "
"all other radio buttons in its group will be toggled off.\n\n"
"The default group is -1." );
addField( "buttonType", TYPEID< ButtonType >(), Offset(mButtonType, GuiButtonBaseCtrl),
"Button behavior type.\n" );
addField( "useMouseEvents", TypeBool, Offset(mUseMouseEvents, GuiButtonBaseCtrl),
"If true, mouse events will be passed on to script. Default is false.\n" );
endGroup( "Button" );
Parent::initPersistFields();
}
//-----------------------------------------------------------------------------
bool GuiButtonBaseCtrl::onWake()
{
if(!Parent::onWake())
return false;
// is we have a script variable, make sure we're in sync
if ( mConsoleVariable[0] )
mStateOn = Con::getBoolVariable( mConsoleVariable );
if(mButtonTextID && *mButtonTextID != 0)
setTextID(mButtonTextID);
return true;
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::setText( const char* text )
{
mButtonText = StringTable->insert(text, true);
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::setTextID(const char *id)
{
S32 n = Con::getIntVariable(id, -1);
if(n != -1)
{
mButtonTextID = StringTable->insert(id);
setTextID(n);
}
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::setTextID(S32 id)
{
const UTF8 *str = getGUIString(id);
if(str)
setText((const char*)str);
//mButtonTextID = id;
}
//-----------------------------------------------------------------------------
const char *GuiButtonBaseCtrl::getText()
{
return mButtonText;
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::setStateOn( bool bStateOn )
{
if(!mActive)
return;
if(mButtonType == ButtonTypeCheck)
{
mStateOn = bStateOn;
}
else if(mButtonType == ButtonTypeRadio)
{
messageSiblings(mRadioGroup);
mStateOn = bStateOn;
}
setUpdate();
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::acceleratorKeyPress(U32)
{
if( !mActive )
return;
//set the bool
mDepressed = true;
if (mProfile->mTabable)
setFirstResponder();
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::acceleratorKeyRelease(U32)
{
if (! mActive)
return;
if (mDepressed)
{
//set the bool
mDepressed = false;
//perform the action
onAction();
}
//update
setUpdate();
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onMouseDown(const GuiEvent &event)
{
if (! mActive)
return;
if (mProfile->mCanKeyFocus)
setFirstResponder();
if (mProfile->mSoundButtonDown)
SFX->playOnce(mProfile->mSoundButtonDown);
mMouseDownPoint = event.mousePoint;
mMouseDragged = false;
if( mUseMouseEvents )
onMouseDown_callback();
//lock the mouse
mouseLock();
mDepressed = true;
// If we have a double click then execute the alt command.
if ( event.mouseClickCount == 2 )
{
onDoubleClick_callback();
execAltConsoleCallback();
}
//update
setUpdate();
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onMouseEnter(const GuiEvent &event)
{
setUpdate();
if( mUseMouseEvents )
onMouseEnter_callback();
if(isMouseLocked())
{
mDepressed = true;
mMouseOver = true;
}
else
{
if ( mActive && mProfile->mSoundButtonOver )
SFX->playOnce(mProfile->mSoundButtonOver);
mMouseOver = true;
}
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onMouseLeave(const GuiEvent &)
{
setUpdate();
if( mUseMouseEvents )
onMouseLeave_callback();
if( isMouseLocked() )
mDepressed = false;
mMouseOver = false;
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onMouseUp(const GuiEvent &event)
{
mouseUnlock();
if( !mActive )
return;
setUpdate();
if( mUseMouseEvents )
onMouseUp_callback();
//if we released the mouse within this control, perform the action
if( mDepressed )
onAction();
mDepressed = false;
mMouseDragged = false;
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onRightMouseUp(const GuiEvent &event)
{
onRightClick_callback();
Parent::onRightMouseUp( event );
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onMouseDragged( const GuiEvent& event )
{
if( mUseMouseEvents )
{
// If we haven't started a drag yet, find whether we have moved past
// the tolerance value.
if( !mMouseDragged )
{
Point2I delta = mMouseDownPoint - event.mousePoint;
if( mAbs( delta.x ) > 2 || mAbs( delta.y ) > 2 )
mMouseDragged = true;
}
if( mMouseDragged )
onMouseDragged_callback();
}
Parent::onMouseDragged( event );
}
//-----------------------------------------------------------------------------
bool GuiButtonBaseCtrl::onKeyDown(const GuiEvent &event)
{
//if the control is a dead end, kill the event
if (!mActive)
return true;
//see if the key down is a return or space or not
if ((event.keyCode == KEY_RETURN || event.keyCode == KEY_SPACE)
&& event.modifier == 0)
{
if ( mProfile->mSoundButtonDown )
SFX->playOnce( mProfile->mSoundButtonDown);
return true;
}
//otherwise, pass the event to it's parent
return Parent::onKeyDown(event);
}
//-----------------------------------------------------------------------------
bool GuiButtonBaseCtrl::onKeyUp(const GuiEvent &event)
{
//if the control is a dead end, kill the event
if (!mActive)
return true;
//see if the key down is a return or space or not
if (mDepressed &&
(event.keyCode == KEY_RETURN || event.keyCode == KEY_SPACE) &&
event.modifier == 0)
{
onAction();
return true;
}
//otherwise, pass the event to it's parent
return Parent::onKeyUp(event);
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::setScriptValue(const char *value)
{
mStateOn = dAtob(value);
// Update the console variable:
if ( mConsoleVariable[0] )
Con::setBoolVariable( mConsoleVariable, mStateOn );
setUpdate();
}
//-----------------------------------------------------------------------------
const char *GuiButtonBaseCtrl::getScriptValue()
{
return mStateOn ? "1" : "0";
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onAction()
{
if(!mActive)
return;
if(mButtonType == ButtonTypeCheck)
{
mStateOn = mStateOn ? false : true;
}
else if(mButtonType == ButtonTypeRadio)
{
mStateOn = true;
messageSiblings(mRadioGroup);
}
setUpdate();
// Update the console variable:
if ( mConsoleVariable[0] )
Con::setBoolVariable( mConsoleVariable, mStateOn );
onClick_callback();
Parent::onAction();
}
//-----------------------------------------------------------------------------
void GuiButtonBaseCtrl::onMessage( GuiControl *sender, S32 msg )
{
Parent::onMessage(sender, msg);
if( mRadioGroup == msg && mButtonType == ButtonTypeRadio )
{
setUpdate();
mStateOn = ( sender == this );
// Update the console variable:
if ( mConsoleVariable[0] )
Con::setBoolVariable( mConsoleVariable, mStateOn );
}
}
//=============================================================================
// Console Methods.
//=============================================================================
// MARK: ---- Console Methods ----
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiButtonBaseCtrl, performClick, void, (),,
"Simulate a click on the button.\n"
"This method will trigger the button's action just as if the button had been pressed by the "
"user.\n\n" )
{
object->onAction();
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiButtonBaseCtrl, setText, void, ( const char* text ),,
"Set the text displayed on the button's label.\n"
"@param text The text to display as the button's text label.\n"
"@note Not all buttons render text labels.\n\n"
"@see getText\n"
"@see setTextID\n" )
{
object->setText( text );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiButtonBaseCtrl, setTextID, void, ( const char* id ),,
"Set the text displayed on the button's label using a string from the string table "
"assigned to the control.\n\n"
"@param id Name of the variable that contains the integer string ID. Used to look up "
"string in table.\n\n"
"@note Not all buttons render text labels.\n\n"
"@see setText\n"
"@see getText\n"
"@see GuiControl::langTableMod\n"
"@see LangTable\n\n"
"@ref Gui_i18n" )
{
object->setTextID( id );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiButtonBaseCtrl, getText, const char*, (),,
"Get the text display on the button's label (if any).\n\n"
"@return The button's label." )
{
return object->getText( );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiButtonBaseCtrl, setStateOn, void, ( bool isOn ), ( true ),
"For toggle or radio buttons, set whether the button is currently activated or not. For radio buttons, "
"toggling a button on will toggle all other radio buttons in its group to off.\n\n"
"@param isOn If true, the button will be toggled on (if not already); if false, it will be toggled off.\n\n"
"@note Toggling the state of a button with this method will <em>not</em> not trigger the action associated with the "
"button. To do that, use performClick()." )
{
object->setStateOn( isOn );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiButtonBaseCtrl, resetState, void, (),,
"Reset the mousing state of the button.\n\n"
"This method should not generally be called." )
{
object->resetState();
}

View file

@ -0,0 +1,127 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUIBUTTONBASECTRL_H_
#define _GUIBUTTONBASECTRL_H_
#ifndef _GUICONTROL_H_
#include "gui/core/guiControl.h"
#endif
/// Base class for all button controls. Subclasses are mostly for specific
/// rendering types.
///
class GuiButtonBaseCtrl : public GuiControl
{
public:
typedef GuiControl Parent;
enum ButtonType
{
ButtonTypePush,
ButtonTypeCheck,
ButtonTypeRadio,
};
protected:
StringTableEntry mButtonText;
StringTableEntry mButtonTextID;
bool mDepressed;
bool mMouseOver;
bool mStateOn;
S32 mButtonType;
S32 mRadioGroup;
bool mUseMouseEvents;
/// Point where left mouse button was pressed down. Used to find when to start
/// a mouse drag.
Point2I mMouseDownPoint;
///
bool mMouseDragged;
/// @name Callbacks
/// @{
DECLARE_CALLBACK( void, onMouseDown, () );
DECLARE_CALLBACK( void, onMouseUp, () );
DECLARE_CALLBACK( void, onClick, () );
DECLARE_CALLBACK( void, onRightClick, () );
DECLARE_CALLBACK( void, onDoubleClick, () );
DECLARE_CALLBACK( void, onMouseEnter, () );
DECLARE_CALLBACK( void, onMouseLeave, () );
DECLARE_CALLBACK( void, onMouseDragged, () );
/// @}
public:
GuiButtonBaseCtrl();
bool onWake();
DECLARE_CONOBJECT( GuiButtonBaseCtrl );
DECLARE_CATEGORY( "Gui Buttons" );
DECLARE_DESCRIPTION( "A basic button control." );
static void initPersistFields();
void setText(const char *text);
void setTextID(S32 id);
void setTextID(const char *id);
const char *getText();
void setStateOn( bool bStateOn );
bool getStateOn() const { return mStateOn; }
void setDepressed( bool depressed ) { mDepressed = depressed; }
void resetState() {mDepressed = false; mMouseOver = false;}
void acceleratorKeyPress(U32 index);
void acceleratorKeyRelease(U32 index);
void onMouseDown(const GuiEvent &);
void onMouseUp(const GuiEvent &);
void onMouseDragged( const GuiEvent& event );
void onRightMouseUp(const GuiEvent &);
void onMouseEnter(const GuiEvent &);
void onMouseLeave(const GuiEvent &);
bool onKeyDown(const GuiEvent &event);
bool onKeyUp(const GuiEvent &event);
void setScriptValue(const char *value);
const char *getScriptValue();
void onMessage(GuiControl *,S32 msg);
void onAction();
bool usesMouseEvents() const { return mUseMouseEvents; }
void setUseMouseEvents( bool val ) { mUseMouseEvents = val; }
};
typedef GuiButtonBaseCtrl::ButtonType GuiButtonType;
DefineEnumType( GuiButtonType );
#endif

View file

@ -0,0 +1,124 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/buttons/guiButtonCtrl.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiDefaultControlRender.h"
IMPLEMENT_CONOBJECT(GuiButtonCtrl);
ConsoleDocClass( GuiButtonCtrl,
"@brief The most widely used button class.\n\n"
"GuiButtonCtrl renders seperately of, but utilizes all of the functionality of GuiBaseButtonCtrl.\n"
"This grants GuiButtonCtrl the versatility to be either of the 3 button types.\n\n"
"@tsexample\n"
"// Create a PushButton GuiButtonCtrl that calls randomFunction when clicked\n"
"%button = new GuiButtonCtrl()\n"
"{\n"
" profile = \"GuiButtonProfile\";\n"
" buttonType = \"PushButton\";\n"
" command = \"randomFunction();\";\n"
"};\n"
"@endtsexample\n\n"
"@ingroup GuiButtons"
);
//-----------------------------------------------------------------------------
GuiButtonCtrl::GuiButtonCtrl()
{
setExtent(140, 30);
mButtonText = StringTable->EmptyString();
}
//-----------------------------------------------------------------------------
bool GuiButtonCtrl::onWake()
{
if( !Parent::onWake() )
return false;
// Button Theme?
if( mProfile->constructBitmapArray() >= 36 )
mHasTheme = true;
else
mHasTheme = false;
return true;
}
//-----------------------------------------------------------------------------
void GuiButtonCtrl::onRender(Point2I offset,
const RectI& updateRect)
{
bool highlight = mMouseOver;
bool depressed = mDepressed;
ColorI fontColor = mActive ? ( highlight ? mProfile->mFontColorHL : mProfile->mFontColor ) : mProfile->mFontColorNA;
ColorI fillColor = mActive ? ( highlight ? mProfile->mFillColorHL : mProfile->mFillColor ) : mProfile->mFillColorNA;
ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA;
RectI boundsRect(offset, getExtent());
if( !mHasTheme )
{
if( mProfile->mBorder != 0 )
renderFilledBorder( boundsRect, borderColor, fillColor, mProfile->mBorderThickness );
else
GFX->getDrawUtil()->drawRectFill( boundsRect, fillColor );
}
else
{
S32 indexMultiplier = 1;
if( !mActive )
indexMultiplier = 4;
else if ( mDepressed || mStateOn )
indexMultiplier = 2;
else if ( mMouseOver )
indexMultiplier = 3;
renderSizableBitmapBordersFilled( boundsRect, indexMultiplier, mProfile );
}
Point2I textPos = offset;
if( depressed )
textPos += Point2I( 1, 1 );
GFX->getDrawUtil()->setBitmapModulation( fontColor );
renderJustifiedText( textPos, getExtent(), mButtonText );
//render the children
renderChildControls( offset, updateRect);
}

View file

@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUIBUTTONCTRL_H_
#define _GUIBUTTONCTRL_H_
#ifndef _GUIBUTTONBASECTRL_H_
#include "gui/buttons/guiButtonBaseCtrl.h"
#endif
class GuiButtonCtrl : public GuiButtonBaseCtrl
{
typedef GuiButtonBaseCtrl Parent;
protected:
bool mHasTheme;
public:
DECLARE_CONOBJECT(GuiButtonCtrl);
GuiButtonCtrl();
bool onWake();
void onRender(Point2I offset, const RectI &updateRect);
};
#endif //_GUI_BUTTON_CTRL_H

View file

@ -0,0 +1,207 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/buttons/guiCheckBoxCtrl.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "console/engineAPI.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "gui/core/guiCanvas.h"
#include "sfx/sfxSystem.h"
#include "sfx/sfxTrack.h"
IMPLEMENT_CONOBJECT( GuiCheckBoxCtrl );
ConsoleDocClass( GuiCheckBoxCtrl,
"@brief A named checkbox that can be toggled on and off.\n\n"
"A GuiCheckBoxCtrl displays a text label next to a checkbox that can be toggled on and off by the user. "
"Checkboxes are usually used to present boolean choices like, for example, a switch to toggle fullscreen "
"video on and off.\n\n"
"@tsexample\n"
"// Create a checkbox that allows to toggle fullscreen on and off.\n"
"new GuiCheckBoxCtrl( FullscreenToggle )\n"
"{\n"
" text = \"Fullscreen\";\n"
"};\n"
"\n"
"// Set the initial state to match the current fullscreen setting.\n"
"FullscreenToggle.setStateOn( Canvas.isFullscreen() );\n"
"\n"
"// Define function to be called when checkbox state is toggled.\n"
"function FullscreenToggle::onClick( %this )\n"
"{\n"
" Canvas.toggleFullscreen();\n"
"}\n"
"@endtsexample\n\n"
"@ingroup GuiButtons"
);
//-----------------------------------------------------------------------------
GuiCheckBoxCtrl::GuiCheckBoxCtrl()
{
setExtent(140, 30);
mStateOn = false;
mIndent = 0;
mButtonType = ButtonTypeCheck;
}
//-----------------------------------------------------------------------------
bool GuiCheckBoxCtrl::onWake()
{
if(!Parent::onWake())
return false;
// make sure there is a bitmap array for this control type
// if it is declared as such in the control
if( !mProfile->mBitmapArrayRects.size() && !mProfile->constructBitmapArray() )
{
Con::errorf( "GuiCheckBoxCtrl::onWake - failed to create bitmap array from profile '%s'", mProfile->getName() );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
void GuiCheckBoxCtrl::onRender(Point2I offset, const RectI &updateRect)
{
// RLP/Sickhead NOTE: New/experimental code
// for notifying the GuiCheckBoxCtrl of changes
// to its mConsoleVariable's state.
if ( mConsoleVariable[0] )
{
bool stateOn = Con::getBoolVariable( mConsoleVariable );
if ( stateOn != mStateOn )
mStateOn = stateOn;
}
ColorI backColor = mActive ? mProfile->mFillColor : mProfile->mFillColorNA;
ColorI fontColor = mActive ? (mMouseOver ? mProfile->mFontColorHL : mProfile->mFontColor) : mProfile->mFontColorNA;
ColorI insideBorderColor = isFirstResponder() ? mProfile->mBorderColorHL : mProfile->mBorderColor;
// just draw the check box and the text:
S32 xOffset = 0;
GFX->getDrawUtil()->clearBitmapModulation();
if(mProfile->mBitmapArrayRects.size() >= 4)
{
S32 index = mStateOn;
if(!mActive)
{
if(mProfile->mBitmapArrayRects.size() >= 6)
{
// New style checkbox bitmap with 6 images
index = 4 + mStateOn;
}
else
{
// Old style checkbox bitmap
index = 2;
}
}
else if(mDepressed)
{
index += 2;
}
xOffset = mProfile->mBitmapArrayRects[0].extent.x + 2 + mIndent;
S32 y = (getHeight() - mProfile->mBitmapArrayRects[0].extent.y) / 2;
GFX->getDrawUtil()->drawBitmapSR(mProfile->mTextureObject, offset + Point2I(mIndent, y), mProfile->mBitmapArrayRects[index]);
}
if(mButtonText[0] != '\0')
{
GFX->getDrawUtil()->setBitmapModulation( fontColor );
renderJustifiedText(Point2I(offset.x + xOffset, offset.y),
Point2I(getWidth() - getHeight(), getHeight()),
mButtonText);
}
//render the children
renderChildControls(offset, updateRect);
}
//-----------------------------------------------------------------------------
void GuiCheckBoxCtrl::autoSize()
{
U32 width, height;
U32 bmpArrayRect0Width = 0;
if( !mAwake )
{
mProfile->incLoadCount();
if( !mProfile->mBitmapArrayRects.size() )
mProfile->constructBitmapArray();
if( mProfile->mBitmapArrayRects.size() )
bmpArrayRect0Width = mProfile->mBitmapArrayRects[ 0 ].extent.x;
}
U32 bmpWidth = bmpArrayRect0Width + 2 + mIndent;
U32 strWidth = mProfile->mFont->getStrWidthPrecise( mButtonText );
width = bmpWidth + strWidth + 2;
U32 bmpHeight = mProfile->mBitmapArrayRects[0].extent.y;
U32 fontHeight = mProfile->mFont->getHeight();
height = getMax( bmpHeight, fontHeight ) + 4;
setExtent( width, height );
if( !mAwake )
mProfile->decLoadCount();
}
//=============================================================================
// API.
//=============================================================================
// MARK: ---- API ----
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiCheckBoxCtrl, setStateOn, void, ( bool newState ),,
"Set whether the checkbox is ticked or not.\n"
"@param newState If true the box will be checked, if false, it will be unchecked.\n\n"
"@note This method will @b not trigger the command associated with the control. To toggle the "
"checkbox state as if the user had clicked the control, use performClick()." )
{
object->setStateOn( newState );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiCheckBoxCtrl, isStateOn, bool, (),,
"Test whether the checkbox is currently checked.\n"
"@return True if the checkbox is currently ticked, false otherwise.\n" )
{
return object->getStateOn();
}

View file

@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUICHECKBOXCTRL_H_
#define _GUICHECKBOXCTRL_H_
#ifndef _GUIBUTTONBASECTRL_H_
#include "gui/buttons/guiButtonBaseCtrl.h"
#endif
/// A checkbox button.
class GuiCheckBoxCtrl : public GuiButtonBaseCtrl
{
public:
typedef GuiButtonBaseCtrl Parent;
protected:
S32 mIndent;
public:
GuiCheckBoxCtrl();
S32 getIndent() const { return mIndent; }
void setIndent( S32 value ) { mIndent = value; }
void onRender( Point2I offset, const RectI &updateRect );
bool onWake();
void autoSize();
DECLARE_CONOBJECT( GuiCheckBoxCtrl );
DECLARE_DESCRIPTION( "A toggle button that displays a text label and an on/off checkbox." );
};
#endif //_GUI_CHECKBOX_CTRL_H

View file

@ -0,0 +1,439 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
//-------------------------------------
//
// Icon Button Control
// Draws the bitmap within a special button control. Only a single bitmap is used and the
// button will be drawn in a highlighted mode when the mouse hovers over it or when it
// has been clicked.
//
// Use mTextLocation to choose where within the button the text will be drawn, if at all.
// Use mTextMargin to set the text away from the button sides or from the bitmap.
// Use mButtonMargin to set everything away from the button sides.
// Use mErrorBitmapName to set the name of a bitmap to draw if the main bitmap cannot be found.
// Use mFitBitmapToButton to force the bitmap to fill the entire button extent. Usually used
// with no button text defined.
//
//
#include "platform/platform.h"
#include "gui/buttons/guiIconButtonCtrl.h"
#include "console/console.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "console/consoleTypes.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiDefaultControlRender.h"
#include "console/engineAPI.h"
static const ColorI colorWhite(255,255,255);
static const ColorI colorBlack(0,0,0);
IMPLEMENT_CONOBJECT(GuiIconButtonCtrl);
ConsoleDocClass( GuiIconButtonCtrl,
"@brief Draws the bitmap within a special button control. Only a single bitmap is used and the\n"
"button will be drawn in a highlighted mode when the mouse hovers over it or when it\n"
"has been clicked.\n\n"
"@tsexample\n"
"new GuiIconButtonCtrl(TestIconButton)\n"
"{\n"
" buttonMargin = \"4 4\";\n"
" iconBitmap = \"art/gui/lagIcon.png\";\n"
" iconLocation = \"Center\";\n"
" sizeIconToButton = \"0\";\n"
" makeIconSquare = \"1\";\n"
" textLocation = \"Bottom\";\n"
" textMargin = \"-2\";\n"
" autoSize = \"0\";\n"
" text = \"Lag Icon\";\n"
" textID = \"\"STR_LAG\"\";\n"
" buttonType = \"PushButton\";\n"
" profile = \"GuiIconButtonProfile\";\n"
"};\n"
"@endtsexample\n\n"
"@see GuiControl\n"
"@see GuiButtonCtrl\n\n"
"@ingroup GuiCore\n"
);
GuiIconButtonCtrl::GuiIconButtonCtrl()
{
mBitmapName = StringTable->insert("");
mTextLocation = TextLocLeft;
mIconLocation = IconLocLeft;
mTextMargin = 4;
mButtonMargin.set(4,4);
mFitBitmapToButton = false;
mMakeIconSquare = false;
mErrorBitmapName = StringTable->insert("");
mErrorTextureHandle = NULL;
mAutoSize = false;
setExtent(140, 30);
}
ImplementEnumType( GuiIconButtonTextLocation,
"\n\n"
"@ingroup GuiImages" )
{ GuiIconButtonCtrl::TextLocNone, "None" },
{ GuiIconButtonCtrl::TextLocBottom, "Bottom" },
{ GuiIconButtonCtrl::TextLocRight, "Right" },
{ GuiIconButtonCtrl::TextLocTop, "Top" },
{ GuiIconButtonCtrl::TextLocLeft, "Left" },
{ GuiIconButtonCtrl::TextLocCenter, "Center" },
EndImplementEnumType;
ImplementEnumType( GuiIconButtonIconLocation,
"\n\n"
"@ingroup GuiImages" )
{ GuiIconButtonCtrl::IconLocNone, "None" },
{ GuiIconButtonCtrl::IconLocLeft, "Left" },
{ GuiIconButtonCtrl::IconLocRight, "Right" },
{ GuiIconButtonCtrl::IconLocCenter, "Center" }
EndImplementEnumType;
void GuiIconButtonCtrl::initPersistFields()
{
addField( "buttonMargin", TypePoint2I, Offset( mButtonMargin, GuiIconButtonCtrl ),"Margin area around the button.\n");
addField( "iconBitmap", TypeFilename, Offset( mBitmapName, GuiIconButtonCtrl ),"Bitmap file for the icon to display on the button.\n");
addField( "iconLocation", TYPEID< IconLocation >(), Offset( mIconLocation, GuiIconButtonCtrl ),"Where to place the icon on the control. Options are 0 (None), 1 (Left), 2 (Right), 3 (Center).\n");
addField( "sizeIconToButton", TypeBool, Offset( mFitBitmapToButton, GuiIconButtonCtrl ),"If true, the icon will be scaled to be the same size as the button.\n");
addField( "makeIconSquare", TypeBool, Offset( mMakeIconSquare, GuiIconButtonCtrl ),"If true, will make sure the icon is square.\n");
addField( "textLocation", TYPEID< TextLocation >(), Offset( mTextLocation, GuiIconButtonCtrl ),"Where to place the text on the control.\n"
"Options are 0 (None), 1 (Bottom), 2 (Right), 3 (Top), 4 (Left), 5 (Center).\n");
addField( "textMargin", TypeS32, Offset( mTextMargin, GuiIconButtonCtrl ),"Margin between the icon and the text.\n");
addField( "autoSize", TypeBool, Offset( mAutoSize, GuiIconButtonCtrl ),"If true, the text and icon will be automatically sized to the size of the control.\n");
Parent::initPersistFields();
}
bool GuiIconButtonCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive(true);
setBitmap(mBitmapName);
if( mProfile )
mProfile->constructBitmapArray();
return true;
}
void GuiIconButtonCtrl::onSleep()
{
mTextureNormal = NULL;
Parent::onSleep();
}
void GuiIconButtonCtrl::inspectPostApply()
{
Parent::inspectPostApply();
}
void GuiIconButtonCtrl::onStaticModified(const char* slotName, const char* newValue)
{
if ( isProperlyAdded() && !dStricmp(slotName, "autoSize") )
resize( getPosition(), getExtent() );
}
bool GuiIconButtonCtrl::resize(const Point2I &newPosition, const Point2I &newExtent)
{
if ( !mAutoSize || !mProfile->mFont )
return Parent::resize( newPosition, newExtent );
Point2I autoExtent( mMinExtent );
if ( mIconLocation != IconLocNone )
{
autoExtent.y = mTextureNormal.getHeight() + mButtonMargin.y * 2;
autoExtent.x = mTextureNormal.getWidth() + mButtonMargin.x * 2;
}
if ( mTextLocation != TextLocNone && mButtonText && mButtonText[0] )
{
U32 strWidth = mProfile->mFont->getStrWidthPrecise( mButtonText );
if ( mTextLocation == TextLocLeft || mTextLocation == TextLocRight )
{
autoExtent.x += strWidth + mTextMargin * 2;
}
else // Top, Bottom, Center
{
strWidth += mTextMargin * 2;
if ( strWidth > autoExtent.x )
autoExtent.x = strWidth;
}
}
return Parent::resize( newPosition, autoExtent );
}
void GuiIconButtonCtrl::setBitmap(const char *name)
{
mBitmapName = StringTable->insert(name);
if(!isAwake())
return;
if (*mBitmapName)
{
mTextureNormal = GFXTexHandle( name, &GFXDefaultPersistentProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__) );
}
else
{
mTextureNormal = NULL;
}
// So that extent is recalculated if autoSize is set.
resize( getPosition(), getExtent() );
setUpdate();
}
void GuiIconButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
{
renderButton( offset, updateRect);
}
void GuiIconButtonCtrl::renderButton( Point2I &offset, const RectI& updateRect )
{
bool highlight = mMouseOver;
bool depressed = mDepressed;
ColorI fontColor = mActive ? (highlight ? mProfile->mFontColor : mProfile->mFontColor) : mProfile->mFontColorNA;
RectI boundsRect(offset, getExtent());
GFXDrawUtil *drawer = GFX->getDrawUtil();
if (mDepressed || mStateOn)
{
// If there is a bitmap array then render using it.
// Otherwise use a standard fill.
if(mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size())
renderBitmapArray(boundsRect, statePressed);
else
renderSlightlyLoweredBox(boundsRect, mProfile);
}
else if(mMouseOver && mActive)
{
// If there is a bitmap array then render using it.
// Otherwise use a standard fill.
if(mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size())
renderBitmapArray(boundsRect, stateMouseOver);
else
renderSlightlyRaisedBox(boundsRect, mProfile);
}
else
{
// If there is a bitmap array then render using it.
// Otherwise use a standard fill.
if(mProfile->mUseBitmapArray && mProfile->mBitmapArrayRects.size())
{
if(mActive)
renderBitmapArray(boundsRect, stateNormal);
else
renderBitmapArray(boundsRect, stateDisabled);
}
else
{
drawer->drawRectFill(boundsRect, mProfile->mFillColorNA);
drawer->drawRect(boundsRect, mProfile->mBorderColorNA);
}
}
Point2I textPos = offset;
if(depressed)
textPos += Point2I(1,1);
RectI iconRect( 0, 0, 0, 0 );
// Render the icon
if ( mTextureNormal && mIconLocation != GuiIconButtonCtrl::IconLocNone )
{
// Render the normal bitmap
drawer->clearBitmapModulation();
// Maintain the bitmap size or fill the button?
if ( !mFitBitmapToButton )
{
Point2I textureSize( mTextureNormal->getWidth(), mTextureNormal->getHeight() );
iconRect.set( offset + mButtonMargin, textureSize );
if ( mIconLocation == IconLocRight )
{
iconRect.point.x = ( offset.x + getWidth() ) - ( mButtonMargin.x + textureSize.x );
iconRect.point.y = offset.y + ( getHeight() - textureSize.y ) / 2;
}
else if ( mIconLocation == IconLocLeft )
{
iconRect.point.x = offset.x + mButtonMargin.x;
iconRect.point.y = offset.y + ( getHeight() - textureSize.y ) / 2;
}
else if ( mIconLocation == IconLocCenter )
{
iconRect.point.x = offset.x + ( getWidth() - textureSize.x ) / 2;
iconRect.point.y = offset.y + ( getHeight() - textureSize.y ) / 2;
}
drawer->drawBitmapStretch( mTextureNormal, iconRect );
}
else
{
iconRect.set( offset + mButtonMargin, getExtent() - (mButtonMargin * 2) );
if ( mMakeIconSquare )
{
// Square the icon to the smaller axis extent.
if ( iconRect.extent.x < iconRect.extent.y )
iconRect.extent.y = iconRect.extent.x;
else
iconRect.extent.x = iconRect.extent.y;
}
drawer->drawBitmapStretch( mTextureNormal, iconRect );
}
}
// Render text
if ( mTextLocation != TextLocNone )
{
// Clip text to fit (appends ...),
// pad some space to keep it off our border
String text( mButtonText );
S32 textWidth = clipText( text, getWidth() - 4 - mTextMargin );
drawer->setBitmapModulation( fontColor );
if ( mTextLocation == TextLocRight )
{
Point2I start( mTextMargin, ( getHeight() - mProfile->mFont->getHeight() ) / 2 );
if ( mTextureNormal && mIconLocation != IconLocNone )
{
start.x = iconRect.extent.x + mButtonMargin.x + mTextMargin;
}
drawer->drawText( mProfile->mFont, start + offset, text, mProfile->mFontColors );
}
if ( mTextLocation == TextLocLeft )
{
Point2I start( mTextMargin, ( getHeight() - mProfile->mFont->getHeight() ) / 2 );
drawer->drawText( mProfile->mFont, start + offset, text, mProfile->mFontColors );
}
if ( mTextLocation == TextLocCenter )
{
Point2I start;
if ( mTextureNormal && mIconLocation == IconLocLeft )
{
start.set( ( getWidth() - textWidth - iconRect.extent.x ) / 2 + iconRect.extent.x,
( getHeight() - mProfile->mFont->getHeight() ) / 2 );
}
else
start.set( ( getWidth() - textWidth ) / 2, ( getHeight() - mProfile->mFont->getHeight() ) / 2 );
drawer->setBitmapModulation( fontColor );
drawer->drawText( mProfile->mFont, start + offset, text, mProfile->mFontColors );
}
if ( mTextLocation == TextLocBottom )
{
Point2I start;
start.set( ( getWidth() - textWidth ) / 2, getHeight() - mProfile->mFont->getHeight() - mTextMargin );
// If the text is longer then the box size
// it will get clipped, force Left Justify
if( textWidth > getWidth() )
start.x = 0;
drawer->setBitmapModulation( fontColor );
drawer->drawText( mProfile->mFont, start + offset, text, mProfile->mFontColors );
}
}
renderChildControls( offset, updateRect);
}
// Draw the bitmap array's borders according to the button's state.
void GuiIconButtonCtrl::renderBitmapArray(RectI &bounds, S32 state)
{
switch(state)
{
case stateNormal:
if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 1, mProfile);
else
renderFixedBitmapBordersFilled(bounds, 1, mProfile);
break;
case stateMouseOver:
if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 2, mProfile);
else
renderFixedBitmapBordersFilled(bounds, 2, mProfile);
break;
case statePressed:
if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 3, mProfile);
else
renderFixedBitmapBordersFilled(bounds, 3, mProfile);
break;
case stateDisabled:
if(mProfile->mBorder == -2)
renderSizableBitmapBordersFilled(bounds, 4, mProfile);
else
renderFixedBitmapBordersFilled(bounds, 4, mProfile);
break;
}
}
DefineEngineMethod( GuiIconButtonCtrl, setBitmap, void, (const char* buttonFilename),,
"@brief Set the bitmap to use for the button portion of this control.\n\n"
"@param buttonFilename Filename for the image\n"
"@tsexample\n"
"// Define the button filename\n"
"%buttonFilename = \"pearlButton\";\n\n"
"// Inform the GuiIconButtonCtrl control to update its main button graphic to the defined bitmap\n"
"%thisGuiIconButtonCtrl.setBitmap(%buttonFilename);\n"
"@endtsexample\n\n"
"@see GuiControl\n"
"@see GuiButtonCtrl\n\n")
{
char* argBuffer = Con::getArgBuffer( 512 );
Platform::makeFullPathName( buttonFilename, argBuffer, 512 );
object->setBitmap( argBuffer );
}

View file

@ -0,0 +1,125 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUIICONBUTTON_H_
#define _GUIICONBUTTON_H_
#ifndef _GUIBUTTONCTRL_H_
#include "gui/buttons/guiButtonCtrl.h"
#endif
#ifndef GFX_Texture_Manager_H_
#include "gfx/gfxTextureManager.h"
#endif
/// The GuiIconButtonCtrl draws an icon and text caption within a normal
/// button control with several layout options.
///
class GuiIconButtonCtrl : public GuiButtonCtrl
{
private:
typedef GuiButtonCtrl Parent;
protected:
StringTableEntry mBitmapName;
GFXTexHandle mTextureNormal;
S32 mIconLocation;
S32 mTextLocation;
S32 mTextMargin;
Point2I mButtonMargin;
/// Make the bitmap fill the button extent.
bool mFitBitmapToButton;
/// Keep a square aspect ration on the icon.
bool mMakeIconSquare;
/// Calculate extent based on icon size, text width, and layout options.
bool mAutoSize;
// Optional bitmap to be displayed when the proper bitmap cannot be found
StringTableEntry mErrorBitmapName;
GFXTexHandle mErrorTextureHandle;
void renderButton( Point2I &offset, const RectI& updateRect);
enum
{
stateNormal,
stateMouseOver,
statePressed,
stateDisabled,
};
void renderBitmapArray(RectI &bounds, S32 state);
public:
enum TextLocation
{
TextLocNone,
TextLocBottom,
TextLocRight,
TextLocTop,
TextLocLeft,
TextLocCenter,
};
enum IconLocation
{
IconLocNone,
IconLocLeft,
IconLocRight,
IconLocCenter
};
DECLARE_CONOBJECT(GuiIconButtonCtrl);
DECLARE_DESCRIPTION( "A button control that displays an icon on the button in addition\n"
"to the optional text label." );
GuiIconButtonCtrl();
static void initPersistFields();
//Parent methods
bool onWake();
void onSleep();
void inspectPostApply();
void onStaticModified(const char* slotName, const char* newValue = NULL);
bool resize(const Point2I &newPosition, const Point2I &newExtent);
void setBitmap(const char *name);
// Used to set the optional error bitmap
void setErrorBitmap(const char *name);
void onRender(Point2I offset, const RectI &updateRect);
};
typedef GuiIconButtonCtrl::TextLocation GuiIconButtonTextLocation;
typedef GuiIconButtonCtrl::IconLocation GuiIconButtonIconLocation;
DefineEnumType( GuiIconButtonTextLocation );
DefineEnumType( GuiIconButtonIconLocation );
#endif //_GUIICONBUTTON_H_

View file

@ -0,0 +1,61 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "gui/buttons/guiRadioCtrl.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "console/engineAPI.h"
#include "gfx/gfxDevice.h"
#include "gui/core/guiCanvas.h"
IMPLEMENT_CONOBJECT(GuiRadioCtrl);
ConsoleDocClass( GuiRadioCtrl,
"@brief A button based around the radio concept.\n\n"
"GuiRadioCtrl's functionality is based around GuiButtonBaseCtrl's ButtonTypeRadio type.\n\n"
"A button control with a radio box and a text label.\n"
"This control is used in groups where multiple radio buttons\n"
"present a range of options out of which one can be chosen.\n"
"A radio button automatically signals its siblings when it is\n"
"toggled on.\n\n"
"@tsexample\n"
"// Create a GuiCheckBoxCtrl that calls randomFunction with its current value when clicked.\n"
"%radio = new GuiRadioCtrl()\n"
"{\n"
" profile = \"GuiRadioProfile\";\n"
"};\n"
"@endtsexample\n\n"
"@ingroup GuiButtons"
);
//-----------------------------------------------------------------------------
GuiRadioCtrl::GuiRadioCtrl()
{
mButtonType = ButtonTypeRadio;
}

View file

@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUIRADIOCTRL_H_
#define _GUIRADIOCTRL_H_
#ifndef _GUICHECKBOXCTRLL_H_
#include "gui/buttons/guiCheckBoxCtrl.h"
#endif
// the radio button renders exactly the same as the check box
// the only difference is it sends messages to its siblings to
// turn themselves off.
class GuiRadioCtrl : public GuiCheckBoxCtrl
{
typedef GuiCheckBoxCtrl Parent;
public:
DECLARE_CONOBJECT(GuiRadioCtrl);
DECLARE_DESCRIPTION( "A button control with a radio box and a text label.\n"
"This control is used in groups where multiple radio buttons\n"
"present a range of options out of which one can be chosen.\n"
"A radio button automatically signals its siblings when it is\n"
"toggled on." );
GuiRadioCtrl();
};
#endif //_GUI_RADIO_CTRL_H

View file

@ -0,0 +1,123 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/buttons/guiSwatchButtonCtrl.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "console/engineAPI.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiDefaultControlRender.h"
IMPLEMENT_CONOBJECT( GuiSwatchButtonCtrl );
ConsoleDocClass( GuiSwatchButtonCtrl,
"@brief A button that is used to represent color; often used in correlation with a color picker.\n\n"
"A swatch button is a push button that uses its color field to designate the color drawn over an image, on top of a button.\n\n"
"The color itself is a float value stored inside the GuiSwatchButtonCtrl::color field. The texture path that represents\n"
"the image underlying the color is stored inside the GuiSwatchButtonCtrl::bitmap field.\n"
"The default value assigned toGuiSwatchButtonCtrl::color is \"1 1 1 1\"( White ). The default/fallback image assigned to \n"
"GuiSwatchButtonCtrl::bitmap is \"core/art/gui/images/transp_grid\".\n\n"
"@tsexample\n"
"// Create a GuiSwatchButtonCtrl that calls randomFunction with its current color when clicked\n"
"%swatchButton = new GuiSwatchButtonCtrl()\n"
"{\n"
" profile = \"GuiInspectorSwatchButtonProfile\";\n"
" command = \"randomFunction( $ThisControl.color );\";\n"
"};\n"
"@endtsexample\n\n"
"@ingroup GuiButtons"
);
//-----------------------------------------------------------------------------
GuiSwatchButtonCtrl::GuiSwatchButtonCtrl()
: mSwatchColor( 1, 1, 1, 1 )
{
mButtonText = StringTable->insert( "" );
setExtent(140, 30);
static StringTableEntry sProfile = StringTable->insert( "profile" );
setDataField( sProfile, NULL, "GuiInspectorSwatchButtonProfile" );
}
void GuiSwatchButtonCtrl::initPersistFields()
{
addField( "color", TypeColorF, Offset( mSwatchColor, GuiSwatchButtonCtrl ), "The foreground color of GuiSwatchButtonCtrl" );
Parent::initPersistFields();
}
bool GuiSwatchButtonCtrl::onWake()
{
if ( !Parent::onWake() )
return false;
if ( mGrid.isNull() )
mGrid.set( "core/art/gui/images/transp_grid", &GFXDefaultGUIProfile, avar("%s() - mGrid (line %d)", __FUNCTION__, __LINE__) );
return true;
}
void GuiSwatchButtonCtrl::onRender( Point2I offset, const RectI &updateRect )
{
bool highlight = mMouseOver;
ColorI backColor = mSwatchColor;
ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA;
RectI renderRect( offset, getExtent() );
if ( !highlight )
renderRect.inset( 1, 1 );
GFXDrawUtil *drawer = GFX->getDrawUtil();
drawer->clearBitmapModulation();
// Draw background transparency grid texture...
if ( mGrid.isValid() )
drawer->drawBitmapStretch( mGrid, renderRect );
// Draw swatch color as fill...
drawer->drawRectFill( renderRect, mSwatchColor );
// Draw any borders...
drawer->drawRect( renderRect, borderColor );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( GuiSwatchButtonCtrl, setColor, void, ( const char* newColor ),,
"Set the color of the swatch control.\n"
"@param newColor The new color string given to the swatch control in float format \"r g b a\".\n"
"@note It's also important to note that when setColor is called causes\n"
"the control's altCommand field to be executed." )
{
object->setField( "color", newColor );
object->execAltConsoleCallback();
}

View file

@ -0,0 +1,67 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUISWATCHBUTTONCTRL_H_
#define _GUISWATCHBUTTONCTRL_H_
#ifndef _GUIBUTTONBASECTRL_H_
#include "gui/buttons/guiButtonBaseCtrl.h"
#endif
/// A color swatch button.
///
class GuiSwatchButtonCtrl : public GuiButtonBaseCtrl
{
public:
typedef GuiButtonBaseCtrl Parent;
protected:
/// The color to display on the button.
ColorF mSwatchColor;
/// Background texture that will show through with transparent colors.
GFXTexHandle mGrid;
public:
GuiSwatchButtonCtrl();
/// Return the color displayed in the swatch.
ColorF getColor() { return mSwatchColor; }
/// Set the color to display in the swatch.
void setColor( const ColorF &color ) { mSwatchColor = color; }
// GuiButtonBaseCtrl
virtual bool onWake();
virtual void onRender(Point2I offset, const RectI &updateRect);
static void initPersistFields();
DECLARE_CONOBJECT( GuiSwatchButtonCtrl );
DECLARE_DESCRIPTION( "A color swatch button." );
};
#endif // _GUISWATCHBUTTONCTRL_H_

View file

@ -0,0 +1,108 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/buttons/guiToggleButtonCtrl.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "console/engineAPI.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiDefaultControlRender.h"
IMPLEMENT_CONOBJECT(GuiToggleButtonCtrl);
ConsoleDocClass( GuiToggleButtonCtrl,
"@brief Deprecated gui control.\n\n"
"@deprecated GuiToggleButtonCtrl's functionality is solely based on GuiButtonBaseCtrl's ButtonTypeCheck type.\n\n"
"@see GuiButtonCtrl\n"
"@see GuiCheckBoxCtrl\n"
"@ingroup GuiButtons"
);
//-----------------------------------------------------------------------------
GuiToggleButtonCtrl::GuiToggleButtonCtrl()
{
setExtent(140, 30);
mButtonText = StringTable->insert("");
mStateOn = false;
mButtonType = ButtonTypeCheck;
}
void GuiToggleButtonCtrl::onPreRender()
{
Parent::onPreRender();
// If we have a script variable, make sure we're in sync
if ( mConsoleVariable[0] )
mStateOn = Con::getBoolVariable( mConsoleVariable );
}
void GuiToggleButtonCtrl::onRender(Point2I offset,
const RectI& updateRect)
{
bool highlight = mMouseOver;
bool depressed = mDepressed;
ColorI fontColor = mActive ? ( highlight ? mProfile->mFontColorHL : mProfile->mFontColor ) : mProfile->mFontColorNA;
ColorI fillColor = mActive ? ( highlight ? mProfile->mFillColorHL : mProfile->mFillColor ) : mProfile->mFillColorNA;
ColorI borderColor = mActive ? ( highlight ? mProfile->mBorderColorHL : mProfile->mBorderColor ) : mProfile->mBorderColorNA;
RectI boundsRect(offset, getExtent());
if( !mHasTheme )
{
if( mProfile->mBorder != 0 )
renderFilledBorder( boundsRect, borderColor, fillColor, mProfile->mBorderThickness );
else
GFX->getDrawUtil()->drawRectFill( boundsRect, fillColor );
}
else if( mHasTheme )
{
S32 indexMultiplier = 1;
if ( !mActive )
indexMultiplier = 4;
else if ( mDepressed || mStateOn )
indexMultiplier = 2;
else if ( mMouseOver )
indexMultiplier = 3;
renderSizableBitmapBordersFilled( boundsRect, indexMultiplier, mProfile );
}
Point2I textPos = offset;
if(depressed)
textPos += Point2I(1,1);
GFX->getDrawUtil()->setBitmapModulation( fontColor );
renderJustifiedText(textPos, getExtent(), mButtonText);
//render the children
renderChildControls( offset, updateRect);
}

View file

@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUITOGGLEBUTTONCTRL_H_
#define _GUITOGGLEBUTTONCTRL_H_
#ifndef _GUIBUTTONCTRL_H_
#include "gui/buttons/guiButtonCtrl.h"
#endif
class GuiToggleButtonCtrl : public GuiButtonCtrl
{
typedef GuiButtonCtrl Parent;
public:
DECLARE_CONOBJECT(GuiToggleButtonCtrl);
GuiToggleButtonCtrl();
virtual void onPreRender();
void onRender(Point2I offset, const RectI &updateRect);
};
#endif //_GUITOGGLEBUTTONCTRL_H_

View file

@ -0,0 +1,227 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "gui/buttons/guiToolboxButtonCtrl.h"
#include "console/console.h"
#include "gfx/gfxDevice.h"
#include "gfx/gfxDrawUtil.h"
#include "console/consoleTypes.h"
#include "gui/core/guiCanvas.h"
#include "gui/core/guiDefaultControlRender.h"
IMPLEMENT_CONOBJECT(GuiToolboxButtonCtrl);
ConsoleDocClass( GuiToolboxButtonCtrl,
"@brief Unimplemented GUI control meant to interact with Toolbox.\n\n"
"For Torque 3D editors only, soon to be deprecated\n\n"
"@internal"
);
//-------------------------------------
GuiToolboxButtonCtrl::GuiToolboxButtonCtrl()
{
mNormalBitmapName = StringTable->insert("");
mLoweredBitmapName = StringTable->insert("sceneeditor/client/images/buttondown");
mHoverBitmapName = StringTable->insert("sceneeditor/client/images/buttonup");
setMinExtent(Point2I(16,16));
setExtent(48, 48);
mButtonType = ButtonTypeRadio;
mTipHoverTime = 100;
}
//-------------------------------------
void GuiToolboxButtonCtrl::initPersistFields()
{
addField("normalBitmap", TypeFilename, Offset(mNormalBitmapName, GuiToolboxButtonCtrl));
addField("loweredBitmap", TypeFilename, Offset(mLoweredBitmapName, GuiToolboxButtonCtrl));
addField("hoverBitmap", TypeFilename, Offset(mHoverBitmapName, GuiToolboxButtonCtrl));
Parent::initPersistFields();
}
//-------------------------------------
bool GuiToolboxButtonCtrl::onWake()
{
if (! Parent::onWake())
return false;
setActive( true );
setNormalBitmap( mNormalBitmapName );
setLoweredBitmap( mLoweredBitmapName );
setHoverBitmap( mHoverBitmapName );
return true;
}
//-------------------------------------
void GuiToolboxButtonCtrl::onSleep()
{
mTextureNormal = NULL;
mTextureLowered = NULL;
mTextureHover = NULL;
Parent::onSleep();
}
//-------------------------------------
ConsoleMethod( GuiToolboxButtonCtrl, setNormalBitmap, void, 3, 3, "( filepath name ) sets the bitmap that shows when the button is active")
{
object->setNormalBitmap(argv[2]);
}
ConsoleMethod( GuiToolboxButtonCtrl, setLoweredBitmap, void, 3, 3, "( filepath name ) sets the bitmap that shows when the button is disabled")
{
object->setLoweredBitmap(argv[2]);
}
ConsoleMethod( GuiToolboxButtonCtrl, setHoverBitmap, void, 3, 3, "( filepath name ) sets the bitmap that shows when the button is disabled")
{
object->setHoverBitmap(argv[2]);
}
//-------------------------------------
void GuiToolboxButtonCtrl::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 ((getWidth() == 0) && (getHeight() == 0) && mTextureNormal)
{
setExtent( mTextureNormal->getWidth(), mTextureNormal->getHeight());
}
}
//-------------------------------------
void GuiToolboxButtonCtrl::setNormalBitmap( StringTableEntry bitmapName )
{
mNormalBitmapName = StringTable->insert( bitmapName );
if(!isAwake())
return;
if ( *mNormalBitmapName )
mTextureNormal = GFXTexHandle( mNormalBitmapName, &GFXDefaultPersistentProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__) );
else
mTextureNormal = NULL;
setUpdate();
}
void GuiToolboxButtonCtrl::setLoweredBitmap( StringTableEntry bitmapName )
{
mLoweredBitmapName = StringTable->insert( bitmapName );
if(!isAwake())
return;
if ( *mLoweredBitmapName )
mTextureLowered = GFXTexHandle( mLoweredBitmapName, &GFXDefaultPersistentProfile, avar("%s() - mTextureLowered (line %d)", __FUNCTION__, __LINE__) );
else
mTextureLowered = NULL;
setUpdate();
}
void GuiToolboxButtonCtrl::setHoverBitmap( StringTableEntry bitmapName )
{
mHoverBitmapName = StringTable->insert( bitmapName );
if(!isAwake())
return;
if ( *mHoverBitmapName )
mTextureHover = GFXTexHandle( mHoverBitmapName, &GFXDefaultPersistentProfile, avar("%s() - mTextureHover (line %d)", __FUNCTION__, __LINE__) );
else
mTextureHover = NULL;
setUpdate();
}
//-------------------------------------
void GuiToolboxButtonCtrl::onRender(Point2I offset, const RectI& updateRect)
{
// Only render the state rect (hover/down) if we're active
if (mActive)
{
RectI r(offset, getExtent());
if ( mDepressed || mStateOn )
renderStateRect( mTextureLowered , r );
else if ( mMouseOver )
renderStateRect( mTextureHover , r );
}
// Now render the image
if( mTextureNormal )
{
renderButton( mTextureNormal, offset, updateRect );
return;
}
Point2I textPos = offset;
if( mDepressed )
textPos += Point2I(1,1);
// Make sure we take the profile's textOffset into account.
textPos += mProfile->mTextOffset;
GFX->getDrawUtil()->setBitmapModulation( mProfile->mFontColor );
renderJustifiedText(textPos, getExtent(), mButtonText);
}
void GuiToolboxButtonCtrl::renderStateRect( GFXTexHandle &texture, const RectI& rect )
{
if (texture)
{
GFX->getDrawUtil()->clearBitmapModulation();
GFX->getDrawUtil()->drawBitmapStretch( texture, rect );
}
}
//------------------------------------------------------------------------------
void GuiToolboxButtonCtrl::renderButton(GFXTexHandle &texture, Point2I &offset, const RectI& updateRect)
{
if (texture)
{
Point2I finalOffset = offset;
finalOffset.x += ( ( getWidth() / 2 ) - ( texture.getWidth() / 2 ) );
finalOffset.y += ( ( getHeight() / 2 ) - ( texture.getHeight() / 2 ) );
GFX->getDrawUtil()->clearBitmapModulation();
GFX->getDrawUtil()->drawBitmap(texture, finalOffset);
renderChildControls( offset, updateRect);
}
}

View file

@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _GUITOOLBOXBUTTON_H_
#define _GUITOOLBOXBUTTON_H_
#ifndef _GUIBUTTONCTRL_H_
#include "gui/buttons/guiButtonCtrl.h"
#endif
#ifndef GFX_Texture_Manager_H_
#include "gfx/gfxTextureManager.h"
#endif
class GuiToolboxButtonCtrl : public GuiButtonCtrl
{
private:
typedef GuiButtonCtrl Parent;
protected:
StringTableEntry mNormalBitmapName;
StringTableEntry mLoweredBitmapName;
StringTableEntry mHoverBitmapName;
GFXTexHandle mTextureNormal;
GFXTexHandle mTextureLowered;
GFXTexHandle mTextureHover;
void renderButton(GFXTexHandle &texture, Point2I &offset, const RectI& updateRect);
void renderStateRect( GFXTexHandle &texture, const RectI& rect );
public:
DECLARE_CONOBJECT(GuiToolboxButtonCtrl);
GuiToolboxButtonCtrl();
static void initPersistFields();
//Parent methods
bool onWake();
void onSleep();
void inspectPostApply();
void setNormalBitmap( StringTableEntry bitmapName );
void setLoweredBitmap( StringTableEntry bitmapName );
void setHoverBitmap( StringTableEntry bitmapName );
void onRender(Point2I offset, const RectI &updateRect);
};
#endif //_GUITOOLBOXBUTTON_H_