Files
source/Laptop/BaseTable.h
T
Flugente 952408b961 Improvements for BaseTable:
- Separator colour can be set
- Fixed column length calculation
- checkboxes are now possible

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8802 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2020-05-17 14:13:57 +00:00

530 lines
16 KiB
C++

#ifndef __BASETABLE_H
#define __BASETABLE_H
/**
* @file
* @author Flugente (bears-pit.com)
*/
#include "DropDown.h"
/*
* A base class for tables
*/
class BaseTable : public WidgetBase
{
public:
BaseTable( );
void SetInit( BOOLEAN fVal ) { fInit = fVal ; }
BOOLEAN IsInit() { return fInit ; }
/*
* set maximum width and height
*/
void SetWidth( UINT16 aVal ) { musWidth = aVal; }
virtual UINT16 GetWidth( ) { return musWidth; }
void SetHeight( UINT16 aVal ) { musHeight = aVal; }
virtual UINT16 GetHeight( ) { return musHeight; }
void SetFrameWorkSpace( UINT16 aVal ) { musFrameWorkSpace = aVal; }
virtual UINT16 GetFrameWorkSpace( ) { return musFrameWorkSpace; }
/*
* Initialise variables. Called after each creation which allows moving a dropdown
*/
virtual void Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
/*
* Create a Dropdown with upper left coordinates
*/
virtual void Create( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
/*
* Destroy Dropdown, for example once a website isn't displayed anymore
*/
virtual void Destroy( );
/*
* Display DropDownBase. Use this when refreshing
*/
virtual void Display( );
/*
* Sometimes a refresh inside the class isn't enough - best example is closing the dropdown area, after which the previous background cannot be restored by this class.
* In that case, the background and this class has to be redrawn.
* This function is called internally whenever such a refresh is necessary.
* It has to be defined in derived classes and should notify your dialogues to redraw at appropriate times
*
* This function has to be implemented!
*/
virtual void SetRefresh( ) = 0;
virtual void DestroyMouseRegions();
void SetActive( BOOLEAN aVal ) { mActive = aVal; }
BOOLEAN IsActive( ) { return mActive; }
virtual void SetMouseRegionActive( BOOLEAN aVal ) { mMouseRegionActive = aVal; }
BOOLEAN IsMouseRegionActive( ) { return mMouseRegionActive; }
virtual void RegisterMemberThingy( BaseTable * arP )
{
if ( mRegisteredMembers.empty() )
{
mRegisteredMembers.push_back( arP );
arP->SetActive( TRUE );
}
else
{
mRegisteredMembers.push_back( arP );
}
}
void SetName( STR16 aName ) { mName = aName; }
STR16 GetName() { return mName; }
private:
// declare but don't define
BaseTable( BaseTable const& );
void operator=(BaseTable const&);
private:
STR16 mName;
BOOLEAN fInit;
UINT16 musHeight;
UINT16 musWidth;
// as blank square dialogues are ugly, we can a framework on the edges - in this case we need to reserve some space for this
UINT16 musFrameWorkSpace;
// determines whether or not this widget will currently be shown
BOOLEAN mActive;
// if FALSE, do not display mouse regions
BOOLEAN mMouseRegionActive;
std::vector<BaseTable*> mRegisteredMembers;
};
// a simple panel into which we can embed other widgets
class TestPanel : public BaseTable
{
public:
TestPanel( );
/*
* Display DropDownBase. Use this when refreshing
*/
virtual void Display( );
virtual void SetRefresh( );
};
extern TestPanel gTestPanel3;
// callback types
enum {
CALLBACK_BUTTON_MOVE = 0,
CALLBACK_BUTTON_CLICK,
CALLBACK_REGION_MOVE,
CALLBACK_REGION_CLICK,
};
class WidgetCallBackInstance
{
public:
WidgetCallBackInstance( ) {}
virtual ~WidgetCallBackInstance( ) {}
virtual void RegionMoveCallBack( MOUSE_REGION * pRegion, INT32 iReason ) {}
virtual void RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason ) {}
virtual void ButtonMoveCallBack( GUI_BUTTON *btn, INT32 reason ) {}
virtual void ButtonClickCallBack( GUI_BUTTON *btn, INT32 reason ) {}
/*
* This function is implemented again in DropDownTemplate
*/
virtual MOUSE_CALLBACK RegionCallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(MOUSE_REGION * pRegion, INT32 iReason) ) { return RegionDummyfunc; }
virtual GUI_CALLBACK ButtonCallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(GUI_BUTTON * btn, INT32 iReason) ) { return ButtonDummyfunc; }
/*
* This dummy is needed internally and does nothing when called
*/
static void RegionDummyfunc( MOUSE_REGION * pRegion, INT32 iReason ) {}
static void ButtonDummyfunc( GUI_BUTTON * btn, INT32 iReason ) {}
};
typedef STR16( *cdp_string_func )(UINT32 aNum);
STR16 cdp_string_func_dummy( UINT32 aNum );
typedef UINT8( *cdp_textcolour_func )( UINT32 aNum );
UINT8 cdp_textcolour_func_dummy( UINT32 aNum );
typedef void( *cdp_image_func )(UINT32 aNum, UINT32& arImageLib, UINT16& arImage );
void cdp_image_func_dummy( UINT32 aNum, UINT32& arImageLib, UINT16& arImage );
typedef void( *cdp_statusbar_func )(UINT32 aId, UINT16& arCol1, UINT16& arVal1, UINT16& arCol2, UINT16& arVal2, UINT16& arCol3, UINT16& arVal3, UINT16& arCol4, UINT16& arVal4);
void cdp_statusbar_func_dummy( UINT32 aId, UINT16& arCol1, UINT16& arVal1, UINT16& arCol2, UINT16& arVal2, UINT16& arCol3, UINT16& arVal3, UINT16& arCol4, UINT16& arVal4 );
#define COLUMNDATAPROVIDER_MOUSEREGIONS 50
class ColumnDataProvider
{
public:
ColumnDataProvider( STR16 aName ) : mName( aName ), mNumberOfEntries( 0 ), mRequiredLength(20), mRequiredHeigth( 20 ),
mType( CDP_STRING ), mCallbackType( CDP_DEFAULT ),
mFuncString( cdp_string_func_dummy ), mFuncTextColour( cdp_textcolour_func_dummy ), mFuncImage( cdp_image_func_dummy ), mFuncStatusBar( cdp_statusbar_func_dummy )
{
for ( int i = 0; i < COLUMNDATAPROVIDER_MOUSEREGIONS; ++i )
{
mMouseRegion_Defined[i] = FALSE;
}
}
// general provider functions
void SetNumberOfEntries( UINT32 aVal ) { mNumberOfEntries = aVal; CalcRequiredLength( ); }
UINT32 GetNumberOfEntries( ) { return mNumberOfEntries; }
void CalcRequiredLength( );
UINT32 GetRequiredLength( ) { return mRequiredLength; }
void SetRequiredLength( UINT32 aVal ) { mRequiredLength = aVal; } // this overrides the calculated value
UINT32 GetRequiredHeigth( ) { return mRequiredHeigth; }
void SetRequiredHeigth( UINT32 aVal ) { mRequiredHeigth = aVal; }
STR16 GetName( ) { return mName; }
typedef enum
{
CDP_DEFAULT = 0,
CDP_MILITIA_LIST,
CDP_MILITIADETAIL,
CDP_TOGGLE,
} CDP_CALLBACKTYPE;
typedef enum
{
CDP_STRING,
CDP_IMAGE,
CDP_STATUSBAR,
} CDP_TYPE;
CDP_TYPE GetProviderType( ) { return mType ; }
void SetProviderType( CDP_TYPE aType ) { mType = aType; }
// functions for handling string contents
void SetMethodString( cdp_string_func afunc ) { mFuncString = afunc; SetProviderType( CDP_STRING ); CalcRequiredLength( ); }
STR16 GetString( UINT32 aNum ) { return mFuncString( aNum ); }
void SetMethodTextColour( cdp_textcolour_func afunc ) { mFuncTextColour = afunc; }
UINT8 GetColour( UINT32 aNum ) { return mFuncTextColour( aNum ); }
// functions for handling images
void SetMethodImage( cdp_image_func afunc ) { mFuncImage = afunc; SetProviderType( CDP_IMAGE ); CalcRequiredLength( ); }
void GetImageData( UINT32 aNum, UINT32& arImageLib, UINT16& arImage ) { return mFuncImage( aNum, arImageLib, arImage ); }
// functions for handling healthbars
void SetMethodStatusBar( cdp_statusbar_func afunc ) { mFuncStatusBar = afunc; SetProviderType( CDP_STATUSBAR ); CalcRequiredLength( ); }
void GetStatusBarData( UINT32 aId, UINT16& arCol1, UINT16& arVal1, UINT16& arCol2, UINT16& arVal2, UINT16& arCol3, UINT16& arVal3, UINT16& arCol4, UINT16& arVal4 )
{
return mFuncStatusBar( aId, arCol1, arVal1, arCol2, arVal2, arCol3, arVal3, arCol4, arVal4 );
}
// callbacks for clicking on a column
void SetCallBackType( CDP_CALLBACKTYPE aVal ) { mCallbackType = aVal; }
CDP_CALLBACKTYPE GetCallBackType( ) { return mCallbackType; }
static void RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason );
void DestroyMouseRegions();
public:
MOUSE_REGION mMouseRegion[COLUMNDATAPROVIDER_MOUSEREGIONS];
BOOLEAN mMouseRegion_Defined[COLUMNDATAPROVIDER_MOUSEREGIONS];
private:
STR16 mName;
UINT32 mNumberOfEntries;
// the maximum length required for a column according to its contents
UINT32 mRequiredLength;
UINT32 mRequiredHeigth;
CDP_TYPE mType;
CDP_CALLBACKTYPE mCallbackType;
cdp_string_func mFuncString;
cdp_textcolour_func mFuncTextColour;
cdp_image_func mFuncImage;
cdp_statusbar_func mFuncStatusBar;
};
// a simple panel into which we can embed other widgets
class TabBox : public BaseTable, public WidgetCallBackInstance
{
public:
TabBox( );
/*
* Initialise variables. Called after each creation which allows moving a dropdown
*/
virtual void Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
/*
* Create a Dropdown with upper left coordinates
*/
virtual void Create( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
/*
* Destroy Dropdown, for example once a website isn't displayed anymore
*/
virtual void Destroy( );
/*
* Display DropDownBase. Use this when refreshing
*/
virtual void Display( );
virtual void DestroyMouseRegions( );
struct TestPanelButtonStruct
{
BaseTable* mTestPanel;
MOUSE_REGION mMouseRegion;
BOOLEAN mMouseRegion_Defined;
};
virtual void RegisterMemberThingy( BaseTable * arP )
{
if ( !mRegisteredTables.empty( ) )
arP->SetActive( FALSE );
TestPanelButtonStruct tmp;
tmp.mTestPanel = arP;
tmp.mMouseRegion_Defined = FALSE;
mRegisteredTables.push_back( tmp );
BaseTable::RegisterMemberThingy( arP );
}
virtual void RegionMoveCallBack( MOUSE_REGION * pRegion, INT32 iReason ) {}
virtual void RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason );
private:
std::vector<TestPanelButtonStruct> mRegisteredTables;
};
class TestTable : public BaseTable, public WidgetCallBackInstance
{
public:
TestTable( );
/*
* Initialise variables. Called after each creation which allows moving a dropdown
*/
virtual void Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
/*
* Create a Dropdown with upper left coordinates
*/
virtual void Create( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
/*
* Destroy Dropdown, for example once a website isn't displayed anymore
*/
virtual void Destroy( );
/*
* Display DropDownBase. Use this when refreshing
*/
virtual void Display( );
virtual void DestroyMouseRegions( ) ;
virtual void RegionMoveCallBack( MOUSE_REGION * pRegion, INT32 iReason );
virtual void RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason );
virtual void ButtonClickCallBack( GUI_BUTTON *btn, INT32 reason );
void AddColumnDataProvider( ColumnDataProvider aCP ) { mColumnDataProviderVector.push_back( aCP ); }
void ClearColumnDataProvider( ) { mColumnDataProviderVector.clear(); }
void CalcRows();
/*
* Color of separating line element
*/
void SetColorSeparator( UINT16 aCol ) { mColorSeparator = aCol; }
UINT16 GetColorSeparator() { return mColorSeparator; }
private:
void CreateScrollAreaButtons( );
UINT32 GetNumberOfDataRows( );
UINT32 GetNumberOfDataRowsShown( );
UINT32 GetRequiredHeigthPerRow();
private:
// parts of the scrollbar
BOOLEAN mScrollBarDefined;
INT32 mScrollArrow[2];
UINT32 mScrollArrowImage[2];
MOUSE_REGION mScrollRegion;
UINT32 mFirstEntryShown;
UINT32 mLastEntryShown;
UINT16 mColorSeparator;
std::vector<ColumnDataProvider> mColumnDataProviderVector;
};
template<int N>
class TestTableTemplate : public TestTable
{
public:
static TestTableTemplate<N>& getInstance( )
{
static TestTableTemplate<N> instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
// this function has to be implemented!
virtual void SetRefresh( );
virtual void Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
static void RegionMove( MOUSE_REGION * pRegion, INT32 iReason ) { return static_cast<TestTable*>(mpSelf)->RegionMoveCallBack( pRegion, iReason ); }
static void RegionClick( MOUSE_REGION * pRegion, INT32 iReason ) { return static_cast<TestTable*>(mpSelf)->RegionClickCallBack( pRegion, iReason ); }
static void ButtonMove( GUI_BUTTON *btn, INT32 iReason ) { return static_cast<TestTable*>(mpSelf)->ButtonMoveCallBack( btn, iReason ); }
static void ButtonClick( GUI_BUTTON *btn, INT32 iReason ) { return static_cast<TestTable*>(mpSelf)->ButtonClickCallBack( btn, iReason ); }
MOUSE_CALLBACK
RegionCallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(MOUSE_REGION * pRegion, INT32 iReason) )
{
mpSelf = pt2Object;
switch ( arg )
{
case CALLBACK_REGION_MOVE: return &RegionMove; break;
case CALLBACK_REGION_CLICK: return &RegionClick; break;
}
return *pt2Function;
}
GUI_CALLBACK
ButtonCallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(GUI_BUTTON *btn, INT32 iReason) )
{
mpSelf = pt2Object;
switch ( arg )
{
case CALLBACK_BUTTON_MOVE: return &ButtonMove; break;
case CALLBACK_BUTTON_CLICK: return &ButtonClick; break;
}
return *pt2Function;
}
private:
static void* mpSelf;
private:
TestTableTemplate<N>( ) {}; // private constructor, so we cannot create more instances
// declare but don't define
TestTableTemplate( TestTableTemplate const& );
void operator=(TestTableTemplate const&);
};
template <int N>
void TestTableTemplate<N>::SetRefresh();
template <int N>
void TestTableTemplate<N>::Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End );
template <int N>
void* TestTableTemplate<N>::mpSelf = NULL;
template<int N>
class TabBoxTemplate : public TabBox
{
public:
static TabBoxTemplate<N>& getInstance( )
{
static TabBoxTemplate<N> instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
static TabBox* GetPSelf( ) { return static_cast<TabBox*>(mpSelf); }
// this function has to be implemented!
virtual void SetRefresh( );
static void RegionMove( MOUSE_REGION * pRegion, INT32 iReason ) { return GetPSelf()->RegionMoveCallBack( pRegion, iReason ); }
static void RegionClick( MOUSE_REGION * pRegion, INT32 iReason ) { return GetPSelf()->RegionClickCallBack( pRegion, iReason ); }
static void ButtonMove( GUI_BUTTON *btn, INT32 iReason ) { return GetPSelf()->ButtonMoveCallBack( btn, iReason ); }
static void ButtonClick( GUI_BUTTON *btn, INT32 iReason ) { return GetPSelf()->ButtonClickCallBack( btn, iReason ); }
void SetPSelf( void* pt2Object ) { mpSelf = pt2Object; }
MOUSE_CALLBACK
RegionCallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(MOUSE_REGION * pRegion, INT32 iReason) )
{
SetPSelf ( pt2Object );
switch ( arg )
{
case CALLBACK_REGION_MOVE: return &RegionMove; break;
case CALLBACK_REGION_CLICK: return &RegionClick; break;
}
return *pt2Function;
}
GUI_CALLBACK
ButtonCallBackWrapper( void* pt2Object, UINT8 arg, void( *pt2Function )(GUI_BUTTON *btn, INT32 iReason) )
{
SetPSelf( pt2Object );
switch ( arg )
{
case CALLBACK_BUTTON_MOVE: return &ButtonMove; break;
case CALLBACK_BUTTON_CLICK: return &ButtonClick; break;
}
return *pt2Function;
}
private:
static void* mpSelf;
private:
TabBoxTemplate<N>( ) {}; // private constructor, so we cannot create more instances
// declare but don't define
TabBoxTemplate( TabBoxTemplate const& );
void operator=(TabBoxTemplate const&);
};
template <int N>
void TabBoxTemplate<N>::SetRefresh( );
template <int N>
void* TabBoxTemplate<N>::mpSelf = NULL;
#endif