/** * @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 #include "Sound Control.h" #define TESTTABLE_FONT_MED FONT12ARIAL #define TESTTABLE_OFFSET_ROW 20 #define TESTTABLE_FONT_COLOR_REGULAR 2 BaseTable::BaseTable( ) : WidgetBase( ), mName(L""), fInit(FALSE), musHeight(0), musWidth(0), musFrameWorkSpace(0), mActive(TRUE), mMouseRegionActive(TRUE) { SetColorLine( Get16BPPColor( FROMRGB( 128, 128, 128 ) ) ); SetColorLineShadow( Get16BPPColor( FROMRGB( 255, 78, 255 ) ) ); SetColorMarked( Get16BPPColor( FROMRGB( 200, 169, 87 ) ) ); SetColorHighLight( Get16BPPColor( FROMRGB( 235, 222, 171 ) ) ); } 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::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::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::iterator it = mRegisteredMembers.begin( ); it != mRegisteredMembers.end( ); ++it ) { if ( (*it) && (*it)->IsActive() ) (*it)->Display( ); } } void BaseTable::DestroyMouseRegions( ) { if ( !IsInit( ) ) return; for ( std::vector::iterator it = mRegisteredMembers.begin( ); it != mRegisteredMembers.end( ); ++it ) { if ( (*it) ) (*it)->DestroyMouseRegions( ); } } STR16 cdp_string_func_dummy( UINT32 aNum ) { return L"nothing found"; } UINT8 cdp_textcolour_func_dummy( UINT32 aNum ) { return TESTTABLE_FONT_COLOR_REGULAR; } 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 = max( mRequiredLength, 6 * wcslen( mName ) ); switch ( GetProviderType() ) { case CDP_STRING: for ( UINT32 i = 0; i < mNumberOfEntries; ++i ) { mRequiredLength = max( mRequiredLength, 6 * wcslen( GetString( i ) ) ); } break; case CDP_IMAGE: /*for ( UINT32 i = 0; i < mNumberOfEntries; ++i ) { // TODO... }*/ break; case CDP_STATUSBAR: mRequiredLength = max( mRequiredLength, 4); break; } } extern void callbackmilitialist( INT32 usId ); extern void callbackmilitiadetail( INT32 usId ); extern void callbacktoggle( INT32 usId ); void ColumnDataProvider::RegionClickCallBack( MOUSE_REGION * pRegion, INT32 iReason ) { if ( iReason & MSYS_CALLBACK_REASON_INIT ) { } else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP ) { } 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_TOGGLE: callbacktoggle( pRegion->UserData[1] ); // we pretend to be a button, thus we make a sound PlayJA2Sample( BIG_SWITCH3_IN, RATE_11025, BTNVOLUME, 1, MIDDLEPAN ); 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 ////////////// TestPanel/////////////////////////////////////// TestPanel::TestPanel( ) : BaseTable( ) { SetFrameWorkSpace( 4 ); } void TestPanel::Display( ) { if ( !IsInit( ) ) return; //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::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::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::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( ) { if ( !IsInit( ) ) return; for ( std::vector::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 ) { } else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { for ( std::vector::iterator it = mRegisteredTables.begin(); it != mRegisteredTables.end(); ++it ) { if ( pRegion->IDNumber == (*it).mMouseRegion.IDNumber ) (*it).mTestPanel->SetActive( TRUE ); else (*it).mTestPanel->SetActive( FALSE ); } SetRefresh( ); } 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 ), mColorSeparator( FROMRGB( 0, 255, 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; } for ( std::vector::iterator it = mColumnDataProviderVector.begin( ), itend = mColumnDataProviderVector.end(); 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::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, GetColorSeparator() ); for ( std::vector::iterator it = mColumnDataProviderVector.begin( ), itend = mColumnDataProviderVector.end(); it != itend; ++it ) { if ( it->GetProviderType() == ColumnDataProvider::CDP_STRING ) { swprintf( sText, ( *it ).GetString( i ) ); DrawTextToScreen( sText, usPosX, usPosY + 7, GetWidth(), TESTTABLE_FONT_MED, ( *it ).GetColour( i ), 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, col2 = 0, col3 = 0, col4 = 0, val1 = 0, val2 = 0, val3 = 0, 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, GetX( ) + GetWidth( ) - 2, GetY( ) + SCROLLARROW_HEIGTH + GetHeight( ) - SCROLLARROW_HEIGTH, GetColorLineShadow( ) ); ColorFillVideoSurfaceArea( FRAME_BUFFER, GetX( ) + GetWidth( ) - SCROLLARROW_WIDTH - 2, GetY( ) + SCROLLARROW_HEIGTH + areabegin, GetX( ) + GetWidth( ) - 2, GetY( ) + SCROLLARROW_HEIGTH + areabegin + scrollareaheigth, GetColorLine() ); CreateScrollAreaButtons( ); } } BaseTable::Display( ); } void TestTable::DestroyMouseRegions() { if ( !IsInit( ) ) return; std::vector::iterator itend = mColumnDataProviderVector.end( ); for ( std::vector::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; for ( std::vector::iterator it = mColumnDataProviderVector.begin( ), itend = mColumnDataProviderVector.end(); 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; for ( std::vector::iterator it = mColumnDataProviderVector.begin( ), itend = mColumnDataProviderVector.end(); it != itend; ++it ) { heigth = max( heigth, (*it).GetRequiredHeigth( ) ); } return heigth; } ////////////////////////// TestTable /////////////////////////////////////