CnC_Remastered_Collection/REDALERT/TOOLTIP.CPP
PG-SteveT 03416d24e1 Initial Source Code commit
Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
2020-05-27 12:16:20 -07:00

294 lines
9.5 KiB
C++

//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
// ToolTip.cpp
#if (0)//PG
#include "function.h"
#include "ToolTip.h"
#include "IconList.h"
//#include "WolDebug.h"
bool SaveSurfaceRect( int xRect, int yRect, int wRect, int hRect, char* pBits, WindowNumberType window );
bool RestoreSurfaceRect( int xRect, int yRect, int wRect, int hRect, const char* pBits, WindowNumberType window );
//***********************************************************************************************
ToolTipClass::ToolTipClass( GadgetClass* pGadget, const char* szText, int xShow, int yShow,
bool bRightAlign /* = false */, bool bIconList /*= false */ )
: pGadget( pGadget ), xShow( xShow ), yShow( yShow ), next( NULL ), bShowing( false ), bIconList( bIconList ),
bRightAlign( bRightAlign )
{
if( szText )
{
if( strlen( szText ) > TOOLTIPTEXT_MAX_LEN )
strcpy( szTip, "Tooltip too long!" );
else
strcpy( szTip, szText );
}
else
*szTip = 0;
Set_Font( TypeFontPtr );
Fancy_Text_Print( TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TYPE ); // Required before String_Pixel_Width() call, for god's sake.
wShow = String_Pixel_Width( szTip ) + 2;
hShow = 11;
if( !bIconList )
{
pSaveRect = new char[ wShow * hShow ]; // Else it is reallocated on every draw.
if( bRightAlign )
this->xShow -= wShow;
}
else
pSaveRect = NULL;
// bIconList is true if tooltips appear for individual line items in an iconlist.
// szText in this case is ignored.
// yShow is the y position of the top row's tooltip - other rows will be offset from here.
}
//***********************************************************************************************
ToolTipClass* ToolTipClass::GetToolTipHit()
{
// Returns 'this' if the mouse is over gadget bound to tooltip.
// Otherwise calls the same function in the next tooltip in the list of which *this is a part.
if( bGadgetHit() )
return this;
else if( next )
return next->GetToolTipHit();
else
return NULL;
}
//***********************************************************************************************
bool ToolTipClass::bGadgetHit()
{
// Returns true if the mouse is currently over the gadget to which *this is bound.
int x = Get_Mouse_X();
int y = Get_Mouse_Y();
return ( x > pGadget->X && x < pGadget->X + pGadget->Width && y > pGadget->Y && y < pGadget->Y + pGadget->Height );
}
//***********************************************************************************************
void ToolTipClass::Move( int xShow, int yShow )
{
bool bRestoreShow = false;
if( bShowing )
{
bRestoreShow = true;
Unshow();
}
this->xShow = xShow;
if( !bIconList )
{
if( bRightAlign )
this->xShow -= wShow;
}
this->yShow = yShow;
if( bRestoreShow )
Show();
}
//***********************************************************************************************
void ToolTipClass::Show()
{
if( !bShowing )
{
Set_Font( TypeFontPtr );
int xShowUse = xShow, yShowUse, wShowUse;
const char* szTipUse;
if( !bIconList )
{
yShowUse = yShow;
wShowUse = wShow;
szTipUse = szTip;
}
else
{
IconListClass* pIconList = (IconListClass*)pGadget;
iLastIconListIndex = pIconList->IndexUnderMouse();
if( iLastIconListIndex < 0 )
{
// Nothing to show.
bShowing = true;
return;
}
yShowUse = pIconList->OffsetToIndex( iLastIconListIndex, yShow );
szTipUse = pIconList->Get_Item_Help( iLastIconListIndex );
if( !szTipUse || *szTipUse == 0 )
{
// Nothing to show.
bShowing = true;
bLastShowNoText = true;
return;
}
Fancy_Text_Print( TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TYPE ); // Required before String_Pixel_Width() call, for god's sake.
wShowUse = String_Pixel_Width( szTipUse ) + 2;
if( bRightAlign )
xShowUse -= wShowUse;
delete [] pSaveRect;
pSaveRect = new char[ wShowUse * hShow ];
bLastShowNoText = false;
xLastShow = xShowUse;
yLastShow = yShowUse;
wLastShow = wShowUse;
}
// Save rect about to be corrupted.
Hide_Mouse();
SaveSurfaceRect( xShowUse, yShowUse, wShowUse, hShow, pSaveRect, WINDOW_MAIN );
// Draw text.
//Simple_Text_Print( szTipUse, xShowUse, yShowUse, GadgetClass::Get_Color_Scheme(), ColorRemaps[ PCOLOR_BROWN ].Color, TPF_TYPE ); //TPF_DROPSHADOW );
Simple_Text_Print( szTipUse, xShowUse, yShowUse, GadgetClass::Get_Color_Scheme(), BLACK, TPF_TYPE ); //TPF_DROPSHADOW );
// Draw bounding rect.
// LogicPage->Draw_Rect( xShowUse, yShowUse, xShowUse + wShowUse - 1, yShowUse + hShow - 1, ColorRemaps[ PCOLOR_GOLD ].Color );
Draw_Box( xShowUse, yShowUse, wShowUse, hShow, BOXSTYLE_BOX, false );
Show_Mouse();
bShowing = true;
}
}
//***********************************************************************************************
void ToolTipClass::Unshow()
{
if( bShowing )
{
int xShowUse, yShowUse, wShowUse;
if( !bIconList )
{
xShowUse = xShow;
wShowUse = wShow;
yShowUse = yShow;
}
else
{
if( iLastIconListIndex == -1 || bLastShowNoText )
{
// Nothing to restore.
bShowing = false;
return;
}
// (Can't rely on iconlist being the same as when Show() occurred.)
// IconListClass* pIconList = (IconListClass*)pGadget;
// yShowUse = pIconList->OffsetToIndex( iLastIconListIndex, yShow );
// const char* szTipUsed = pIconList->Get_Item_Help( iLastIconListIndex );
// if( !szTipUsed || *szTipUsed == 0 )
// {
// // Nothing to restore.
// bShowing = false;
// return;
// }
// Fancy_Text_Print( TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TYPE ); // Required before String_Pixel_Width() call, for god's sake.
// wShowUse = String_Pixel_Width( szTipUsed ) + 2;
// if( bRightAlign )
// xShowUse -= wShowUse;
xShowUse = xLastShow;
yShowUse = yLastShow;
wShowUse = wLastShow;
}
Hide_Mouse();
RestoreSurfaceRect( xShowUse, yShowUse, wShowUse, hShow, pSaveRect, WINDOW_MAIN );
Show_Mouse();
bShowing = false;
}
}
//***********************************************************************************************
bool ToolTipClass::bOverDifferentLine() const
{
// bIconList must be true if this is being used.
// Returns true if the iconlist line that the mouse is over is different than the last time Show() was called.
return ( ((IconListClass*)pGadget)->IndexUnderMouse() != iLastIconListIndex );
}
//***********************************************************************************************
bool SaveSurfaceRect( int xRect, int yRect, int wRect, int hRect, char* pBits, WindowNumberType window )
{
// Saves a rect of the LogicPage DirectDraw surface to pBits.
// if( wRect * hRect > iBufferSize )
// {
// debugprint( "SaveSurfaceRect failed.\n" );
// return false;
// }
GraphicViewPortClass draw_window( LogicPage->Get_Graphic_Buffer(),
WindowList[window][WINDOWX] + LogicPage->Get_XPos(),
WindowList[window][WINDOWY] + LogicPage->Get_YPos(),
WindowList[window][WINDOWWIDTH],
WindowList[window][WINDOWHEIGHT] );
if( draw_window.Lock() )
{
int iPitchSurf = draw_window.Get_Pitch() + draw_window.Get_Width(); // Meaning of "Pitch" in this class seems to mean the eol skip.
const char* pLineSurf = (char*)draw_window.Get_Offset() + xRect + yRect * iPitchSurf;
char* pLineSave = pBits;
// ajw - Should copy DWORDs here instead for speed.
for( int y = 0; y != hRect; y++ )
{
const char* pSurf = pLineSurf;
char* pSave = pLineSave;
for( int x = 0; x != wRect; x++ )
*pSave++ = *pSurf++;
pLineSurf += iPitchSurf;
pLineSave += wRect;
}
draw_window.Unlock();
return true;
}
else
{
// debugprint( "SaveSurfaceRect Could not lock surface.\n" );
return false;
}
}
//***********************************************************************************************
bool RestoreSurfaceRect( int xRect, int yRect, int wRect, int hRect, const char* pBits, WindowNumberType window )
{
// Copies a saved rect of bits back to the LogicPage DD surface.
GraphicViewPortClass draw_window( LogicPage->Get_Graphic_Buffer(),
WindowList[window][WINDOWX] + LogicPage->Get_XPos(),
WindowList[window][WINDOWY] + LogicPage->Get_YPos(),
WindowList[window][WINDOWWIDTH],
WindowList[window][WINDOWHEIGHT] );
if( draw_window.Lock() )
{
int iPitchSurf = draw_window.Get_Pitch() + draw_window.Get_Width(); // Meaning of "Pitch" in this class seems to mean the eol skip.
char* pLineSurf = (char*)draw_window.Get_Offset() + xRect + yRect * iPitchSurf;
const char* pLineSave = pBits;
// ajw - Should copy DWORDs here instead for speed.
for( int y = 0; y != hRect; y++ )
{
char* pSurf = pLineSurf;
const char* pSave = pLineSave;
for( int x = 0; x != wRect; x++ )
*pSurf++ = *pSave++;
pLineSurf += iPitchSurf;
pLineSave += wRect;
}
draw_window.Unlock();
return true;
}
else
{
// debugprint( "RestoreSurfaceRect Could not lock surface.\n" );
return false;
}
}
#endif