W3DPushButton.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: W3DPushButton.cpp ////////////////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Westwood Studios Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2001 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // Project: RTS3
  34. //
  35. // File name: W3DPushButton.cpp
  36. //
  37. // Created: Colin Day, June 2001
  38. //
  39. // Desc: W3D implementation for the push button control element
  40. //
  41. //-----------------------------------------------------------------------------
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  44. #include <stdlib.h>
  45. // USER INCLUDES //////////////////////////////////////////////////////////////
  46. #include "GameClient/Gadget.h"
  47. #include "GameClient/GameWindowGlobal.h"
  48. #include "GameClient/GameWindowManager.h"
  49. #include "GameClient/GadgetPushButton.h"
  50. #include "GameClient/Display.h"
  51. #include "W3DDevice/GameClient/W3DGameWindow.h"
  52. #include "W3DDevice/GameClient/W3DDisplay.h"
  53. #include "W3DDevice/GameClient/W3DGadget.h"
  54. #ifdef _INTERNAL
  55. // for occasional debugging...
  56. //#pragma optimize("", off)
  57. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  58. #endif
  59. // DEFINES ////////////////////////////////////////////////////////////////////
  60. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  61. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  62. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  63. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  64. void W3DGadgetPushButtonImageDrawThree(GameWindow *window, WinInstanceData *instData );
  65. void W3DGadgetPushButtonImageDrawOne(GameWindow *window, WinInstanceData *instData );
  66. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  67. // drawButtonText =============================================================
  68. /** Draw button text to the screen */
  69. //=============================================================================
  70. static void drawButtonText( GameWindow *window, WinInstanceData *instData )
  71. {
  72. ICoord2D origin, size, textPos;
  73. Int width, height;
  74. Color textColor, dropColor;
  75. DisplayString *text = instData->getTextDisplayString();
  76. // sanity
  77. if( text == NULL || text->getTextLength() == 0 )
  78. return;
  79. // get window position and size
  80. window->winGetScreenPosition( &origin.x, &origin.y );
  81. window->winGetSize( &size.x, &size.y );
  82. // set whether or not we center the wrapped text
  83. text->setWordWrapCentered( BitTest( instData->getStatus(), WIN_STATUS_WRAP_CENTERED ));
  84. text->setWordWrap(size.x);
  85. // get the right text color
  86. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  87. {
  88. textColor = window->winGetDisabledTextColor();
  89. dropColor = window->winGetDisabledTextBorderColor();
  90. } // end if, disabled
  91. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  92. {
  93. textColor = window->winGetHiliteTextColor();
  94. dropColor = window->winGetHiliteTextBorderColor();
  95. } // end else if, hilited
  96. else
  97. {
  98. textColor = window->winGetEnabledTextColor();
  99. dropColor = window->winGetEnabledTextBorderColor();
  100. } // end enabled only
  101. // set our font to that of our parent if not the same
  102. if( text->getFont() != window->winGetFont() )
  103. text->setFont( window->winGetFont() );
  104. // get text size
  105. text->getSize( &width, &height );
  106. // where to draw
  107. if( BitTest( window->winGetStatus(), WIN_STATUS_SHORTCUT_BUTTON ) )
  108. {
  109. // Oh god... this is a total hack for shortcut buttons to handle rendering text top left corner...
  110. textPos.x = origin.x + 2;
  111. textPos.y = origin.y + 0;
  112. }
  113. else
  114. {
  115. textPos.x = origin.x + (size.x / 2) - (width / 2);
  116. textPos.y = origin.y + (size.y / 2) - (height / 2);
  117. }
  118. // draw it
  119. text->draw( textPos.x, textPos.y, textColor, dropColor );
  120. } // end drawButtonText
  121. ///////////////////////////////////////////////////////////////////////////////
  122. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  123. ///////////////////////////////////////////////////////////////////////////////
  124. // W3DGadgetPushButtonDraw ====================================================
  125. /** Draw colored pushbutton using standard graphics */
  126. //=============================================================================
  127. void W3DGadgetPushButtonDraw( GameWindow *window, WinInstanceData *instData )
  128. {
  129. Color color, border;
  130. ICoord2D origin, size, start, end;
  131. // get window position and size
  132. window->winGetScreenPosition( &origin.x, &origin.y );
  133. window->winGetSize( &size.x, &size.y );
  134. //
  135. // get pointer to image we want to draw depending on our state,
  136. // see GadgetPushButton.h for info
  137. //
  138. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  139. {
  140. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  141. {
  142. color = GadgetButtonGetDisabledSelectedColor( window );
  143. border = GadgetButtonGetDisabledSelectedBorderColor( window );
  144. }
  145. else
  146. {
  147. color = GadgetButtonGetDisabledColor( window );
  148. border = GadgetButtonGetDisabledBorderColor( window );
  149. }
  150. } // end if, disabled
  151. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  152. {
  153. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  154. {
  155. color = GadgetButtonGetHiliteSelectedColor( window );
  156. border = GadgetButtonGetHiliteSelectedBorderColor( window );
  157. }
  158. else
  159. {
  160. color = GadgetButtonGetHiliteColor( window );
  161. border = GadgetButtonGetHiliteBorderColor( window );
  162. }
  163. } // end else if, hilited and enabled
  164. else
  165. {
  166. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  167. {
  168. color = GadgetButtonGetEnabledSelectedColor( window );
  169. border = GadgetButtonGetEnabledSelectedBorderColor( window );
  170. }
  171. else
  172. {
  173. color = GadgetButtonGetEnabledColor( window );
  174. border = GadgetButtonGetEnabledBorderColor( window );
  175. }
  176. } // end else, enabled only
  177. // compute draw position
  178. start.x = origin.x;
  179. start.y = origin.y;
  180. end.x = start.x + size.x;
  181. end.y = start.y + size.y;
  182. // box and border
  183. if( border != WIN_COLOR_UNDEFINED )
  184. {
  185. TheWindowManager->winOpenRect( border, WIN_DRAW_LINE_WIDTH,
  186. start.x, start.y, end.x, end.y );
  187. } // end if
  188. if( color != WIN_COLOR_UNDEFINED )
  189. {
  190. // draw inside border
  191. start.x++;
  192. start.y++;
  193. end.x--;
  194. end.y--;
  195. TheWindowManager->winFillRect( color, WIN_DRAW_LINE_WIDTH,
  196. start.x, start.y, end.x, end.y );
  197. } // end if
  198. // draw the button text
  199. if( instData->getTextLength() )
  200. drawButtonText( window, instData );
  201. // if we have a video buffer, draw the video buffer
  202. if ( instData->m_videoBuffer )
  203. {
  204. TheDisplay->drawVideoBuffer( instData->m_videoBuffer, origin.x, origin.y, origin.x + size.x, origin.y + size.y );
  205. }
  206. PushButtonData *pData = (PushButtonData *)window->winGetUserData();
  207. if( pData )
  208. {
  209. if( pData->overlayImage )
  210. {
  211. //Render the overlay image now.
  212. TheDisplay->drawImage( pData->overlayImage, origin.x, origin.y, origin.x + size.x, origin.y + size.y );
  213. }
  214. if( pData->drawClock )
  215. {
  216. if( pData->drawClock == NORMAL_CLOCK )
  217. {
  218. TheDisplay->drawRectClock(origin.x, origin.y, size.x, size.y, pData->percentClock,pData->colorClock);
  219. }
  220. else if( pData->drawClock == INVERSE_CLOCK )
  221. {
  222. TheDisplay->drawRemainingRectClock( origin.x, origin.y, size.x, size.y, pData->percentClock,pData->colorClock );
  223. }
  224. pData->drawClock = NO_CLOCK;
  225. window->winSetUserData(pData);
  226. }
  227. if( pData->drawBorder && pData->colorBorder != GAME_COLOR_UNDEFINED )
  228. {
  229. TheDisplay->drawOpenRect(origin.x -1, origin.y - 1, size.x + 2, size.y + 2,1 , pData->colorBorder);
  230. }
  231. }
  232. } // end W3DGadgetPushButtonDraw
  233. // W3DGadgetPushButtonImageDraw ===============================================
  234. /** Draw pushbutton with user supplied images */
  235. //=============================================================================
  236. void W3DGadgetPushButtonImageDraw( GameWindow *window,
  237. WinInstanceData *instData )
  238. {
  239. // if we return NULL then we'll call the one picture drawing code, if we return a value
  240. // then we'll call the 3 picture drawing code
  241. if( GadgetButtonGetMiddleEnabledImage( window ) )
  242. {
  243. if( BitTest( instData->getState(), WIN_STATUS_USE_OVERLAY_STATES ) )
  244. {
  245. ICoord2D size, start;
  246. // get window position
  247. window->winGetScreenPosition( &start.x, &start.y );
  248. window->winGetSize( &size.x, &size.y );
  249. // offset position by image offset
  250. start.x += instData->m_imageOffset.x;
  251. start.y += instData->m_imageOffset.y;
  252. DEBUG_CRASH( ("Button at %d,%d is attempting to render with W3DGadgetPushButtonImageDrawThree(), but is using overlay states! Forcing the code to use W3DGadgetPushButtonImageDrawOne() instead.", start.x, start.y ) );
  253. W3DGadgetPushButtonImageDrawOne( window, instData );
  254. }
  255. else
  256. {
  257. W3DGadgetPushButtonImageDrawThree( window, instData );
  258. }
  259. }
  260. else
  261. {
  262. W3DGadgetPushButtonImageDrawOne( window, instData );
  263. }
  264. }
  265. void W3DGadgetPushButtonImageDrawOne( GameWindow *window,
  266. WinInstanceData *instData )
  267. {
  268. const Image *image = NULL;
  269. ICoord2D size, start, end;
  270. //
  271. // get pointer to image we want to draw depending on our state,
  272. // see GadgetPushButton.h for info
  273. //
  274. image = GadgetButtonGetEnabledImage( window );
  275. if( !BitTest( window->winGetStatus(), WIN_STATUS_USE_OVERLAY_STATES ) )
  276. {
  277. //Certain buttons have the option to specify specific images for
  278. //altered states. If they do, then we won't render the auto-overlay versions.
  279. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  280. {
  281. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  282. image = GadgetButtonGetDisabledSelectedImage( window );
  283. else
  284. image = GadgetButtonGetDisabledImage( window );
  285. } // end if, disabled
  286. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  287. {
  288. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  289. image = GadgetButtonGetHiliteSelectedImage( window );
  290. else
  291. image = GadgetButtonGetHiliteImage( window );
  292. } // end else if, hilited and enabled
  293. else
  294. {
  295. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  296. image = GadgetButtonGetHiliteSelectedImage( window );
  297. } // end else, enabled only
  298. }
  299. // draw the image
  300. if( image )
  301. {
  302. // get window position
  303. window->winGetScreenPosition( &start.x, &start.y );
  304. window->winGetSize( &size.x, &size.y );
  305. // offset position by image offset
  306. start.x += instData->m_imageOffset.x;
  307. start.y += instData->m_imageOffset.y;
  308. // find end point
  309. end.x = start.x + size.x;
  310. end.y = start.y + size.y;
  311. Display::DrawImageMode drawMode=Display::DRAW_IMAGE_ALPHA;
  312. Int colorMultiplier = 0xffffffff;
  313. if(BitTest( window->winGetStatus(), WIN_STATUS_USE_OVERLAY_STATES ) )
  314. {
  315. //we're using a new drawing system which does "grayscale" disabled buttons using original color artwork.
  316. if( !BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) )
  317. {
  318. if( !BitTest( window->winGetStatus(), WIN_STATUS_NOT_READY ) )
  319. {
  320. //The button is disabled -- but if the button isn't "ready", we don't want to do this because
  321. //we want to show the button in color with just the clock overlay.
  322. if( !BitTest( window->winGetStatus(), WIN_STATUS_ALWAYS_COLOR ) )
  323. {
  324. drawMode=Display::DRAW_IMAGE_GRAYSCALE;
  325. }
  326. else
  327. {
  328. colorMultiplier = 0xff909090; //RGB values are 144/255 (90) -- Alpha is opaque (ff) --> ff909090;
  329. }
  330. }
  331. }
  332. }
  333. TheDisplay->drawImage( image, start.x, start.y, end.x, end.y, colorMultiplier, drawMode );
  334. } // end if
  335. // draw the button text
  336. if( instData->getTextLength() )
  337. drawButtonText( window, instData );
  338. // get window position
  339. window->winGetScreenPosition( &start.x, &start.y );
  340. window->winGetSize( &size.x, &size.y );
  341. // if we have a video buffer, draw the video buffer
  342. if ( instData->m_videoBuffer )
  343. {
  344. TheDisplay->drawVideoBuffer( instData->m_videoBuffer, start.x, start.y, start.x + size.x, start.y + size.y );
  345. }
  346. PushButtonData *pData = (PushButtonData *)window->winGetUserData();
  347. if( pData )
  348. {
  349. if( pData->overlayImage )
  350. {
  351. //Render the overlay image now.
  352. TheDisplay->drawImage( pData->overlayImage, start.x, start.y, start.x + size.x, start.y + size.y );
  353. }
  354. if( pData->drawClock )
  355. {
  356. if( pData->drawClock == NORMAL_CLOCK )
  357. {
  358. TheDisplay->drawRectClock(start.x, start.y, size.x, size.y, pData->percentClock,pData->colorClock);
  359. }
  360. else if( pData->drawClock == INVERSE_CLOCK )
  361. {
  362. TheDisplay->drawRemainingRectClock( start.x, start.y, size.x, size.y, pData->percentClock,pData->colorClock );
  363. }
  364. pData->drawClock = NO_CLOCK;
  365. window->winSetUserData(pData);
  366. }
  367. if( pData->drawBorder && pData->colorBorder != GAME_COLOR_UNDEFINED )
  368. {
  369. TheDisplay->drawOpenRect(start.x - 1, start.y - 1, size.x + 2, size.y + 2, 1, pData->colorBorder);
  370. }
  371. }
  372. //Now render overlays that pertain to the correct state.
  373. if( BitTest( window->winGetStatus(), WIN_STATUS_FLASHING ) )
  374. {
  375. //Handle cameo flashing (let the flashing stack with overlay states)
  376. static const Image *hilitedOverlayIcon = TheMappedImageCollection->findImageByName( "Cameo_push" );
  377. TheDisplay->drawImage( hilitedOverlayIcon, start.x, start.y, start.x + size.x, start.y + size.y );
  378. }
  379. if( BitTest( window->winGetStatus(), WIN_STATUS_USE_OVERLAY_STATES ) )
  380. {
  381. image = NULL;
  382. static const Image *pushedOverlayIcon = TheMappedImageCollection->findImageByName( "Cameo_push" );
  383. static const Image *hilitedOverlayIcon = TheMappedImageCollection->findImageByName( "Cameo_hilited" );
  384. if( pushedOverlayIcon && hilitedOverlayIcon )
  385. {
  386. if(BitTest(window->winGetStatus(), WIN_STATUS_ENABLED))
  387. {
  388. if (BitTest( instData->getState(), WIN_STATE_HILITED ))
  389. {
  390. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  391. {
  392. //The button is hilited and pushed
  393. TheDisplay->drawImage( pushedOverlayIcon, start.x, start.y, start.x + size.x, start.y + size.y );
  394. }
  395. else
  396. {
  397. //The button is hilited
  398. TheDisplay->drawImage( hilitedOverlayIcon, start.x, start.y, start.x + size.x, start.y + size.y );
  399. }
  400. }
  401. else if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  402. {
  403. //The button appears to be pushed -- CHECK_LIKE buttons that are on.
  404. TheDisplay->drawImage( pushedOverlayIcon, start.x, start.y, start.x + size.x, start.y + size.y );
  405. }
  406. }
  407. }
  408. }
  409. } // end W3DGadgetPushButtonImageDraw
  410. void W3DGadgetPushButtonImageDrawThree(GameWindow *window, WinInstanceData *instData )
  411. {
  412. const Image *leftImage, *rightImage, *centerImage;
  413. ICoord2D origin, size, start, end;
  414. Int xOffset, yOffset;
  415. Int i;
  416. // get screen position and size
  417. window->winGetScreenPosition( &origin.x, &origin.y );
  418. window->winGetSize( &size.x, &size.y );
  419. // get image offset
  420. xOffset = instData->m_imageOffset.x;
  421. yOffset = instData->m_imageOffset.y;
  422. //
  423. // get pointer to image we want to draw depending on our state,
  424. // see GadgetPushButton.h for info
  425. //
  426. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  427. {
  428. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  429. {
  430. leftImage = GadgetButtonGetLeftDisabledSelectedImage( window );
  431. rightImage = GadgetButtonGetRightDisabledSelectedImage( window );
  432. centerImage = GadgetButtonGetMiddleDisabledSelectedImage( window );
  433. }
  434. else
  435. {
  436. leftImage = GadgetButtonGetLeftDisabledImage( window );
  437. rightImage = GadgetButtonGetRightDisabledImage( window );
  438. centerImage = GadgetButtonGetMiddleDisabledImage( window );
  439. }
  440. } // end if, disabled
  441. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  442. {
  443. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  444. {
  445. leftImage = GadgetButtonGetLeftHiliteSelectedImage( window );
  446. rightImage = GadgetButtonGetRightHiliteSelectedImage( window );
  447. centerImage = GadgetButtonGetMiddleHiliteSelectedImage( window );
  448. }
  449. else
  450. {
  451. leftImage = GadgetButtonGetLeftHiliteImage( window );
  452. rightImage = GadgetButtonGetRightHiliteImage( window );
  453. centerImage = GadgetButtonGetMiddleHiliteImage( window );
  454. }
  455. } // end else if, hilited and enabled
  456. else
  457. {
  458. if( BitTest( instData->getState(), WIN_STATE_SELECTED ) )
  459. {
  460. leftImage = GadgetButtonGetLeftEnabledSelectedImage( window );
  461. rightImage = GadgetButtonGetRightEnabledSelectedImage( window );
  462. centerImage = GadgetButtonGetMiddleEnabledSelectedImage( window );
  463. }
  464. else
  465. {
  466. leftImage = GadgetButtonGetLeftEnabledImage( window );
  467. rightImage = GadgetButtonGetRightEnabledImage( window );
  468. centerImage = GadgetButtonGetMiddleEnabledImage( window );
  469. }
  470. } // end else, enabled only
  471. // sanity, we need to have these images to make it look right
  472. if( leftImage == NULL || rightImage == NULL ||
  473. centerImage == NULL )
  474. return;
  475. // get image sizes for the ends
  476. ICoord2D leftSize, rightSize;
  477. leftSize.x = leftImage->getImageWidth();
  478. leftSize.y = leftImage->getImageHeight();
  479. rightSize.x = rightImage->getImageWidth();
  480. rightSize.y = rightImage->getImageHeight();
  481. // get two key points used in the end drawing
  482. ICoord2D leftEnd, rightStart;
  483. leftEnd.x = origin.x + leftSize.x + xOffset;
  484. leftEnd.y = origin.y + size.y + yOffset;
  485. rightStart.x = origin.x + size.x - rightSize.x + xOffset;
  486. rightStart.y = origin.y + yOffset;
  487. // draw the center repeating bar
  488. Int centerWidth, pieces;
  489. // get width we have to draw our repeating center in
  490. centerWidth = rightStart.x - leftEnd.x;
  491. if( centerWidth <= 0)
  492. {
  493. // draw left end
  494. start.x = origin.x + xOffset;
  495. start.y = origin.y + yOffset;
  496. end.y = leftEnd.y;
  497. end.x = origin.x + xOffset + size.x/2;
  498. TheWindowManager->winDrawImage(leftImage, start.x, start.y, end.x, end.y);
  499. // draw right end
  500. start.y = rightStart.y;
  501. start.x = end.x;
  502. end.x = origin.x + size.x;
  503. end.y = start.y + size.y;
  504. TheWindowManager->winDrawImage(rightImage, start.x, start.y, end.x, end.y);
  505. }
  506. else
  507. {
  508. // how many whole repeating pieces will fit in that width
  509. pieces = centerWidth / centerImage->getImageWidth();
  510. // draw the pieces
  511. start.x = leftEnd.x;
  512. start.y = origin.y + yOffset;
  513. end.y = start.y + size.y + yOffset; //centerImage->getImageHeight() + yOffset;
  514. for( i = 0; i < pieces; i++ )
  515. {
  516. end.x = start.x + centerImage->getImageWidth();
  517. TheWindowManager->winDrawImage( centerImage,
  518. start.x, start.y,
  519. end.x, end.y );
  520. start.x += centerImage->getImageWidth();
  521. } // end for i
  522. // we will draw the image but clip the parts we don't want to show
  523. IRegion2D reg;
  524. reg.lo.x = start.x;
  525. reg.lo.y = start.y;
  526. reg.hi.x = rightStart.x;
  527. reg.hi.y = end.y;
  528. centerWidth = rightStart.x - start.x;
  529. if( centerWidth > 0)
  530. {
  531. TheDisplay->setClipRegion(&reg);
  532. end.x = start.x + centerImage->getImageWidth();
  533. TheWindowManager->winDrawImage( centerImage,
  534. start.x, start.y,
  535. end.x, end.y );
  536. TheDisplay->enableClipping(FALSE);
  537. }
  538. // draw left end
  539. start.x = origin.x + xOffset;
  540. start.y = origin.y + yOffset;
  541. end = leftEnd;
  542. TheWindowManager->winDrawImage(leftImage, start.x, start.y, end.x, end.y);
  543. // draw right end
  544. start = rightStart;
  545. end.x = start.x + rightSize.x;
  546. end.y = start.y + size.y;
  547. TheWindowManager->winDrawImage(rightImage, start.x, start.y, end.x, end.y);
  548. }
  549. // draw the button text
  550. if( instData->getTextLength() )
  551. drawButtonText( window, instData );
  552. // get window position
  553. window->winGetScreenPosition( &start.x, &start.y );
  554. window->winGetSize( &size.x, &size.y );
  555. // if we have a video buffer, draw the video buffer
  556. if ( instData->m_videoBuffer )
  557. {
  558. TheDisplay->drawVideoBuffer( instData->m_videoBuffer, start.x, start.y, start.x + size.x, start.y + size.y );
  559. }
  560. PushButtonData *pData = (PushButtonData *)window->winGetUserData();
  561. if( pData )
  562. {
  563. if( pData->overlayImage )
  564. {
  565. //Render the overlay image now.
  566. TheDisplay->drawImage( pData->overlayImage, origin.x, origin.y, origin.x + size.x, origin.y + size.y );
  567. }
  568. if( pData->drawClock )
  569. {
  570. if( pData->drawClock == NORMAL_CLOCK )
  571. {
  572. TheDisplay->drawRectClock(start.x, start.y, size.x, size.y, pData->percentClock,pData->colorClock);
  573. }
  574. else if( pData->drawClock == INVERSE_CLOCK )
  575. {
  576. TheDisplay->drawRemainingRectClock( start.x, start.y, size.x, size.y, pData->percentClock,pData->colorClock );
  577. }
  578. pData->drawClock = NO_CLOCK;
  579. window->winSetUserData(pData);
  580. }
  581. if( pData->drawBorder && pData->colorBorder != GAME_COLOR_UNDEFINED )
  582. {
  583. TheDisplay->drawOpenRect(start.x - 1, start.y - 1, size.x + 2, size.y + 2, 1, pData->colorBorder);
  584. }
  585. }
  586. }