CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

TOOLTIP.CPP (9704B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 //	ToolTip.cpp
     17 #if (0)//PG
     18 #include "function.h"
     19 #include "ToolTip.h"
     20 #include "IconList.h"
     21 
     22 //#include "WolDebug.h"
     23 
     24 bool SaveSurfaceRect( int xRect, int yRect, int wRect, int hRect, char* pBits, WindowNumberType window );
     25 bool RestoreSurfaceRect( int xRect, int yRect, int wRect, int hRect, const char* pBits, WindowNumberType window );
     26 
     27 //***********************************************************************************************
     28 ToolTipClass::ToolTipClass( GadgetClass* pGadget, const char* szText, int xShow, int yShow, 
     29 								bool bRightAlign /* = false */, bool bIconList /*= false */ )
     30 	: pGadget( pGadget ), xShow( xShow ), yShow( yShow ), next( NULL ), bShowing( false ), bIconList( bIconList ),
     31 		bRightAlign( bRightAlign )
     32 
     33 {
     34 	if( szText )
     35 	{
     36 		if( strlen( szText ) > TOOLTIPTEXT_MAX_LEN )
     37 			strcpy( szTip, "Tooltip too long!" );
     38 		else
     39 			strcpy( szTip, szText );
     40 	}
     41 	else
     42 		*szTip = 0;
     43 
     44 	Set_Font( TypeFontPtr );
     45 	Fancy_Text_Print( TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TYPE );	//	Required before String_Pixel_Width() call, for god's sake.
     46 	wShow = String_Pixel_Width( szTip ) + 2;
     47 	hShow = 11;
     48 
     49 	if( !bIconList )
     50 	{
     51 		pSaveRect = new char[ wShow * hShow ];		//	Else it is reallocated on every draw.
     52 		if( bRightAlign )
     53 			this->xShow -= wShow;
     54 	}
     55 	else
     56 		pSaveRect = NULL;
     57 
     58 	//	bIconList is true if tooltips appear for individual line items in an iconlist.
     59 	//	szText in this case is ignored.
     60 	//	yShow is the y position of the top row's tooltip - other rows will be offset from here.
     61 }
     62 
     63 //***********************************************************************************************
     64 ToolTipClass* ToolTipClass::GetToolTipHit()
     65 {
     66 	//	Returns 'this' if the mouse is over gadget bound to tooltip.
     67 	//	Otherwise calls the same function in the next tooltip in the list of which *this is a part.
     68 	if( bGadgetHit() )
     69 		return this;
     70 	else if( next )
     71 		return next->GetToolTipHit();
     72 	else
     73 		return NULL;
     74 }
     75 
     76 //***********************************************************************************************
     77 bool ToolTipClass::bGadgetHit()
     78 {
     79 	//	Returns true if the mouse is currently over the gadget to which *this is bound.
     80 	int x = Get_Mouse_X();
     81 	int y = Get_Mouse_Y();
     82 	return ( x > pGadget->X && x < pGadget->X + pGadget->Width && y > pGadget->Y && y < pGadget->Y + pGadget->Height );
     83 }
     84 
     85 //***********************************************************************************************
     86 void ToolTipClass::Move( int xShow, int yShow )
     87 {
     88 	bool bRestoreShow = false;
     89 	if( bShowing )
     90 	{
     91 		bRestoreShow = true;
     92 		Unshow();
     93 	}
     94 	this->xShow = xShow;
     95 	if( !bIconList )
     96 	{
     97 		if( bRightAlign )
     98 			this->xShow -= wShow;
     99 	}
    100 	this->yShow = yShow;
    101 	if( bRestoreShow )
    102 		Show();
    103 }
    104 
    105 //***********************************************************************************************
    106 void ToolTipClass::Show()
    107 {
    108 	if( !bShowing )
    109 	{
    110 		Set_Font( TypeFontPtr );
    111 		int xShowUse = xShow, yShowUse, wShowUse;
    112 		const char* szTipUse;
    113 		if( !bIconList )
    114 		{
    115 			yShowUse = yShow;
    116 			wShowUse = wShow;
    117 			szTipUse = szTip;
    118 		}
    119 		else
    120 		{
    121 			IconListClass* pIconList = (IconListClass*)pGadget;
    122 			iLastIconListIndex = pIconList->IndexUnderMouse();
    123 			if( iLastIconListIndex < 0 )
    124 			{
    125 				//	Nothing to show.
    126 				bShowing = true;
    127 				return;
    128 			}
    129 			yShowUse = pIconList->OffsetToIndex( iLastIconListIndex, yShow );
    130 			szTipUse = pIconList->Get_Item_Help( iLastIconListIndex );
    131 			if( !szTipUse || *szTipUse == 0 )
    132 			{
    133 				//	Nothing to show.
    134 				bShowing = true;
    135 				bLastShowNoText = true;
    136 				return;
    137 			}
    138 			Fancy_Text_Print( TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TYPE );	//	Required before String_Pixel_Width() call, for god's sake.
    139 			wShowUse = String_Pixel_Width( szTipUse ) + 2;
    140 			if( bRightAlign )
    141 				xShowUse -= wShowUse;
    142 			delete [] pSaveRect;
    143 			pSaveRect = new char[ wShowUse * hShow ];
    144 			bLastShowNoText = false;
    145 			xLastShow = xShowUse;
    146 			yLastShow = yShowUse;
    147 			wLastShow = wShowUse;
    148 		}
    149 
    150 		//	Save rect about to be corrupted.
    151 		Hide_Mouse();
    152 		SaveSurfaceRect( xShowUse, yShowUse, wShowUse, hShow, pSaveRect, WINDOW_MAIN );
    153 		//	Draw text.
    154 		//Simple_Text_Print( szTipUse, xShowUse, yShowUse, GadgetClass::Get_Color_Scheme(), ColorRemaps[ PCOLOR_BROWN ].Color, TPF_TYPE ); //TPF_DROPSHADOW );
    155 		Simple_Text_Print( szTipUse, xShowUse, yShowUse, GadgetClass::Get_Color_Scheme(), BLACK, TPF_TYPE ); //TPF_DROPSHADOW );
    156 		//	Draw bounding rect.
    157 //		LogicPage->Draw_Rect( xShowUse, yShowUse, xShowUse + wShowUse - 1, yShowUse + hShow - 1, ColorRemaps[ PCOLOR_GOLD ].Color );
    158 		Draw_Box( xShowUse, yShowUse, wShowUse, hShow, BOXSTYLE_BOX, false );
    159 		Show_Mouse();
    160 		bShowing = true;
    161 	}
    162 }
    163 
    164 //***********************************************************************************************
    165 void ToolTipClass::Unshow()
    166 {
    167 	if( bShowing )
    168 	{
    169 		int xShowUse, yShowUse, wShowUse;
    170 		if( !bIconList )
    171 		{
    172 			xShowUse = xShow;
    173 			wShowUse = wShow;
    174 			yShowUse = yShow;
    175 		}
    176 		else
    177 		{
    178 			if( iLastIconListIndex == -1 || bLastShowNoText )
    179 			{
    180 				//	Nothing to restore.
    181 				bShowing = false;
    182 				return;
    183 			}
    184 			//	(Can't rely on iconlist being the same as when Show() occurred.)
    185 //			IconListClass* pIconList = (IconListClass*)pGadget;
    186 //			yShowUse = pIconList->OffsetToIndex( iLastIconListIndex, yShow );
    187 //			const char* szTipUsed = pIconList->Get_Item_Help( iLastIconListIndex );
    188 //			if( !szTipUsed || *szTipUsed == 0 )
    189 //			{
    190 //				//	Nothing to restore.
    191 //				bShowing = false;
    192 //				return;
    193 //			}
    194 //			Fancy_Text_Print( TXT_NONE, 0, 0, TBLACK, TBLACK, TPF_TYPE );	//	Required before String_Pixel_Width() call, for god's sake.
    195 //			wShowUse = String_Pixel_Width( szTipUsed ) + 2;
    196 //			if( bRightAlign )
    197 //				xShowUse -= wShowUse;
    198 			xShowUse = xLastShow;
    199 			yShowUse = yLastShow;
    200 			wShowUse = wLastShow;
    201 		}
    202 		Hide_Mouse();
    203 		RestoreSurfaceRect( xShowUse, yShowUse, wShowUse, hShow, pSaveRect, WINDOW_MAIN );
    204 		Show_Mouse();
    205 		bShowing = false;
    206 	}
    207 }
    208 
    209 //***********************************************************************************************
    210 bool ToolTipClass::bOverDifferentLine() const
    211 {
    212 	//	bIconList must be true if this is being used.
    213 	//	Returns true if the iconlist line that the mouse is over is different than the last time Show() was called.
    214 	return ( ((IconListClass*)pGadget)->IndexUnderMouse() != iLastIconListIndex );
    215 }
    216 
    217 //***********************************************************************************************
    218 bool SaveSurfaceRect( int xRect, int yRect, int wRect, int hRect, char* pBits, WindowNumberType window )
    219 {
    220 	//	Saves a rect of the LogicPage DirectDraw surface to pBits.
    221 //	if( wRect * hRect > iBufferSize )
    222 //	{
    223 //		debugprint( "SaveSurfaceRect failed.\n" );
    224 //		return false;
    225 //	}
    226 
    227 	GraphicViewPortClass draw_window(	LogicPage->Get_Graphic_Buffer(),
    228 										WindowList[window][WINDOWX] + LogicPage->Get_XPos(),
    229 										WindowList[window][WINDOWY] + LogicPage->Get_YPos(),
    230 										WindowList[window][WINDOWWIDTH],
    231 										WindowList[window][WINDOWHEIGHT] );
    232 	if( draw_window.Lock() )
    233 	{
    234 		int iPitchSurf = draw_window.Get_Pitch() + draw_window.Get_Width();	//	Meaning of "Pitch" in this class seems to mean the eol skip.
    235 		const char* pLineSurf = (char*)draw_window.Get_Offset() + xRect + yRect * iPitchSurf;
    236 		char* pLineSave = pBits;
    237 
    238 		//	ajw - Should copy DWORDs here instead for speed.
    239 		for( int y = 0; y != hRect; y++ )
    240 		{
    241 			const char* pSurf = pLineSurf;
    242 			char* pSave = pLineSave;
    243 			for( int x = 0; x != wRect; x++ )
    244 				*pSave++ = *pSurf++;
    245 
    246 			pLineSurf += iPitchSurf;
    247 			pLineSave += wRect;
    248 		}
    249 		draw_window.Unlock();
    250 		return true;
    251 	}
    252 	else
    253 	{
    254 //		debugprint( "SaveSurfaceRect Could not lock surface.\n" );
    255 		return false;
    256 	}
    257 }
    258 
    259 //***********************************************************************************************
    260 bool RestoreSurfaceRect( int xRect, int yRect, int wRect, int hRect, const char* pBits, WindowNumberType window )
    261 {
    262 	//	Copies a saved rect of bits back to the LogicPage DD surface.
    263 	GraphicViewPortClass draw_window(	LogicPage->Get_Graphic_Buffer(),
    264 										WindowList[window][WINDOWX] + LogicPage->Get_XPos(),
    265 										WindowList[window][WINDOWY] + LogicPage->Get_YPos(),
    266 										WindowList[window][WINDOWWIDTH],
    267 										WindowList[window][WINDOWHEIGHT] );
    268 	if( draw_window.Lock() )
    269 	{
    270 		int iPitchSurf = draw_window.Get_Pitch() + draw_window.Get_Width();	//	Meaning of "Pitch" in this class seems to mean the eol skip.
    271 		char* pLineSurf = (char*)draw_window.Get_Offset() + xRect + yRect * iPitchSurf;
    272 		const char* pLineSave = pBits;
    273 
    274 		//	ajw - Should copy DWORDs here instead for speed.
    275 		for( int y = 0; y != hRect; y++ )
    276 		{
    277 			char* pSurf = pLineSurf;
    278 			const char* pSave = pLineSave;
    279 			for( int x = 0; x != wRect; x++ )
    280 				*pSurf++ = *pSave++;
    281 
    282 			pLineSurf += iPitchSurf;
    283 			pLineSave += wRect;
    284 		}
    285 		draw_window.Unlock();
    286 		return true;
    287 	}
    288 	else
    289 	{
    290 //		debugprint( "RestoreSurfaceRect Could not lock surface.\n" );
    291 		return false;
    292 	}
    293 }
    294 #endif