W3DTextEntry.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  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: W3DTextEntry.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: W3DTextEntry.cpp
  36. //
  37. // Created: Colin Day, June 2001
  38. //
  39. // Desc: W3D implementation for the text entry gadget
  40. //
  41. //-----------------------------------------------------------------------------
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  44. #include <stdlib.h>
  45. // USER INCLUDES //////////////////////////////////////////////////////////////
  46. #include "GameClient/GameWindowGlobal.h"
  47. #include "GameClient/GadgetTextEntry.h"
  48. #include "GameClient/IMEManager.h"
  49. #include "W3DDevice/GameClient/W3DGadget.h"
  50. #include "W3DDevice/GameClient/W3DDisplay.h"
  51. #ifdef _INTERNAL
  52. // for occasional debugging...
  53. //#pragma optimize("", off)
  54. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  55. #endif
  56. // DEFINES ////////////////////////////////////////////////////////////////////
  57. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  58. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  59. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  60. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  63. ///////////////////////////////////////////////////////////////////////////////
  64. // drawTextEntryText ==========================================================
  65. //=============================================================================
  66. static void drawTextEntryText( GameWindow *window, WinInstanceData *instData,
  67. Color textColor, Color textDropColor,
  68. Color compositeColor, Color compositeDropColor,
  69. Int x, Int y, Int width, Int fontHeight )
  70. {
  71. static Byte drawCnt = 0;
  72. EntryData *e = (EntryData *)window->winGetUserData();
  73. // Int charPos = e->charPos;
  74. Int cursorPos;
  75. // WideChar buffer[ ENTRY_TEXT_LEN + 1 ];
  76. // WideChar *bufptr = buffer;
  77. // Color constructColor = TheWindowManager->winMakeColor( 192, 0, 192, 255 );
  78. DisplayString *text = e->text;
  79. IRegion2D clipRegion;
  80. ICoord2D origin, size;
  81. Int compositeCursorPos = 0;
  82. // Check to see if the IME manager is composing text
  83. e->constructText->setText(UnicodeString::TheEmptyString);
  84. if ( TheIMEManager && TheIMEManager->isAttachedTo( window) && TheIMEManager->isComposing())
  85. {
  86. // The user is composing a string.
  87. // Show the composition in the text gadget.
  88. UnicodeString composition;
  89. TheIMEManager->getCompositionString( composition );
  90. if ( e->secretText )
  91. {
  92. e->sText->setText( UnicodeString::TheEmptyString );
  93. Int len = composition.getLength() + e->text->getTextLength();
  94. for ( int i = 0; i < len; i++ )
  95. {
  96. e->sText->appendChar( '*' );
  97. }
  98. }
  99. else
  100. {
  101. e->constructText->setText( composition );
  102. compositeCursorPos = TheIMEManager->getCompositionCursorPosition();
  103. }
  104. }
  105. // get out of here if no text color to show up
  106. if( textColor == WIN_COLOR_UNDEFINED )
  107. return;
  108. // if our text is "secret" we will print only '*' characters
  109. if( e->secretText )
  110. text = e->sText;
  111. // make sure our font is the same as our parents
  112. if( text->getFont() != window->winGetFont() )
  113. text->setFont( window->winGetFont() );
  114. if( e->constructText->getFont() != window->winGetFont() )
  115. e->constructText->setFont( window->winGetFont() );
  116. // get the size of our text, and construct text
  117. Int textWidth = text->getWidth();
  118. if (!e->drawTextFromStart)
  119. {
  120. // clip the text to the edit window size
  121. window->winGetScreenPosition( &origin.x, &origin.y );
  122. window->winGetSize( &size.x, &size.y );
  123. clipRegion.lo.x = x;
  124. clipRegion.hi.x = x + width ;
  125. clipRegion.lo.y = y;
  126. clipRegion.hi.y = y + fontHeight;
  127. text->setClipRegion( &clipRegion );
  128. e->constructText->setClipRegion( &clipRegion );
  129. // set construct window position if needed
  130. //if( e->constructList && e->constructText->getTextLength() )
  131. // e->constructList->winSetPosition( (x + textWidth1), (y + fontHeight) );
  132. x+= 2;
  133. // draw the text
  134. if(textWidth < width)
  135. {
  136. text->draw( x, y, textColor, textDropColor );
  137. cursorPos = textWidth + x;
  138. }
  139. else
  140. {
  141. Int div = textWidth / (width / 2) - 1;
  142. text->draw(x - (div * (width/2)), y, textColor, textDropColor);
  143. cursorPos = textWidth - (div * (width/2)) + x;
  144. }
  145. //cursorPos = x + textWidth;
  146. }
  147. else
  148. {
  149. window->winGetScreenPosition( &origin.x, &origin.y );
  150. window->winGetSize( &size.x, &size.y );
  151. clipRegion.lo.x = origin.x;
  152. clipRegion.hi.x = origin.x + size.x;
  153. clipRegion.lo.y = origin.y;
  154. clipRegion.hi.y = origin.y + size.y;
  155. text->setClipRegion( &clipRegion );
  156. e->constructText->setClipRegion( &clipRegion );
  157. // set construct window position if needed
  158. //if( e->constructList && e->constructText->getTextLength() )
  159. // e->constructList->winSetPosition( (x + textWidth1), (y + fontHeight) );
  160. x+= 5;
  161. // draw the text
  162. text->draw( x, y, textColor, textDropColor );
  163. cursorPos = textWidth + x;
  164. }
  165. if (e->constructText->getTextLength() > 0 )
  166. {
  167. e->constructText->draw( x + textWidth, y, compositeColor, compositeDropColor );
  168. cursorPos += e->constructText->getWidth( compositeCursorPos );
  169. }
  170. // draw blinking cursor
  171. GameWindow *parent;
  172. parent = window->winGetParent();
  173. if(parent && !BitTest(parent->winGetStyle(), GWS_COMBO_BOX))
  174. parent = NULL;
  175. if( (window == TheWindowManager->winGetFocus() || (parent && parent == TheWindowManager->winGetFocus())) && ((drawCnt++ >> 3) & 0x1) )
  176. TheWindowManager->winFillRect( textColor, WIN_DRAW_LINE_WIDTH,
  177. cursorPos, origin.y + 3,
  178. cursorPos + 2, origin.y + size.y - 3 );
  179. window->winSetCursorPosition( cursorPos + 2 - origin.x, 0 );
  180. } // end drawTextEntryText
  181. ///////////////////////////////////////////////////////////////////////////////
  182. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  183. ///////////////////////////////////////////////////////////////////////////////
  184. // W3DGadgetTextEntryDraw =====================================================
  185. /** Draw colored entry field using standard graphics */
  186. //=============================================================================
  187. void W3DGadgetTextEntryDraw( GameWindow *window, WinInstanceData *instData )
  188. {
  189. EntryData *e = (EntryData *)window->winGetUserData();
  190. ICoord2D origin, size, start, end;
  191. Color backBorder, backColor, textColor, textBorder,
  192. compositeColor, compositeBorder;
  193. // cancel unichar flag
  194. e->receivedUnichar = FALSE;
  195. // get size and position of window
  196. window->winGetScreenPosition( &origin.x, &origin.y );
  197. window->winGetSize( &size.x, &size.y );
  198. // get the right colors
  199. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  200. {
  201. compositeColor = window->winGetDisabledTextColor();
  202. compositeBorder = window->winGetDisabledTextBorderColor();
  203. textColor = window->winGetDisabledTextColor();
  204. textBorder = window->winGetDisabledTextBorderColor();
  205. backColor = GadgetTextEntryGetDisabledColor( window );
  206. backBorder = GadgetTextEntryGetDisabledBorderColor( window );
  207. } // end if, disabled
  208. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  209. {
  210. compositeColor = window->winGetIMECompositeTextColor();
  211. compositeBorder = window->winGetIMECompositeBorderColor();
  212. textColor = window->winGetHiliteTextColor();
  213. textBorder = window->winGetHiliteTextBorderColor();
  214. backColor = GadgetTextEntryGetHiliteColor( window );
  215. backBorder = GadgetTextEntryGetHiliteBorderColor( window );
  216. } // end else if, hilited
  217. else
  218. {
  219. compositeColor = window->winGetIMECompositeTextColor();
  220. compositeBorder = window->winGetIMECompositeBorderColor();
  221. textColor = window->winGetEnabledTextColor();
  222. textBorder = window->winGetEnabledTextBorderColor();
  223. backColor = GadgetTextEntryGetEnabledColor( window );
  224. backBorder = GadgetTextEntryGetEnabledBorderColor( window );
  225. } // end else, just enabled
  226. // draw the back border
  227. if( backBorder != WIN_COLOR_UNDEFINED )
  228. {
  229. start.x = origin.x;
  230. start.y = origin.y;
  231. end.x = start.x + size.x;
  232. end.y = start.y + size.y;
  233. TheWindowManager->winOpenRect( backBorder, WIN_DRAW_LINE_WIDTH,
  234. start.x, start.y, end.x, end.y );
  235. } // end if
  236. // draw the filled back
  237. if( backColor != WIN_COLOR_UNDEFINED )
  238. {
  239. start.x = origin.x + 1;
  240. start.y = origin.y + 1;
  241. end.x = start.x + size.x - 2;
  242. end.y = start.y + size.y - 2;
  243. TheWindowManager->winFillRect( backColor, WIN_DRAW_LINE_WIDTH,
  244. start.x, start.y, end.x, end.y );
  245. } // end if
  246. // draw the text
  247. Int fontHeight = TheWindowManager->winFontHeight( instData->getFont() );
  248. Int startOffset = 5;
  249. Int width;
  250. width = size.x - (2 * startOffset);
  251. start.x = origin.x + startOffset; // offset a little bit into the entry
  252. if( BitTest( window->winGetStatus(), WIN_STATUS_ONE_LINE ) )
  253. start.y = size.y / 2 - fontHeight / 2;
  254. else
  255. start.y = origin.y + startOffset; // offset a little bit into the entry
  256. // draw the edit text
  257. drawTextEntryText( window, instData, textColor, textBorder, compositeColor, compositeBorder,
  258. start.x, start.y, width, fontHeight );
  259. } // end W3DGadgetTextEntryDraw
  260. // W3DGadgetTextEntryImageDraw ================================================
  261. /** Draw horizontal slider with user supplied images */
  262. //=============================================================================
  263. void W3DGadgetTextEntryImageDraw( GameWindow *window, WinInstanceData *instData )
  264. {
  265. EntryData *e = (EntryData *)window->winGetUserData();
  266. ICoord2D origin, size, start, end;
  267. Color textColor, textBorder;
  268. Color compositeColor, compositeBorder;
  269. const Image *leftImage, *rightImage, *centerImage, *smallCenterImage;
  270. Int xOffset, yOffset;
  271. Int i;
  272. // cancel unichar flag
  273. e->receivedUnichar = FALSE;
  274. // get size and position of window
  275. window->winGetScreenPosition( &origin.x, &origin.y );
  276. window->winGetSize( &size.x, &size.y );
  277. // get image offset
  278. xOffset = instData->m_imageOffset.x;
  279. yOffset = instData->m_imageOffset.y;
  280. // get the right colors
  281. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  282. {
  283. textColor = window->winGetDisabledTextColor();
  284. textBorder = window->winGetDisabledTextBorderColor();
  285. compositeColor = window->winGetDisabledTextColor();
  286. compositeBorder = window->winGetDisabledTextBorderColor();
  287. leftImage = GadgetTextEntryGetDisabledImageLeft( window );
  288. rightImage = GadgetTextEntryGetDisabledImageRight( window );
  289. centerImage = GadgetTextEntryGetDisabledImageCenter( window );
  290. smallCenterImage = GadgetTextEntryGetDisabledImageSmallCenter( window );
  291. } // end if, disabled
  292. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  293. {
  294. textColor = window->winGetHiliteTextColor();
  295. textBorder = window->winGetHiliteTextBorderColor();
  296. compositeColor = window->winGetIMECompositeTextColor();
  297. compositeBorder = window->winGetIMECompositeBorderColor();
  298. leftImage = GadgetTextEntryGetHiliteImageLeft( window );
  299. rightImage = GadgetTextEntryGetHiliteImageRight( window );
  300. centerImage = GadgetTextEntryGetHiliteImageCenter( window );
  301. smallCenterImage = GadgetTextEntryGetHiliteImageSmallCenter( window );
  302. } // end else if, hilited
  303. else
  304. {
  305. textColor = window->winGetEnabledTextColor();
  306. textBorder = window->winGetEnabledTextBorderColor();
  307. compositeColor = window->winGetIMECompositeTextColor();
  308. compositeBorder = window->winGetIMECompositeBorderColor();
  309. leftImage = GadgetTextEntryGetEnabledImageLeft( window );
  310. rightImage = GadgetTextEntryGetEnabledImageRight( window );
  311. centerImage = GadgetTextEntryGetEnabledImageCenter( window );
  312. smallCenterImage = GadgetTextEntryGetEnabledImageSmallCenter( window );
  313. } // end else, just enabled
  314. // get image sizes for the ends
  315. ICoord2D leftSize, rightSize;
  316. leftSize.x = leftImage->getImageWidth();
  317. leftSize.y = leftImage->getImageHeight();
  318. rightSize.x = rightImage->getImageWidth();
  319. rightSize.y = rightImage->getImageHeight();
  320. // get two key points used in the end drawing
  321. ICoord2D leftEnd, rightStart;
  322. leftEnd.x = origin.x + leftSize.x + xOffset;
  323. leftEnd.y = origin.y + size.y + yOffset;
  324. rightStart.x = origin.x + size.x - rightSize.x + xOffset;
  325. rightStart.y = origin.y + yOffset;
  326. // draw the center repeating bar
  327. Int centerWidth, pieces;
  328. // get width we have to draw our repeating center in
  329. centerWidth = rightStart.x - leftEnd.x;
  330. // how many whole repeating pieces will fit in that width
  331. pieces = centerWidth / centerImage->getImageWidth();
  332. // draw the pieces
  333. start.x = leftEnd.x;
  334. start.y = origin.y + yOffset;
  335. end.y = start.y + size.y;
  336. for( i = 0; i < pieces; i++ )
  337. {
  338. end.x = start.x + centerImage->getImageWidth();
  339. TheWindowManager->winDrawImage( centerImage,
  340. start.x, start.y,
  341. end.x, end.y );
  342. start.x += centerImage->getImageWidth();
  343. } // end for i
  344. //
  345. // how many small repeating pieces will fit in the gap from where the
  346. // center repeating bar stopped and the right image, draw them
  347. // and overlapping underneath where the right end will go
  348. //
  349. centerWidth = rightStart.x - start.x;
  350. pieces = centerWidth / smallCenterImage->getImageWidth() + 1;
  351. end.y = start.y + size.y;
  352. for( i = 0; i < pieces; i++ )
  353. {
  354. end.x = start.x + smallCenterImage->getImageWidth();
  355. TheWindowManager->winDrawImage( smallCenterImage,
  356. start.x, start.y,
  357. end.x, end.y );
  358. start.x += smallCenterImage->getImageWidth();
  359. } // end for i
  360. // draw left end
  361. start.x = origin.x + xOffset;
  362. start.y = origin.y + yOffset;
  363. end = leftEnd;
  364. TheWindowManager->winDrawImage(leftImage, start.x, start.y, end.x, end.y);
  365. // draw right end
  366. start = rightStart;
  367. end.x = start.x + rightSize.x;
  368. end.y = start.y + size.y;
  369. TheWindowManager->winDrawImage(rightImage, start.x, start.y, end.x, end.y);
  370. // draw the text
  371. Int fontHeight = TheWindowManager->winFontHeight( instData->getFont() );
  372. Int startOffset = 5;
  373. Int width;
  374. width = size.x - (2 * startOffset);
  375. start.x = origin.x + startOffset; // offset a little bit into the entry
  376. if( BitTest( window->winGetStatus(), WIN_STATUS_ONE_LINE ) )
  377. start.y = size.y / 2 - fontHeight / 2;
  378. else
  379. start.y = origin.y + startOffset; // offset a little bit into the entry
  380. // draw the edit text
  381. drawTextEntryText( window, instData, textColor, textBorder, compositeColor, compositeBorder,
  382. start.x, start.y, width, fontHeight );
  383. } // end W3DGadgetTextEntryImageDraw