buttonctrl.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. /*
  2. ** Command & Conquer Renegade(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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Combat *
  23. * *
  24. * $Archive:: /Commando/Code/wwui/buttonctrl.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 1/02/02 11:16a $*
  29. * *
  30. * $Revision:: 14 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. // Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
  36. #pragma warning(disable : 4530)
  37. #include "buttonctrl.h"
  38. #include "assetmgr.h"
  39. #include "font3d.h"
  40. #include "dialogbase.h"
  41. #include "mousemgr.h"
  42. #include "stylemgr.h"
  43. #include "dialogmgr.h"
  44. ////////////////////////////////////////////////////////////////
  45. // Local constants
  46. ////////////////////////////////////////////////////////////////
  47. static const RectClass BUTTON_UVS (96.0F, 51.0F, 217.0F, 84.0F);
  48. static const RectClass BUTTON_DN_UVS (96.0F, 92.0F, 217.0F, 125.0F);
  49. static const RectClass HILIGHT_UVS (117.0F, 4.0F, 220.0F, 41.0F);
  50. ////////////////////////////////////////////////////////////////
  51. //
  52. // ButtonCtrlClass
  53. //
  54. ////////////////////////////////////////////////////////////////
  55. ButtonCtrlClass::ButtonCtrlClass (void) :
  56. WasButtonPressedOnMe (false),
  57. IsMouseOverMe (false),
  58. PulseTime (0)
  59. {
  60. //
  61. // Set the font for the text renderer
  62. //
  63. StyleMgrClass::Assign_Font (&TextRenderer, StyleMgrClass::FONT_CONTROLS);
  64. StyleMgrClass::Assign_Font (&GlowRenderer, StyleMgrClass::FONT_CONTROLS);
  65. //
  66. // Configure the renderers
  67. //
  68. StyleMgrClass::Configure_Renderer (&ButtonRenderers[0]);
  69. StyleMgrClass::Configure_Renderer (&ButtonRenderers[1]);
  70. return ;
  71. }
  72. ////////////////////////////////////////////////////////////////
  73. //
  74. // Render
  75. //
  76. ////////////////////////////////////////////////////////////////
  77. void
  78. ButtonCtrlClass::Render (void)
  79. {
  80. //
  81. // Recreate the renderers (if necessary)
  82. //
  83. if (Is_Dirty ()) {
  84. Create_Text_Renderers ();
  85. //
  86. // Determine which type of button to create
  87. //
  88. if ((Get_Style () & BS_BITMAP) == 0) {
  89. Create_Component_Button ();
  90. } else {
  91. Create_Bitmap_Button ();
  92. }
  93. //Create_Vector_Button ();
  94. //Create_Bitmap_Button ();
  95. }
  96. if (WasButtonPressedOnMe && IsMouseOverMe) {
  97. //
  98. // Render the button "pressed"
  99. //
  100. ButtonRenderers[DOWN].Render ();
  101. ButtonRenderers[UP].Render ();
  102. } else {
  103. //
  104. // Render the button normally
  105. //
  106. ButtonRenderers[UP].Render ();
  107. }
  108. //
  109. // Render the text (only if its not a bitmap button)
  110. //
  111. if ((Get_Style () & BS_BITMAP) == 0) {
  112. if (HasFocus) {
  113. GlowRenderer.Render ();
  114. }
  115. TextRenderer.Render ();
  116. }
  117. DialogControlClass::Render ();
  118. return ;
  119. }
  120. ////////////////////////////////////////////////////////////////
  121. //
  122. // On_Create
  123. //
  124. ////////////////////////////////////////////////////////////////
  125. void
  126. ButtonCtrlClass::On_Create (void)
  127. {
  128. GlowRenderer.Build_Sentence (Title);
  129. return ;
  130. }
  131. ////////////////////////////////////////////////////////////////
  132. //
  133. // On_LButton_Down
  134. //
  135. ////////////////////////////////////////////////////////////////
  136. void
  137. ButtonCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
  138. {
  139. Set_Capture ();
  140. WasButtonPressedOnMe = true;
  141. //
  142. // Play the sound effect
  143. //
  144. StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MOUSE_CLICK);
  145. return ;
  146. }
  147. ////////////////////////////////////////////////////////////////
  148. //
  149. // On_LButton_Up
  150. //
  151. ////////////////////////////////////////////////////////////////
  152. void
  153. ButtonCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
  154. {
  155. Release_Capture ();
  156. IsMouseOverMe = Rect.Contains (mouse_pos);
  157. //
  158. // Notify the parent (if necessary)
  159. //
  160. if (WasButtonPressedOnMe && IsMouseOverMe) {
  161. Parent->On_Command (ID, BN_CLICKED, 0);
  162. }
  163. WasButtonPressedOnMe = false;
  164. return ;
  165. }
  166. ////////////////////////////////////////////////////////////////
  167. //
  168. // On_Mouse_Move
  169. //
  170. ////////////////////////////////////////////////////////////////
  171. void
  172. ButtonCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
  173. {
  174. IsMouseOverMe = Rect.Contains (mouse_pos);
  175. return ;
  176. }
  177. ////////////////////////////////////////////////////////////////
  178. //
  179. // Create_Vector_Button
  180. //
  181. ////////////////////////////////////////////////////////////////
  182. void
  183. ButtonCtrlClass::Create_Vector_Button (void)
  184. {
  185. ButtonRenderers[0].Reset ();
  186. ButtonRenderers[1].Reset ();
  187. ButtonRenderers[0].Enable_Texturing (false);
  188. ButtonRenderers[1].Enable_Texturing (false);
  189. //
  190. // Determine which color to draw the outline in
  191. //
  192. int color = StyleMgrClass::Get_Line_Color ();
  193. int bkcolor = StyleMgrClass::Get_Bk_Color ();
  194. if (IsEnabled == false) {
  195. color = StyleMgrClass::Get_Disabled_Line_Color ();
  196. bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
  197. } else if (HasFocus) {
  198. //bkcolor =
  199. }
  200. //
  201. // Draw the button outline
  202. //
  203. ButtonRenderers[0].Add_Outline (Rect, 1.0F, color);
  204. ButtonRenderers[1].Add_Outline (Rect, 1.0F, RGB_TO_INT32 (255, 0, 0));
  205. //
  206. // Draw the button center
  207. //
  208. RectClass rect = Rect;
  209. rect.Right -= 1;
  210. rect.Bottom -= 1;
  211. ButtonRenderers[0].Add_Quad (rect, bkcolor);
  212. ButtonRenderers[1].Add_Quad (rect, RGB_TO_INT32 (128, 0, 0));
  213. return ;
  214. }
  215. ////////////////////////////////////////////////////////////////
  216. //
  217. // Create_Bitmap_Button
  218. //
  219. ////////////////////////////////////////////////////////////////
  220. void
  221. ButtonCtrlClass::Create_Bitmap_Button (void)
  222. {
  223. //
  224. // Darken the bitmap if its disabled
  225. //
  226. int color = 0xFFFFFFFF;
  227. if (IsEnabled == false) {
  228. color = RGB_TO_INT32 (96, 96, 96);
  229. }
  230. ButtonRenderers[0].Reset ();
  231. ButtonRenderers[1].Reset ();
  232. ButtonRenderers[0].Add_Quad (Rect, color);
  233. ButtonRenderers[1].Add_Quad (Rect, color);
  234. //
  235. // Turn off texturing on the UI background
  236. //
  237. /*TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("if_circle02.tga", TextureClass::MIP_LEVELS_1);
  238. ButtonRenderers[0].Set_Texture (texture);
  239. ButtonRenderers[1].Set_Texture (texture);
  240. texture->Release_Ref();
  241. RectClass uv_rect1 = BUTTON_UVS;
  242. uv_rect1.Inverse_Scale (Vector2 (256.0F, 256.0F));
  243. ButtonRenderers[0].Add_Quad (Rect, uv_rect1);
  244. RectClass uv_rect2 = BUTTON_DN_UVS;
  245. uv_rect2.Inverse_Scale (Vector2 (256.0F, 256.0F));
  246. ButtonRenderers[1].Add_Quad (Rect, uv_rect2);
  247. ShaderClass *shader = ButtonRenderers[0].Get_Shader ();
  248. shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
  249. shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE);
  250. shader = ButtonRenderers[1].Get_Shader ();
  251. shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
  252. shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE); */
  253. return ;
  254. }
  255. ////////////////////////////////////////////////////////////////
  256. //
  257. // Blit_Section
  258. //
  259. ////////////////////////////////////////////////////////////////
  260. void
  261. Blit_Section
  262. (
  263. Render2DClass & renderer,
  264. const Vector2 & screen_pos,
  265. const Vector2 & texture_pos,
  266. const Vector2 & pixels,
  267. const Vector2 & texture_dimensions
  268. )
  269. {
  270. RectClass screen_rect;
  271. screen_rect.Left = screen_pos.X;
  272. screen_rect.Top = screen_pos.Y;
  273. screen_rect.Right = screen_rect.Left + pixels.X;
  274. screen_rect.Bottom = screen_rect.Top + pixels.Y;
  275. RectClass uv_rect (texture_pos.X, texture_pos.Y, texture_pos.X + pixels.X, texture_pos.Y + pixels.Y);
  276. uv_rect.Inverse_Scale (Vector2 (texture_dimensions.X, texture_dimensions.Y));
  277. renderer.Add_Quad (screen_rect, uv_rect);
  278. return ;
  279. }
  280. ////////////////////////////////////////////////////////////////
  281. //
  282. // Create_Component_Button
  283. //
  284. ////////////////////////////////////////////////////////////////
  285. void
  286. ButtonCtrlClass::Create_Component_Button (void)
  287. {
  288. ButtonRenderers[0].Reset ();
  289. ButtonRenderers[1].Reset ();
  290. //
  291. // Turn off texturing on the UI background
  292. //
  293. TextureClass *texture = WW3DAssetManager::Get_Instance ()->Get_Texture ("if_circle02.tga", TextureClass::MIP_LEVELS_1);
  294. ButtonRenderers[0].Set_Texture (texture);
  295. ButtonRenderers[1].Set_Texture (texture);
  296. texture->Release_Ref();
  297. float height = 10.0F;
  298. float edge_width = 10.0F;
  299. float top = BUTTON_UVS.Top;
  300. float left = BUTTON_UVS.Left;
  301. float right = BUTTON_UVS.Right;
  302. float bottom = BUTTON_UVS.Bottom;
  303. // float dn_start = bottom - height;
  304. //float horz_tile_width = 20.0F;
  305. //float vert_tile_height = 10.0F;
  306. Vector2 texture_dimensions (256.0F, 256.0F);
  307. //
  308. // Upper left
  309. //
  310. ::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, Rect.Top), Vector2 (left, top),
  311. Vector2 (edge_width, height), texture_dimensions);
  312. //
  313. // Upper right
  314. //
  315. ::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, Rect.Top), Vector2 (right - edge_width, top),
  316. Vector2 (edge_width, height), texture_dimensions);
  317. //
  318. // Lower left
  319. //
  320. ::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, Rect.Bottom - height), Vector2 (left, bottom - height),
  321. Vector2 (edge_width, height), texture_dimensions);
  322. //
  323. // Lower right
  324. //
  325. ::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, Rect.Bottom - height), Vector2 (right - edge_width, bottom - height),
  326. Vector2 (edge_width, height), texture_dimensions);
  327. Vector2 horz_top_pos (left + ((right-left) / 2) - 5, top);
  328. Vector2 horz_bottom_pos (left + ((right-left) / 2) - 5, bottom - height);
  329. Vector2 horz_size (10, height);
  330. //
  331. // Horizontal tile
  332. //
  333. float remaining_width = Rect.Width () - (edge_width * 2);
  334. float x_pos = Rect.Left + edge_width;
  335. while (remaining_width > 0) {
  336. horz_size.X = min (remaining_width, horz_size.X);
  337. ::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, Rect.Top), horz_top_pos,
  338. horz_size, texture_dimensions);
  339. ::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, Rect.Bottom - height), horz_bottom_pos,
  340. horz_size, texture_dimensions);
  341. x_pos += horz_size.X;
  342. remaining_width -= horz_size.X;
  343. }
  344. Vector2 vert_left_pos (left, top + ((bottom - top)/ 2) - 5);
  345. Vector2 vert_right_pos (right - edge_width, top + ((bottom - top)/ 2) - 5);
  346. Vector2 vert_size (edge_width, 10);
  347. //
  348. // Vertical tile
  349. //
  350. float remaining_height = Rect.Height () - (height * 2);
  351. float y_pos = Rect.Top + height;
  352. while (remaining_height > 0) {
  353. vert_size.Y = min (remaining_height, vert_size.Y);
  354. ::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Left, y_pos), vert_left_pos,
  355. vert_size, texture_dimensions);
  356. ::Blit_Section (ButtonRenderers[0], Vector2 (Rect.Right - edge_width, y_pos), vert_right_pos,
  357. vert_size, texture_dimensions);
  358. y_pos += vert_size.Y;
  359. remaining_height -= vert_size.Y;
  360. }
  361. RectClass hilight_rect = Rect;
  362. hilight_rect.Inflate (Vector2 (-((edge_width/2)+1), -((height/2)+1)));
  363. hilight_rect.Right += 1.0F;
  364. hilight_rect.Bottom += 1.0F;
  365. RectClass uv_rect = HILIGHT_UVS;
  366. uv_rect.Inverse_Scale (Vector2 (256.0F, 256.0F));
  367. ButtonRenderers[1].Add_Quad (hilight_rect, uv_rect);
  368. //
  369. // "Patch" fill the interior
  370. //
  371. /*y_pos = Rect.Top + height;
  372. remaining_height = Rect.Height () - (height * 2);
  373. while (remaining_height > 0) {
  374. x_pos = Rect.Left + edge_width;
  375. remaining_width = Rect.Width () - (edge_width * 2);
  376. while (remaining_width > 0) {
  377. Vector2 size (8, 8);
  378. size.X = min (remaining_width, size.X);
  379. size.Y = min (remaining_height, size.Y);
  380. ::Blit_Section (ButtonRenderers[0], Vector2 (x_pos, y_pos), Vector2 ((right / 2) - 4, (bottom / 2) - 4),
  381. size, texture_dimensions);
  382. ::Blit_Section (ButtonRenderers[1], Vector2 (x_pos, y_pos), Vector2 ((right / 2) - 4, dn_start + (bottom / 2) - 4),
  383. size, texture_dimensions);
  384. remaining_width -= 8;
  385. x_pos += 8;
  386. }
  387. remaining_height -= 8;
  388. y_pos += 8;
  389. }*/
  390. ShaderClass *shader = ButtonRenderers[0].Get_Shader ();
  391. shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
  392. shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE);
  393. shader = ButtonRenderers[1].Get_Shader ();
  394. shader->Set_Dst_Blend_Func (ShaderClass::DSTBLEND_ONE);
  395. shader->Set_Src_Blend_Func (ShaderClass::SRCBLEND_ONE);
  396. return ;
  397. }
  398. ////////////////////////////////////////////////////////////////
  399. //
  400. // Create_Component_Button2
  401. //
  402. ////////////////////////////////////////////////////////////////
  403. void
  404. ButtonCtrlClass::Create_Component_Button2 (void)
  405. {
  406. ButtonRenderers[0].Reset ();
  407. ButtonRenderers[1].Reset ();
  408. ButtonRenderers[0].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
  409. ButtonRenderers[1].Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
  410. //
  411. // Turn off texturing on the UI background
  412. //
  413. ButtonRenderers[0].Enable_Texturing (false);
  414. ButtonRenderers[1].Enable_Texturing (false);
  415. const int BLACK = VRGB_TO_INT32 (Vector3 (0, 0, 0));
  416. const int WHITE = VRGB_TO_INT32 (Vector3 (1, 1, 1));
  417. const int DK_GRAY = VRGB_TO_INT32 (Vector3 (0.5F, 0.5F, 0.5F));
  418. const int GRAY = VRGB_TO_INT32 (Vector3 (0.75F, 0.75F, 0.75F));
  419. const int LT_GRAY = VRGB_TO_INT32 (Vector3 (0.9F, 0.9F, 0.9F));
  420. //
  421. // Draw the outside button outline
  422. //
  423. RectClass rect = Rect;
  424. ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, WHITE);
  425. ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, WHITE);
  426. ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, BLACK);
  427. ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, BLACK);
  428. ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, BLACK);
  429. ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, BLACK);
  430. ButtonRenderers[1].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, WHITE);
  431. ButtonRenderers[1].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, WHITE);
  432. //
  433. // Draw the inside button outline
  434. //
  435. rect.Inflate (Vector2 (-1, -1));
  436. ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, LT_GRAY);
  437. ButtonRenderers[0].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, LT_GRAY);
  438. ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Top), Vector2 (rect.Right, rect.Bottom), 1, DK_GRAY);
  439. ButtonRenderers[0].Add_Line (Vector2 (rect.Right, rect.Bottom), Vector2 (rect.Left, rect.Bottom), 1, DK_GRAY);
  440. ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Bottom), Vector2 (rect.Left, rect.Top-1), 1, DK_GRAY);
  441. ButtonRenderers[1].Add_Line (Vector2 (rect.Left, rect.Top), Vector2 (rect.Right, rect.Top), 1, DK_GRAY);
  442. //
  443. // Fill the button center
  444. //
  445. rect.Right -= 1;
  446. rect.Bottom -= 1;
  447. ButtonRenderers[0].Add_Quad (rect, GRAY);
  448. ButtonRenderers[1].Add_Quad (rect, GRAY);
  449. return ;
  450. }
  451. ////////////////////////////////////////////////////////////////
  452. //
  453. // Create_Text_Renderers
  454. //
  455. ////////////////////////////////////////////////////////////////
  456. void
  457. ButtonCtrlClass::Create_Text_Renderers (void)
  458. {
  459. TextRenderer.Reset ();
  460. GlowRenderer.Reset_Polys ();
  461. //
  462. // Draw the text
  463. //
  464. StyleMgrClass::Render_Text (Title, &TextRenderer, Rect, true, true, StyleMgrClass::CENTER_JUSTIFY, IsEnabled);
  465. //
  466. // Draw the glow effect
  467. //
  468. StyleMgrClass::Render_Glow (Title, &GlowRenderer, Rect, 8, 8,
  469. StyleMgrClass::Get_Tab_Glow_Color (), StyleMgrClass::CENTER_JUSTIFY);
  470. return ;
  471. }
  472. ////////////////////////////////////////////////////////////////
  473. //
  474. // On_Set_Cursor
  475. //
  476. ////////////////////////////////////////////////////////////////
  477. void
  478. ButtonCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
  479. {
  480. //
  481. // Change the mouse cursor if necessary
  482. //
  483. if (ClientRect.Contains (mouse_pos)) {
  484. MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
  485. }
  486. return ;
  487. }
  488. ////////////////////////////////////////////////////////////////
  489. //
  490. // On_Frame_Update
  491. //
  492. ////////////////////////////////////////////////////////////////
  493. void
  494. ButtonCtrlClass::On_Frame_Update (void)
  495. {
  496. DialogControlClass::On_Frame_Update ();
  497. //
  498. // Get the current mouse position
  499. //
  500. Vector3 complete_mouse_pos = DialogMgrClass::Get_Mouse_Pos ();
  501. Vector2 mouse_pos;
  502. mouse_pos.X = complete_mouse_pos.X;
  503. mouse_pos.Y = complete_mouse_pos.Y;
  504. //
  505. // Update the pulse (as necessary)
  506. //
  507. if (ClientRect.Contains (mouse_pos)) {
  508. Update_Pulse (true);
  509. } else {
  510. Update_Pulse (false);
  511. }
  512. return ;
  513. }
  514. ////////////////////////////////////////////////////////////////
  515. //
  516. // On_Kill_Focus
  517. //
  518. ////////////////////////////////////////////////////////////////
  519. void
  520. ButtonCtrlClass::On_Kill_Focus (DialogControlClass *focus)
  521. {
  522. WasButtonPressedOnMe = false;
  523. IsMouseOverMe = false;
  524. DialogControlClass::On_Kill_Focus (focus);
  525. return ;
  526. }
  527. ////////////////////////////////////////////////////////////////
  528. //
  529. // On_Key_Down
  530. //
  531. ////////////////////////////////////////////////////////////////
  532. bool
  533. ButtonCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
  534. {
  535. switch (key_id)
  536. {
  537. case VK_RETURN:
  538. case VK_SPACE:
  539. Parent->On_Command (ID, BN_CLICKED, 0);
  540. //
  541. // Play the sound effect
  542. //
  543. StyleMgrClass::Play_Sound (StyleMgrClass::EVENT_MOUSE_CLICK);
  544. return true;
  545. break;
  546. }
  547. return false;
  548. }
  549. ////////////////////////////////////////////////////////////////
  550. //
  551. // Set_Bitmap
  552. //
  553. ////////////////////////////////////////////////////////////////
  554. void
  555. ButtonCtrlClass::Set_Bitmap (const char *texture_up_name, const char *texture_dn_name)
  556. {
  557. //
  558. // Configure the up bitmap
  559. //
  560. TextureClass *texture_up = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_up_name, TextureClass::MIP_LEVELS_1);
  561. ButtonRenderers[0].Set_Texture (texture_up);
  562. //
  563. // Configure the down bitmap
  564. //
  565. if (texture_dn_name != NULL && texture_dn_name[0] != 0) {
  566. TextureClass *texture_dn = WW3DAssetManager::Get_Instance ()->Get_Texture (texture_dn_name, TextureClass::MIP_LEVELS_1);
  567. ButtonRenderers[1].Set_Texture (texture_dn);
  568. REF_PTR_RELEASE (texture_dn);
  569. } else {
  570. ButtonRenderers[1].Set_Texture (texture_up);
  571. }
  572. REF_PTR_RELEASE (texture_up);
  573. //
  574. // Force the bitmap style on...
  575. //
  576. Style |= BS_BITMAP;
  577. return ;
  578. }
  579. ////////////////////////////////////////////////////////////////
  580. //
  581. // Update_Pulse
  582. //
  583. ////////////////////////////////////////////////////////////////
  584. void
  585. ButtonCtrlClass::Update_Pulse (bool is_mouse_over)
  586. {
  587. const int PULSE_LEN = 1000;
  588. int color;
  589. //
  590. // Short circuit if there's nothing to do
  591. //
  592. if (PulseTime == PULSE_LEN && is_mouse_over == false) {
  593. return ;
  594. }
  595. if (IsEnabled) {
  596. if (is_mouse_over) {
  597. //
  598. // Examine the current time to determine what
  599. // percent of the "pulse" we are at
  600. //
  601. PulseTime -= DialogMgrClass::Get_Frame_Time ();
  602. if (PulseTime < 0) {
  603. PulseTime += PULSE_LEN;
  604. }
  605. float percent = (float)PulseTime / (float)PULSE_LEN;
  606. //
  607. // Map the percent onto a circle to give us a pulse
  608. //
  609. float value = ::cos (DEG_TO_RADF (360.0F) * percent);
  610. value = 0.8F + (value * 0.2F);
  611. //
  612. // Convert this value into a grayscale color
  613. //
  614. color = VRGB_TO_INT32 (Vector3 (value, value, value));
  615. } else {
  616. color = RGB_TO_INT32 (0xff, 0xff, 0xff);
  617. PulseTime = PULSE_LEN;
  618. }
  619. } else {
  620. color = RGB_TO_INT32 (0x60, 0x60, 0x60);
  621. }
  622. //
  623. // Update the color vector arrays
  624. //
  625. DynamicVectorClass<unsigned long> &color_array = ButtonRenderers[0].Get_Color_Array ();
  626. for (int index = 0; index < color_array.Count (); index ++) {
  627. color_array[index] = color;
  628. }
  629. DynamicVectorClass<unsigned long> &color_array2 = ButtonRenderers[1].Get_Color_Array ();
  630. for (index = 0; index < color_array2.Count (); index ++) {
  631. color_array2[index] = color;
  632. }
  633. return ;
  634. }