Files
source/Laptop/BaseTable.cpp
T

938 lines
26 KiB
C++

/**
* @file
* @author Flugente (bears-pit.com)
*/
#include "BaseTable.h"
#include "Font.h"
#include "laptop.h"
#include "Cursors.h"
#include "Utilities.h"
#include "vobject.h"
#include "WCheck.h"
#include "line.h"
#include "WordWrap.h"
#include "input.h" // for gfLeftButtonState
#include "insurance.h" // for DisplaySmallColouredLineWithShadow
BaseTable::BaseTable( )
: WidgetBase( ),
mName(L""),
fInit(FALSE),
musHeight(0),
musWidth(0),
musFrameWorkSpace(0),
mActive(TRUE),
mMouseRegionActive(TRUE)
{
}
void
BaseTable::Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End )
{
SetX( sX );
SetY( sY );
SetWidth( sX_End - sX );
SetHeight( sY_End - sY );
for ( std::vector<BaseTable*>::iterator it = mRegisteredMembers.begin( ); it != mRegisteredMembers.end( ); ++it )
{
if ( (*it) )
(*it)->Init( sX, sY, sX_End, sY_End );
}
SetInit( TRUE );
}
void
BaseTable::Create( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End )
{
Destroy( );
Init( sX, sY, sX_End, sY_End );
}
void
BaseTable::Destroy( )
{
if ( !IsInit() )
return;
DestroyMouseRegions();
for ( std::vector<BaseTable*>::iterator it = mRegisteredMembers.begin( ); it != mRegisteredMembers.end( ); ++it )
{
if ( (*it) )
(*it)->Destroy( );
}
mRegisteredMembers.clear( );
SetInit(FALSE);
SetRefresh( );
}
void
BaseTable::Display( )
{
if ( !IsInit() )
return;
for ( std::vector<BaseTable*>::iterator it = mRegisteredMembers.begin( ); it != mRegisteredMembers.end( ); ++it )
{
if ( (*it) && (*it)->IsActive() )
(*it)->Display( );
}
}
void
BaseTable::DestroyMouseRegions( )
{
if ( !IsInit( ) )
return;
for ( std::vector<BaseTable*>::iterator it = mRegisteredMembers.begin( ); it != mRegisteredMembers.end( ); ++it )
{
if ( (*it) )
(*it)->DestroyMouseRegions( );
}
}
STR16 cdp_string_func_dummy( UINT32 aNum )
{
return L"nothing found";
}
void cdp_image_func_dummy( UINT32 aNum, UINT32& arImageLib, UINT16& arImage )
{
}
void cdp_statusbar_func_dummy( UINT32 aId, UINT16& arCol1, UINT16& arVal1, UINT16& arCol2, UINT16& arVal2, UINT16& arCol3, UINT16& arVal3, UINT16& arCol4, UINT16& arVal4 )
{
}
void
ColumnDataProvider::CalcRequiredLength( )
{
mRequiredLength = 0;
if ( CDP_STRING == GetProviderType() )
{
for ( UINT32 i = 0; i < mNumberOfEntries; ++i )
{
mRequiredLength = max( mRequiredLength, 7 * wcslen( GetString( i ) ) );
}
}
else if ( CDP_IMAGE == GetProviderType() )
{
for ( UINT32 i = 0; i < mNumberOfEntries; ++i )
{
// TODO...
mRequiredLength = max( mRequiredLength, 40 );
}
}
else if ( CDP_STATUSBAR == GetProviderType( ) )
{
mRequiredLength = 4;
}
}
extern void callbackmilitialist( INT32 usId );
extern void callbackmilitiadetail( INT32 usId );
void
ColumnDataProvider::RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason )
{
if ( iReason & MSYS_CALLBACK_REASON_INIT )
{
}
else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
//gfScrollBoxIsScrolling = FALSE;
//gHelpScreen.iLastMouseClickY = -1;
}
else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
CDP_CALLBACKTYPE chosenentry = (CDP_CALLBACKTYPE)(pRegion->UserData[0]);
// do stuff
switch ( chosenentry )
{
case CDP_MILITIA_LIST:
callbackmilitialist( pRegion->UserData[1] );
break;
case CDP_MILITIADETAIL:
callbackmilitiadetail( pRegion->UserData[1] );
break;
case CDP_DEFAULT:
default:
break;
}
}
else if ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP )
{
}
}
void
ColumnDataProvider::DestroyMouseRegions( )
{
for ( int i = 0; i < COLUMNDATAPROVIDER_MOUSEREGIONS; ++i )
{
if ( mMouseRegion_Defined[i] )
{
MSYS_RemoveRegion( &mMouseRegion[i] );
mMouseRegion_Defined[i] = FALSE;
}
}
}
// Flugente: this unused page will now be a testbed for the BaseTable development
#define TESTTABLE_FONT_MED FONT12ARIAL
#define TESTTABLE_OFFSET_ROW 20
#define TESTTABLE_FONT_COLOR_REGULAR 2
////////////// TestPanel///////////////////////////////////////
TestPanel::TestPanel( )
: BaseTable( )
{
SetFrameWorkSpace( 4 );
}
void
TestPanel::Display( )
{
if ( !IsInit( ) )
return;
SetColorLine( Get16BPPColor( FROMRGB( 128, 128, 128 ) ) );
SetColorLineShadow( Get16BPPColor( FROMRGB( 255, 255, 255 ) ) );
SetColorMarked(Get16BPPColor( FROMRGB( 200, 169, 87 ) ));
SetColorHighLight(Get16BPPColor( FROMRGB( 235, 222, 171 )) );
//Display the background
ColorFillVideoSurfaceArea( FRAME_BUFFER, GetX( ), GetY( ), GetX( ) + GetWidth( ), GetY( ) + GetHeight( ), GetColorMarked( ) );
// framework
// top
Display2Line2ShadowHorizontal( GetX( ), GetY( ), GetX( ) + GetWidth( ), GetColorLine( ), GetColorLineShadow( ) );
// bottom
Display2Line2ShadowHorizontal( GetX( ), GetY( ) + GetHeight( ) - GetFrameWorkSpace( ) * 3 / 2, GetX( ) + GetWidth( ), GetColorLineShadow( ), GetColorLine( ) );
// left
Display2Line2ShadowVertical( GetX( ), GetY( ) + GetFrameWorkSpace( )/2, GetY( ) + GetHeight( ) - 5, GetColorLine( ), GetColorLineShadow( ) );
// right
Display2Line2ShadowVertical( GetX( ) + GetWidth( ) - GetFrameWorkSpace( ) * 3 / 2, GetY( ) + GetFrameWorkSpace( ) / 2, GetY( ) + GetHeight( ) - 5, GetColorLineShadow( ), GetColorLine( ) );
BaseTable::Display( );
}
void
TestPanel::SetRefresh( )
{
}
TestPanel gTestPanel3;
////////////////////////// TestPanel /////////////////////////////////////
////////////////////////// TabBox /////////////////////////////////////
TabBox::TabBox( )
: BaseTable( )
{
SetFrameWorkSpace(4);
}
void
TabBox::Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End )
{
SetColorLine( Get16BPPColor( FROMRGB( 128, 128, 128 ) ) );
SetColorLineShadow( Get16BPPColor( FROMRGB( 255, 255, 255 ) ) );
SetColorMarked( Get16BPPColor( FROMRGB( 200, 169, 87 ) ) );
SetColorHighLight( Get16BPPColor( FROMRGB( 235, 222, 171 ) ) );
BaseTable::Init( sX, sY, sX_End, sY_End );
}
void
TabBox::Create( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End )
{
Destroy( );
Init( sX, sY, sX_End, sY_End );
UINT16 usPosX = GetX( );
UINT16 panelcnt = 0;
for ( std::vector<TestPanelButtonStruct>::iterator it = mRegisteredTables.begin( ); it != mRegisteredTables.end( ); ++it )
{
if ( !(*it).mMouseRegion_Defined && IsMouseRegionActive() )
{
// determine required width of mouse region
UINT32 textwidth = 7 * wcslen( (*it).mTestPanel->GetName( ) );
MSYS_DefineRegion( &(*it).mMouseRegion, usPosX, GetY( ), usPosX + textwidth, GetY( ) + TESTTABLE_OFFSET_ROW, MSYS_PRIORITY_HIGH,
CURSOR_WWW,
RegionCallBackWrapper( (void*) this, CALLBACK_REGION_MOVE, &RegionDummyfunc ),
RegionCallBackWrapper( (void*) this, CALLBACK_REGION_CLICK, &RegionDummyfunc ) );
MSYS_AddRegion( &(*it).mMouseRegion );
MSYS_SetRegionUserData( &(*it).mMouseRegion, 0, panelcnt );
(*it).mMouseRegion_Defined = TRUE;
++panelcnt;
usPosX += textwidth;
}
}
}
void
TabBox::Destroy( )
{
if ( !IsInit( ) )
return;
for ( std::vector<TestPanelButtonStruct>::iterator it = mRegisteredTables.begin( ); it != mRegisteredTables.end( ); ++it )
{
if ( (*it).mMouseRegion_Defined )
{
MSYS_RemoveRegion( &(*it).mMouseRegion );
(*it).mMouseRegion_Defined = FALSE;
}
}
mRegisteredTables.clear( );
BaseTable::Destroy( );
}
void
TabBox::Display( )
{
if ( !IsInit( ) )
return;
DestroyMouseRegions();
CHAR16 sText[800];
swprintf( sText, L"" );
UINT16 usPosX = GetX( );
UINT16 panelcnt = 0;
UINT16 selectedx = 0;
UINT16 selectedwidth = 0;
SetFontShadow( NO_SHADOW );
for ( std::vector<TestPanelButtonStruct>::iterator it = mRegisteredTables.begin( ); it != mRegisteredTables.end( ); ++it )
{
if ( IsActive() )
{
// determine required width
UINT32 textwidth = 7 * wcslen( (*it).mTestPanel->GetName( ) );
if ( (*it).mTestPanel->IsActive( ) )
{
ColorFillVideoSurfaceArea( FRAME_BUFFER,
usPosX, GetY( ),
usPosX + textwidth, GetY( ) + TESTTABLE_OFFSET_ROW,
GetColorMarked() );
selectedx = usPosX;
selectedwidth = textwidth;
}
else
{
ColorFillVideoSurfaceArea( FRAME_BUFFER,
usPosX, GetY( ),
usPosX + textwidth, GetY( ) + TESTTABLE_OFFSET_ROW,
GetColorHighLight() );
}
// framework
// top
Display2Line2ShadowHorizontal( usPosX, GetY( ), usPosX + textwidth, GetColorLine( ), GetColorLineShadow( ) );
// left
Display2Line2ShadowVertical( usPosX, GetY( ) + GetFrameWorkSpace( ) / 2, GetY( ) + TESTTABLE_OFFSET_ROW - 1, GetColorLine( ), GetColorLineShadow( ) );
// right
Display2Line2ShadowVertical( usPosX + textwidth - 3, GetY( ) + GetFrameWorkSpace( ) / 2, GetY( ) + TESTTABLE_OFFSET_ROW, GetColorLineShadow( ), GetColorLine( ) );
swprintf( sText, (*it).mTestPanel->GetName( ) );
DrawTextToScreen( sText, usPosX + 7, GetY( ) + 7, GetWidth( ), TESTTABLE_FONT_MED, TESTTABLE_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 );
// mouse region
if ( !(*it).mMouseRegion_Defined && IsMouseRegionActive( ) )
{
MSYS_DefineRegion( &(*it).mMouseRegion, usPosX, GetY( ), usPosX + textwidth, GetY( ) + TESTTABLE_OFFSET_ROW, MSYS_PRIORITY_HIGH,
CURSOR_WWW,
RegionCallBackWrapper( (void*) this, CALLBACK_REGION_MOVE, &RegionDummyfunc ),
RegionCallBackWrapper( (void*) this, CALLBACK_REGION_CLICK, &RegionDummyfunc ) );
MSYS_AddRegion( &(*it).mMouseRegion );
MSYS_SetRegionUserData( &(*it).mMouseRegion, 0, panelcnt );
(*it).mMouseRegion_Defined = TRUE;
++panelcnt;
}
usPosX += textwidth;
}
}
BaseTable::Display( );
// to indicate which frame is the active one we 'delete' the border to the content below
ColorFillVideoSurfaceArea( FRAME_BUFFER,
selectedx + GetFrameWorkSpace( ), GetY( ) + TESTTABLE_OFFSET_ROW,
selectedx + selectedwidth - 3, GetY( ) + TESTTABLE_OFFSET_ROW + GetFrameWorkSpace( ),
GetColorMarked( ) );
// left
Display2Line2ShadowVertical( selectedx, GetY( ) + TESTTABLE_OFFSET_ROW - 3, GetY( ) + TESTTABLE_OFFSET_ROW + 1, GetColorLine( ), GetColorLineShadow( ) );
// right
Display2Line2ShadowVertical( selectedx + selectedwidth - 3, GetY( ) + TESTTABLE_OFFSET_ROW - 3, GetY( ) + TESTTABLE_OFFSET_ROW + 1, GetColorLineShadow( ), GetColorLine( ) );
}
void
TabBox::DestroyMouseRegions( )
{
for ( std::vector<TestPanelButtonStruct>::iterator it = mRegisteredTables.begin( ); it != mRegisteredTables.end( ); ++it )
{
if ( (*it).mMouseRegion_Defined )
{
MSYS_RemoveRegion( &(*it).mMouseRegion );
(*it).mMouseRegion_Defined = FALSE;
}
}
BaseTable::DestroyMouseRegions( );
}
void
TabBox::RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason )
{
if ( iReason & MSYS_CALLBACK_REASON_INIT )
{
}
else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
//gfScrollBoxIsScrolling = FALSE;
//gHelpScreen.iLastMouseClickY = -1;
}
else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
for ( std::vector<TestPanelButtonStruct>::iterator it = mRegisteredTables.begin(); it != mRegisteredTables.end(); ++it )
{
if ( pRegion->IDNumber == (*it).mMouseRegion.IDNumber )
(*it).mTestPanel->SetActive( TRUE );
else
(*it).mTestPanel->SetActive( FALSE );
}
SetRefresh( );
//gfScrollBoxIsScrolling = TRUE;
//HelpScreenMouseMoveScrollBox( pRegion->MouseYPos );
}
else if ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP )
{
}
}
////////////////////////// TabBox /////////////////////////////////////
////////////////////////// TestTable /////////////////////////////////////
#define SCROLLARROW_WIDTH 20
#define SCROLLARROW_HEIGTH 20
TestTable::TestTable( )
: BaseTable( ),
mScrollBarDefined( FALSE ),
mFirstEntryShown(0),
mLastEntryShown( 0 )
{
}
void
TestTable::Init( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End )
{
SetX( sX );
SetY( sY );
SetHeight( sY_End - sY );
SetWidth( sX_End - sX );
CalcRows( );
SetInit( TRUE );
}
extern UINT32 guiHelpScreenBackGround;
void
TestTable::Create( UINT16 sX, UINT16 sY, UINT16 sX_End, UINT16 sY_End )
{
VOBJECT_DESC VObjectDesc;
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP( "INTERFACE\\HelpScreen.sti", VObjectDesc.ImageFile );
if ( !AddVideoObject( &VObjectDesc, &guiHelpScreenBackGround ) )
return;
Destroy( );
Init( sX, sY, sX_End, sY_End );
}
void
TestTable::Destroy( )
{
if ( !IsInit( ) )
return;
if ( mScrollBarDefined )
{
for ( UINT16 i = 0; i < 2; ++i )
{
RemoveButton( mScrollArrow[i] );
UnloadButtonImage( mScrollArrowImage[i] );
}
MSYS_RemoveRegion( &mScrollRegion );
mScrollBarDefined = FALSE;
}
std::vector<ColumnDataProvider>::iterator itend = mColumnDataProviderVector.end( );
for ( std::vector<ColumnDataProvider>::iterator it = mColumnDataProviderVector.begin( ); it != itend; ++it )
{
(*it).DestroyMouseRegions();
}
ClearColumnDataProvider();
DeleteVideoObjectFromIndex( guiHelpScreenBackGround );
SetInit( FALSE );
SetRefresh( );
}
void
TestTable::Display( )
{
if ( !IsInit( ) )
return;
CHAR16 sText[800];
swprintf( sText, L"" );
UINT16 usPosX, usPosY;
usPosX = GetX( );
usPosY = GetY( );
DestroyMouseRegions();
if ( IsActive() )
{
for ( std::vector<ColumnDataProvider>::iterator it = mColumnDataProviderVector.begin( ); it != mColumnDataProviderVector.end( ); ++it )
{
swprintf( sText, (*it).GetName( ) );
DrawTextToScreen( sText, usPosX, usPosY, GetWidth( ), TESTTABLE_FONT_MED, TESTTABLE_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 );
usPosX += (*it).GetRequiredLength( );
}
usPosY += TESTTABLE_OFFSET_ROW - 4;
UINT32 heightperrow = GetRequiredHeigthPerRow( );
for ( UINT32 i = mFirstEntryShown; i < mLastEntryShown; ++i )
{
usPosX = GetX( );
DisplaySmallColouredLineWithShadow( usPosX, usPosY - 2, usPosX + GetWidth( ) - SCROLLARROW_WIDTH, usPosY - 2, FROMRGB( 0, 255, 0 ) );
std::vector<ColumnDataProvider>::iterator itend = mColumnDataProviderVector.end( );
for ( std::vector<ColumnDataProvider>::iterator it = mColumnDataProviderVector.begin( ); it != itend; ++it )
{
if ( it->GetProviderType( ) == ColumnDataProvider::CDP_STRING )
{
swprintf( sText, (*it).GetString( i ) );
DrawTextToScreen( sText, usPosX, usPosY + 7, GetWidth( ), TESTTABLE_FONT_MED, TESTTABLE_FONT_COLOR_REGULAR, FONT_MCOLOR_BLACK, FALSE, 0 );
}
else if ( it->GetProviderType( ) == ColumnDataProvider::CDP_IMAGE )
{
UINT32 imagelib = 0;
UINT16 imageid = 0;
it->GetImageData( i, imagelib, imageid );
BltVideoObjectFromIndex( FRAME_BUFFER, imagelib, imageid, usPosX, usPosY, VO_BLT_SRCTRANSPARENCY, NULL );
}
else if ( it->GetProviderType( ) == ColumnDataProvider::CDP_STATUSBAR )
{
UINT16 col1 = 0;
UINT16 col2 = 0;
UINT16 col3 = 0;
UINT16 col4 = 0;
UINT16 val1 = 0;
UINT16 val2 = 0;
UINT16 val3 = 0;
UINT16 val4 = 0;
it->GetStatusBarData( i, col1, val1, col2, val2, col3, val3, col4, val4 );
UINT16 height1 = (heightperrow * val1) / 100;
UINT16 height2 = (heightperrow * val2) / 100;
UINT16 height3 = (heightperrow * val3) / 100;
UINT16 height4 = (heightperrow * val4) / 100;
UINT16 endY = usPosY + heightperrow - 1;
// first a grey background (that way we get a grey 'border' for our bar, then the content
UINT16 bg = Get16BPPColor( FROMRGB( 158, 158, 158 ) );
DisplaySmallLine( usPosX + 0, usPosY, usPosX + 0, endY, bg );
DisplaySmallLine( usPosX + 1, usPosY, usPosX + 1, endY, bg );
DisplaySmallLine( usPosX + 2, usPosY, usPosX + 2, endY, bg );
DisplaySmallLine( usPosX + 3, usPosY, usPosX + 3, endY, bg );
DisplaySmallLine( usPosX + 1, endY - height1, usPosX + 1, endY, col1 );
DisplaySmallLine( usPosX + 2, endY - height1, usPosX + 2, endY, col1 );
DisplaySmallLine( usPosX + 1, endY - height2, usPosX + 1, endY, col2 );
DisplaySmallLine( usPosX + 2, endY - height2, usPosX + 2, endY, col2 );
DisplaySmallLine( usPosX + 1, endY - height3, usPosX + 1, endY, col3 );
DisplaySmallLine( usPosX + 2, endY - height3, usPosX + 2, endY, col3 );
DisplaySmallLine( usPosX + 1, endY - height4, usPosX + 1, endY, col4 );
DisplaySmallLine( usPosX + 2, endY - height4, usPosX + 2, endY, col4 );
}
if ( i - mFirstEntryShown < COLUMNDATAPROVIDER_MOUSEREGIONS && IsMouseRegionActive( ) )
{
MSYS_DefineRegion( &it->mMouseRegion[i - mFirstEntryShown],
usPosX, usPosY, usPosX + it->GetRequiredLength( ), usPosY + heightperrow,
MSYS_PRIORITY_HIGHEST, CURSOR_WWW,
MSYS_NO_CALLBACK, (*it).RegionClickCallBack );
MSYS_AddRegion( &it->mMouseRegion[i - mFirstEntryShown] );
// first entry of userdata is the callback type - we need to know what kind of callback function should be called
MSYS_SetRegionUserData( &it->mMouseRegion[i - mFirstEntryShown], 0, it->GetCallBackType() );
// second entry: the id to use as input in the callback
MSYS_SetRegionUserData( &it->mMouseRegion[i - mFirstEntryShown], 1, i );
it->mMouseRegion_Defined[i - mFirstEntryShown] = TRUE;
}
usPosX += (*it).GetRequiredLength( );
}
usPosY += heightperrow;
}
UINT32 shownentries = GetNumberOfDataRowsShown( );
UINT32 totalentries = GetNumberOfDataRows( );
// do we need scrollbars in the first place?
if ( shownentries < totalentries )
{
// length of scrollbar and length of scrollbar element
UINT32 scrollbarheigth = GetHeight( ) - 2 * SCROLLARROW_HEIGTH;
UINT32 scrollareaheigth = (scrollbarheigth * shownentries) / totalentries;
UINT32 areabegin = (scrollbarheigth * mFirstEntryShown) / totalentries;
ColorFillVideoSurfaceArea( FRAME_BUFFER,
GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2,
GetY( ) + SCROLLARROW_HEIGTH + areabegin,
GetX( ) + GetWidth( ) - 2,
GetY( ) + SCROLLARROW_HEIGTH + areabegin + scrollareaheigth,
Get16BPPColor( FROMRGB( 20, 250, 50 ) ) );
CreateScrollAreaButtons( );
}
}
BaseTable::Display( );
}
void
TestTable::DestroyMouseRegions()
{
std::vector<ColumnDataProvider>::iterator itend = mColumnDataProviderVector.end( );
for ( std::vector<ColumnDataProvider>::iterator it = mColumnDataProviderVector.begin( ); it != itend; ++it )
{
(*it).DestroyMouseRegions( );
}
if ( mScrollBarDefined )
{
for ( UINT16 i = 0; i < 2; ++i )
{
RemoveButton( mScrollArrow[i] );
UnloadButtonImage( mScrollArrowImage[i] );
}
MSYS_RemoveRegion( &mScrollRegion );
mScrollBarDefined = FALSE;
}
BaseTable::DestroyMouseRegions( );
}
void
TestTable::RegionMoveCallBack( MOUSE_REGION * pRegion, INT32 iReason )
{
if ( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE )
{
// InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, pRegion->RegionBottomRightX, pRegion->RegionBottomRightY);
}
else if ( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE )
{
}
else if ( iReason & MSYS_CALLBACK_REASON_MOVE )
{
if ( gfLeftButtonState )
{
// if mouse is outside of the bar, simply move bar up or down
if ( pRegion->MouseYPos < mScrollRegion.RegionTopLeftY )
{
mLastEntryShown = max( 0, mLastEntryShown - 1 );
}
else if ( pRegion->MouseYPos > mScrollRegion.RegionBottomRightY )
{
++mLastEntryShown;
}
// inside the scroll bar, determine where the middle of the slider is to determine where to go
else
{
// length of scrollbar
UINT32 scrollbarheigth = GetHeight( ) - 2 * SCROLLARROW_HEIGTH;
if ( scrollbarheigth > 0 )
{
FLOAT rate = (FLOAT)(pRegion->MouseYPos - GetY( ) + SCROLLARROW_HEIGTH) / (FLOAT)(scrollbarheigth);
mLastEntryShown = rate * GetNumberOfDataRows();
}
}
// simply altering the position of mLastEntryShown and the recalculating the rows does the trick
CalcRows();
SetRefresh( );
}
}
}
void
TestTable::RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason )
{
iReason = iReason;
if ( iReason & MSYS_CALLBACK_REASON_INIT )
{
}
else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
//gfScrollBoxIsScrolling = FALSE;
//gHelpScreen.iLastMouseClickY = -1;
}
else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
//gfScrollBoxIsScrolling = TRUE;
//HelpScreenMouseMoveScrollBox( pRegion->MouseYPos );
}
else if ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP )
{
}
}
void
TestTable::ButtonClickCallBack( GUI_BUTTON *btn, INT32 reason )
{
if ( reason & MSYS_CALLBACK_REASON_INIT )
{
return;
}
if ( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
// up-arrow
if ( btn->IDNum == this->mScrollArrow[0] )
{
// do things!
if ( mFirstEntryShown )
--mFirstEntryShown;
mLastEntryShown = mFirstEntryShown + GetNumberOfDataRowsShown( );
}
// down-arrow
else if ( btn->IDNum == this->mScrollArrow[1] )
{
// do slightly different things!
mLastEntryShown = min( mLastEntryShown + 1, GetNumberOfDataRows( ) );
mFirstEntryShown = mLastEntryShown - GetNumberOfDataRowsShown( );
}
// this should not happen
else
{
return;
}
SetRefresh( );
}
else if ( reason & MSYS_CALLBACK_REASON_RBUTTON_UP )
{
// nothing yet
}
}
void
TestTable::CalcRows()
{
// don't show more entries than exist
UINT32 numrows = GetNumberOfDataRows( );
UINT32 rowsshown = GetNumberOfDataRowsShown( );
mLastEntryShown = max( mLastEntryShown, rowsshown );
mLastEntryShown = min( mLastEntryShown, numrows );
if ( mLastEntryShown > rowsshown )
mFirstEntryShown = mLastEntryShown - rowsshown;
else
mFirstEntryShown = 0;
mLastEntryShown = mFirstEntryShown + rowsshown;
}
void
TestTable::CreateScrollAreaButtons( )
{
if ( !mScrollBarDefined )
{
if ( IsMouseRegionActive() )
{
MSYS_DefineRegion( &mScrollRegion, GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2, GetY( ), GetX( ) + GetWidth( ) - 2, GetY( ) + GetHeight( ) - 2, MSYS_PRIORITY_HIGHEST,
CURSOR_WWW,
RegionCallBackWrapper( (void*) this, CALLBACK_REGION_MOVE, &RegionDummyfunc ),
RegionCallBackWrapper( (void*) this, CALLBACK_REGION_CLICK, &RegionDummyfunc ) );
MSYS_AddRegion( &mScrollRegion );
MSYS_SetRegionUserData( &mScrollRegion, 0, 0 );
mScrollArrowImage[0] = LoadButtonImage( "INTERFACE\\HelpScreen.sti", 14, 10, 11, 12, 13 );
mScrollArrowImage[1] = UseLoadedButtonImage( mScrollArrowImage[0], 19, 15, 16, 17, 18 );
//Create the scroll arrows
mScrollArrow[0] = QuickCreateButton( mScrollArrowImage[0], GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2, GetY( ),
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
ButtonCallBackWrapper( (void*) this, CALLBACK_BUTTON_MOVE, &ButtonDummyfunc ),
ButtonCallBackWrapper( (void*) this, CALLBACK_BUTTON_CLICK, &ButtonDummyfunc ) );
MSYS_SetBtnUserData( mScrollArrow[0], 0, 0 );
//Create the scroll arrows
mScrollArrow[1] = QuickCreateButton( mScrollArrowImage[1], GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2, GetY( ) + GetHeight( ) - SCROLLARROW_HEIGTH - 2,
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
ButtonCallBackWrapper( (void*) this, CALLBACK_BUTTON_MOVE, &ButtonDummyfunc ),
ButtonCallBackWrapper( (void*) this, CALLBACK_BUTTON_CLICK, &ButtonDummyfunc ) );
MSYS_SetBtnUserData( mScrollArrow[1], 0, 1 );
mScrollBarDefined = TRUE;
}
else
{
// if buttons are disabled, we'll display the images of the buttons instead
HVOBJECT hArrowHandle;
//get and display the up and down arrows
GetVideoObject( &hArrowHandle, guiHelpScreenBackGround );
if ( hArrowHandle )
{
// top arrow
BltVideoObject( FRAME_BUFFER, hArrowHandle, 10,
GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2,
GetY( ),
VO_BLT_SRCTRANSPARENCY, NULL );
// down arrow
BltVideoObject( FRAME_BUFFER, hArrowHandle, 17,
GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2,
GetY( ) + GetHeight( ) - SCROLLARROW_HEIGTH - 2,
VO_BLT_SRCTRANSPARENCY, NULL );
}
}
}
}
UINT32
TestTable::GetNumberOfDataRows( )
{
BOOLEAN fFound = FALSE;
UINT32 minrowsinproviders = 1000;
std::vector<ColumnDataProvider>::iterator itend = mColumnDataProviderVector.end( );
for ( std::vector<ColumnDataProvider>::iterator it = mColumnDataProviderVector.begin( ); it != itend; ++it )
{
minrowsinproviders = min( minrowsinproviders, (*it).GetNumberOfEntries( ) );
fFound = TRUE;
}
if ( fFound && minrowsinproviders )
return minrowsinproviders;
return 0;
}
UINT32
TestTable::GetNumberOfDataRowsShown( )
{
// determine total height that can be used for display - we have to substract space for the header and the column headers
UINT32 heightperrow = GetRequiredHeigthPerRow();
if ( !heightperrow )
return 0;
UINT32 totalheighttodistribute = GetHeight( );
if ( totalheighttodistribute < heightperrow + TESTTABLE_OFFSET_ROW )
return 0;
totalheighttodistribute -= TESTTABLE_OFFSET_ROW;
UINT32 rows = GetNumberOfDataRows( );
if ( !rows )
return 0;
// we need TESTTABLE_OFFSET_ROW space for each row. We cannot display more than we have
return min( totalheighttodistribute / heightperrow, rows );
}
UINT32
TestTable::GetRequiredHeigthPerRow( )
{
UINT32 heigth = 0;
std::vector<ColumnDataProvider>::iterator itend = mColumnDataProviderVector.end( );
for ( std::vector<ColumnDataProvider>::iterator it = mColumnDataProviderVector.begin( ); it != itend; ++it )
{
heigth = max( heigth, (*it).GetRequiredHeigth( ) );
}
return heigth;
}
////////////////////////// TestTable /////////////////////////////////////