MsgBox.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. //
  20. // MsgBox.CPP
  21. //
  22. // History:
  23. // 08/20/96 JMI Started.
  24. //
  25. // 08/21/96 JMI Updated to make new lib.
  26. //
  27. // 09/24/96 JMI Now uses CGuiItem::GetTopLeftBorderThickness() and
  28. // CGuiItem::GetBottomRightBorderThickness() instead of
  29. // old CGuiItem::GetTotalBorderThickness().
  30. //
  31. // 10/01/96 JMI DrawDirty() now uses rsp[Un]ShieldCursor(). DoModal()
  32. // was always overwriting m_ulId by when callbacks were
  33. // used..fixed. DoModal() no longer calls GetNext(phot).
  34. // It now calls GetNext() with no args.
  35. //
  36. // 10/03/96 JMI Added DoModeless() to handle simple non-modal dirty
  37. // work.
  38. //
  39. // 10/31/96 JMI Changed:
  40. // Old label: New label:
  41. // ========= =========
  42. // CMsgBox RMsgBox
  43. // CImage RImage
  44. // CDirtyRect RDirtyRects <-- Yes. Now plural.
  45. // DRECT RDRect
  46. // PDRECT RDRect*
  47. // CHot RHot
  48. // CList RList
  49. // BMP8 RImage::BMP8
  50. // CGuiItem RGuiItem
  51. // CTxt RTxt
  52. // CBtn RBtn
  53. // CDlg RDlg
  54. // CEdit REdit
  55. //
  56. // 11/01/96 JMI Also, changed all members referenced in RImage to
  57. // m_ and all position/dimension members referenced in
  58. // RImage to type short usage.
  59. //
  60. // 11/12/96 JMI Changed GKF_SHIFT to RSP_GKF_SHIFT.
  61. //
  62. // 11/14/96 JMI Now adds some additional width to Edits when added
  63. // with AddEdit() so they can fit their caret with their
  64. // text.
  65. //
  66. // 11/15/96 JMI Now provides a clip rect when getting new erase data
  67. // for the dialog and when sets the m_sClipX/Y members of
  68. // RDirtyRects in DoModal().
  69. //
  70. // 12/04/96 JMI DoModless() and, consequently, DoModal() now take a
  71. // pointer to an rspGetKey() formmatted key that is passed
  72. // to REdits, if they have the focus. Also, now moves
  73. // focus through the gui items even if an edit field is not
  74. // active.
  75. // Now initializes RRects using new syntax.
  76. //
  77. // 12/16/96 JMI Focus is can now be specific to any type.
  78. //
  79. // 12/19/96 JMI Upgraded to new RFont/RPrint.
  80. //
  81. // 12/19/96 JMI In CopyParms(), I was getting the height from the wrong
  82. // m_pprint (was using the one in pgui, instead of 'this').
  83. //
  84. // 12/31/96 JMI Reduced focus support such that it mostly utilized that
  85. // in RGuiItem, but preserved RMsgBox.SetFocus() so it could
  86. // steal the focus from an REdit. Note that this would be
  87. // a good opportunity for a OnLoseFocus() virtual func so
  88. // that REdit could handle this itself.
  89. //
  90. // 12/31/96 JMI Removed RMsgBox.SetFocus() since REdit now handles its
  91. // own garbage in REdit.OnLoseFocus().
  92. //
  93. // 01/18/97 JMI NOTE! HIGHLY TEMP FIX: Commented out calls to Do() with
  94. // a long*. Now Do() takes an RInputEvent*. RMsgBox should
  95. // be changed to taking this as a parm instead of lKey as
  96. // well. The reason I don't just go ahead and do it is b/c
  97. // I'm not sure if this API is worth keeping since it is
  98. // currently unused and is mostly obsoleted by new abilites
  99. // in RGuiItem (e.g., Load(), LoadInstantiate(),
  100. // Focus/NextPrev(), DoFocus(), etc.).
  101. //
  102. // 01/19/97 JMI This is actually used by the Menu API, so I upated it.
  103. // Converted Do*() to taking an RInputEvent* instead of a
  104. // long*.
  105. //
  106. // 01/23/97 JMI Now calls m_hot.Do() directly and does not need to
  107. // deactivate other hotboxes.
  108. //
  109. // 04/11/97 JMI Now uses m_sFontCellHeight instead of GetPos() to
  110. // determine cell height.
  111. //
  112. // 04/24/97 JMI Add additional parms to Add*() to add extra size to a
  113. // GUI.
  114. //
  115. // 04/24/97 JMI CopyParms() now copies new m_u32TextShadowColor parm.
  116. //
  117. //////////////////////////////////////////////////////////////////////////////
  118. //
  119. // This a GUI item that is based on CDlg derived from the basic RGuiItem.
  120. // This utilizes the m_ulUserData, m_ulUserInstance, and m_bcUser fields. If
  121. // you use any of these fields for other purposes MAKE SURE that m_bcUser is
  122. // set to NULL or any other callback besides ItemBtnUpCall!!!!!!!!!!
  123. //
  124. // If you do m_mbcUser is NULL, DoModal() will call rspDoSystem(), RHot::Do(),
  125. // and this->Do(). If m_mbcUser is not NULL, NONE OF THESE WILL BE CALLED.
  126. // You must call whatever is necessary for the CMsgBox to work with your
  127. // scenario. Usually this will be the 3 functions listed above and whatever
  128. // others you feel like calling (e.g., rspDoSound()).
  129. //
  130. // Order matters!:
  131. // When you use AddButton, AddText, or AddEdit parameters (including colors,
  132. // border thickness, font, DRAWCALL, BACKCALL, etc.) are copied from this CMsgBox{CDlg}. If you
  133. // change the settings in CMsgBox after calling one of these functions,
  134. // the created GUI item will differ by those settings.
  135. //
  136. // Enhancements/Uses:
  137. // You could derive from this. /shrug
  138. //
  139. //////////////////////////////////////////////////////////////////////////////
  140. //////////////////////////////////////////////////////////////////////////////
  141. // C Headers.
  142. //////////////////////////////////////////////////////////////////////////////
  143. #include <string.h>
  144. //////////////////////////////////////////////////////////////////////////////
  145. // RSPiX Headers.
  146. //////////////////////////////////////////////////////////////////////////////
  147. #include "Blue.h"
  148. #ifdef PATHS_IN_INCLUDES
  149. #include "ORANGE/MsgBox/MsgBox.h"
  150. #include "ORANGE/DirtRect/DirtRect.h"
  151. #include "ORANGE/GUI/scrollbar.h"
  152. #else
  153. #include "MsgBox.h"
  154. #include "dirtrect.h"
  155. #include "scrollbar.h"
  156. #endif // PATHS_IN_INCLUDES
  157. //////////////////////////////////////////////////////////////////////////////
  158. // Module specific macros.
  159. //////////////////////////////////////////////////////////////////////////////
  160. // Sets val to def if val is -1.
  161. #define DEF(val, def) ((val == -1) ? def : val)
  162. //////////////////////////////////////////////////////////////////////////////
  163. // Module specific typedefs.
  164. //////////////////////////////////////////////////////////////////////////////
  165. //////////////////////////////////////////////////////////////////////////////
  166. // Module specific (static) variables.
  167. //////////////////////////////////////////////////////////////////////////////
  168. //////////////////////////////////////////////////////////////////////////////
  169. // Construction/Destruction.
  170. //////////////////////////////////////////////////////////////////////////////
  171. //////////////////////////////////////////////////////////////////////////////
  172. //
  173. // Default constructor.
  174. //
  175. //////////////////////////////////////////////////////////////////////////////
  176. RMsgBox::RMsgBox()
  177. {
  178. // Assume no button up callback.
  179. m_mbcUser = NULL;
  180. // Active when visible.
  181. m_sActive = TRUE;
  182. // No current clickage.
  183. m_ulId = 0;
  184. }
  185. //////////////////////////////////////////////////////////////////////////////
  186. //
  187. // Destructor.
  188. //
  189. //////////////////////////////////////////////////////////////////////////////
  190. RMsgBox::~RMsgBox()
  191. {
  192. // Clean up.
  193. RemoveAll();
  194. }
  195. ////////////////////////////////////////////////////////////////////////
  196. // Methods.
  197. ////////////////////////////////////////////////////////////////////////
  198. ////////////////////////////////////////////////////////////////////////
  199. //
  200. // Add a btn with provided text at sX, sY in RMsgBox dlg.
  201. //
  202. ////////////////////////////////////////////////////////////////////////
  203. RBtn* RMsgBox::AddButton( // Returns allocated GUI item on success.
  204. // Do NOT delete this item; it will be deleted
  205. // by a RemoveAll() call.
  206. char* pszText, // Text for btn item.
  207. short sX, // X position in RMsgBox dlg.
  208. short sY, // Y position in RMsgBox dlg.
  209. ULONG ulId, // ID to return if this item is chosen.
  210. // There will be no response to this item
  211. // if lId is 0.
  212. short sAddW /*= 0*/, // Additional width for guis that require more.
  213. short sAddH /*= 0*/) // Additional height for guis that require more.
  214. {
  215. short sError = 0;
  216. // Attempt to allocate new btn.
  217. RBtn* pbtn = new RBtn;
  218. if (pbtn != NULL)
  219. {
  220. if (AddItem(pbtn, pszText, sX, sY, ulId, sAddW, sAddH) == 0)
  221. {
  222. // Success.
  223. }
  224. else
  225. {
  226. TRACE("AddButton(): AddItem() failed for allocated RBtn.\n");
  227. sError = 2;
  228. }
  229. // If any errors occurred after allocation . . .
  230. if (sError != 0)
  231. {
  232. delete pbtn;
  233. pbtn = NULL;
  234. }
  235. }
  236. else
  237. {
  238. TRACE("AddButton(): Failed to allocate RBtn.\n");
  239. sError = 1;
  240. }
  241. return pbtn;
  242. }
  243. ////////////////////////////////////////////////////////////////////////
  244. //
  245. // Add a txt item with provided text at sX, sY in RMsgBox dlg.
  246. //
  247. ////////////////////////////////////////////////////////////////////////
  248. RTxt* RMsgBox::AddText( // Returns allocated GUI item on success.
  249. // Do NOT delete this item; it will be deleted
  250. // by a RemoveAll() call.
  251. char* pszText, // Text for txt item.
  252. short sX, // X position in RMsgBox dlg.
  253. short sY, // Y position in RMsgBox dlg.
  254. ULONG ulId, // ID to return if this item is chosen.
  255. // There will be no response to this item
  256. // if lId is 0.
  257. short sAddW /*= 0*/, // Additional width for guis that require more.
  258. short sAddH /*= 0*/) // Additional height for guis that require more.
  259. {
  260. short sError = 0;
  261. // Attempt to allocate new btn.
  262. RTxt* ptxt = new RTxt;
  263. if (ptxt != NULL)
  264. {
  265. if (AddItem(ptxt, pszText, sX, sY, ulId, sAddW, sAddH) == 0)
  266. {
  267. // Success.
  268. }
  269. else
  270. {
  271. TRACE("AddText(): AddItem() failed for allocated RTxt.\n");
  272. sError = 2;
  273. }
  274. // If any errors occurred after allocation . . .
  275. if (sError != 0)
  276. {
  277. delete ptxt;
  278. ptxt = NULL;
  279. }
  280. }
  281. else
  282. {
  283. TRACE("AddText(): Failed to allocate RTxt.\n");
  284. sError = 1;
  285. }
  286. return ptxt;
  287. }
  288. ////////////////////////////////////////////////////////////////////////
  289. //
  290. // Add an edit field with provided text at sX, sY in RMsgBox dlg.
  291. //
  292. ////////////////////////////////////////////////////////////////////////
  293. REdit* RMsgBox::AddEdit( // Returns allocated GUI item on success.
  294. // Do NOT delete this item; it will be deleted
  295. // by a RemoveAll() call.
  296. char* pszText, // Text for edit item.
  297. short sX, // X position in RMsgBox dlg.
  298. short sY, // Y position in RMsgBox dlg.
  299. ULONG ulId, // ID to return if this item is chosen.
  300. // There will be no response to this item
  301. // if lId is 0.
  302. short sAddW /*= 0*/, // Additional width for guis that require more.
  303. short sAddH /*= 0*/) // Additional height for guis that require more.
  304. {
  305. short sError = 0;
  306. // Attempt to allocate new btn.
  307. REdit* pedit = new REdit;
  308. if (pedit != NULL)
  309. {
  310. // Need to create string so we can determine size of caret.
  311. char szCaret[] = { pedit->m_cCaretChar, '\0' };
  312. // Store text width.
  313. short sTextWidth = pedit->m_pprint->GetWidth(szCaret);
  314. if (AddItem(pedit, pszText, sX, sY, ulId, sTextWidth + sAddW, sAddH) == 0)
  315. {
  316. // Limit text to the number of characters originally used.
  317. // pedit->m_sMaxText = strlen(pszText);
  318. // Success.
  319. }
  320. else
  321. {
  322. TRACE("AddEdit(): AddItem() failed for allocated REdit.\n");
  323. sError = 2;
  324. }
  325. // If any errors occurred after allocation . . .
  326. if (sError != 0)
  327. {
  328. delete pedit;
  329. pedit = NULL;
  330. }
  331. }
  332. else
  333. {
  334. TRACE("AddEdit(): Failed to allocate REdit.\n");
  335. sError = 1;
  336. }
  337. return pedit;
  338. }
  339. ////////////////////////////////////////////////////////////////////////
  340. //
  341. // Add the RGuiItem of your choice. pgui->m_ulUserData will be returned
  342. // by DoModal() if this item is chosen.
  343. //
  344. ////////////////////////////////////////////////////////////////////////
  345. RGuiItem* RMsgBox::AddItem( // Returns pgui on success.
  346. RGuiItem* pgui) // The RGuiItem to add (its m_sX/Y should
  347. // already have been set).
  348. {
  349. // Store RMsgBox instance.
  350. pgui->m_ulUserInstance = (ULONG)this;
  351. // Let RGuiItem know where to call.
  352. pgui->m_bcUser = ItemBtnUpCall;
  353. // Simply sets this RGuiItem as a child of this RMsgBox{RDlg}.
  354. pgui->SetParent(this);
  355. return pgui;
  356. }
  357. ////////////////////////////////////////////////////////////////////////
  358. //
  359. // Draw dirty areas if not going direct to screen and
  360. // remove rects from drl.
  361. //
  362. ////////////////////////////////////////////////////////////////////////
  363. inline void DrawDirty( // Returns nothing.
  364. RImage* pimComp, // Composite buffer.
  365. RImage* pimScr, // Screen buffer.
  366. RDirtyRects* pdrl) // List of dirty rects.
  367. {
  368. RDRect* pdr;
  369. // If not going direct to screen . . .
  370. if (pimComp != pimScr)
  371. {
  372. rspShieldMouseCursor();
  373. pdr = pdrl->GetHead();
  374. while (pdr != NULL)
  375. {
  376. // Update screen.
  377. rspBlit( pimComp, pimScr,
  378. pdr->sX, pdr->sY,
  379. pdr->sX, pdr->sY,
  380. pdr->sW, pdr->sH);
  381. pdrl->Remove();
  382. delete pdr;
  383. pdr = pdrl->GetNext();
  384. }
  385. rspUnshieldMouseCursor();
  386. }
  387. }
  388. ////////////////////////////////////////////////////////////////////////
  389. //
  390. // Operates RMsgBox for one iteration. Does NOT Draw().
  391. // Check m_pguiFocus to determine RGuiItem with focus.
  392. //
  393. ////////////////////////////////////////////////////////////////////////
  394. ULONG RMsgBox::DoModeless( // Returns item clicked or 0, if none.
  395. RInputEvent* pie) // In: Most recent user input event.
  396. // Out: pie->sUsed = TRUE, if used.
  397. {
  398. // If there is a user callback . . .
  399. if (m_mbcUser != NULL)
  400. {
  401. // Allow the user to call stuff.
  402. ULONG ulRes = (*m_mbcUser)(this);
  403. // If the user returned a non-zero value . . .
  404. if (ulRes != 0)
  405. {
  406. // Override ours.
  407. m_ulId = ulRes;
  408. }
  409. }
  410. else
  411. {
  412. // Provide minimum system callage.
  413. rspDoSystem();
  414. m_hot.Do(pie);
  415. }
  416. RGuiItem::DoFocus(pie);
  417. ULONG ulResId = m_ulId;
  418. // Reset.
  419. m_ulId = 0;
  420. return ulResId;
  421. }
  422. ////////////////////////////////////////////////////////////////////////
  423. //
  424. // Activates this RMsgBox and waits for input until m_mbcUser returns
  425. // non-zero or an item is clicked. If sDeactivateHots is TRUE, all
  426. // RHots are deactivated before activating GUI items. These RHots are
  427. // reactivated before exitting DoModal().
  428. //
  429. ////////////////////////////////////////////////////////////////////////
  430. ULONG RMsgBox::DoModal( // Returns chosen ID on success,
  431. // 0 on failure.
  432. RInputEvent* pie, // In: Most recent user input event.
  433. // Out: pie->sUsed = TRUE, if used.
  434. RImage* pimDst /*= NULL*/) // Where to draw dialog and rspBlit from.
  435. // If this is NULL, the system buffer is
  436. // used.
  437. // rspBlit is used to update this to the
  438. // screen image unless pimDst is the screen
  439. // image.
  440. {
  441. m_ulId = 0; // ID to return.
  442. short sError = 0; // No errors yet.
  443. // Deactivate RHots, adding them to our list.
  444. // We now can just service our own RHots.
  445. RImage* pimScr;
  446. // If composition buffer provided . . .
  447. if (pimDst != NULL)
  448. {
  449. rspNameBuffers(NULL, &pimScr, NULL);
  450. }
  451. else // No composition buffer provided.
  452. {
  453. rspNameBuffers(&pimDst, &pimScr, NULL);
  454. }
  455. // Allocate eraser . . .
  456. RImage imEraser;
  457. if (imEraser.CreateImage(
  458. m_im.m_sWidth,
  459. m_im.m_sHeight,
  460. RImage::BMP8,
  461. 0,
  462. m_im.m_sDepth) == 0)
  463. {
  464. }
  465. else
  466. {
  467. TRACE("DoModal(): m_imEraser.CreateImage() failed.\n");
  468. sError = 1;
  469. }
  470. // Activate this and all children.
  471. SetVisible(TRUE);
  472. RDRect dr = { m_sX, m_sY, m_im.m_sWidth, m_im.m_sHeight };
  473. RDirtyRects drl;
  474. drl.m_sClipX = pimDst->m_sWidth - 1;
  475. drl.m_sClipY = pimDst->m_sHeight - 1;
  476. // Clipping rectangle for composite buffer.
  477. RRect rcCompositeClip(0, 0, drl.m_sClipX, drl.m_sClipY);
  478. // Main loop:
  479. // Wait for an error or an ID.
  480. while (m_ulId == 0 && sError == 0)
  481. {
  482. dr.sX = m_sX;
  483. dr.sY = m_sY;
  484. // Get new erase data.
  485. rspBlit( pimDst, &imEraser,
  486. dr.sX, dr.sY,
  487. 0, 0,
  488. dr.sW, dr.sH,
  489. NULL, // Destination clippage.
  490. &rcCompositeClip); // Source clippage.
  491. // Draw new dlg data.
  492. Draw(pimDst, 0, 0, 0, 0, 0, 0, &rcCompositeClip);
  493. // Add to dirty rect list. Most likely will combine.
  494. drl.Add(&dr);
  495. // Draw dirty areas if not going direct to screen and
  496. // remove rects from drl.
  497. DrawDirty(pimDst, pimScr, &drl);
  498. // Do GUI maintainence.
  499. ULONG ulRes = DoModeless(pie);
  500. if (ulRes != 0)
  501. {
  502. // Override ours.
  503. m_ulId = ulRes;
  504. }
  505. // Erase old.
  506. rspBlit( &imEraser, pimDst, 0, 0,
  507. dr.sX, dr.sY,
  508. dr.sW, dr.sH);
  509. // Add to dirty rect list.
  510. drl.Add(&dr);
  511. }
  512. // Erase.
  513. DrawDirty(pimDst, pimScr, &drl);
  514. // Free up any memory no longer needed.
  515. imEraser.DestroyData();
  516. // Deactivate this and all children.
  517. SetVisible(FALSE);
  518. return m_ulId;
  519. }
  520. ////////////////////////////////////////////////////////////////////////
  521. //
  522. // Destroys all allocated items (i.e., items NOT added with
  523. // AddItem(...) (i.e., items allocated by RMsgBox)).
  524. //
  525. ////////////////////////////////////////////////////////////////////////
  526. void RMsgBox::RemoveAll(void) // Returns nothing.
  527. {
  528. RGuiItem* pgui = m_listGuis.GetHead();
  529. while (pgui != NULL)
  530. {
  531. m_listGuis.Remove();
  532. delete pgui;
  533. pgui = m_listGuis.GetNext();
  534. }
  535. }
  536. ////////////////////////////////////////////////////////////////////////
  537. // Querries.
  538. ////////////////////////////////////////////////////////////////////////
  539. ////////////////////////////////////////////////////////////////////////
  540. // Callback points (Non-Static).
  541. ////////////////////////////////////////////////////////////////////////
  542. ////////////////////////////////////////////////////////////////////////
  543. // Callback points (Static).
  544. ////////////////////////////////////////////////////////////////////////
  545. ////////////////////////////////////////////////////////////////////////
  546. //
  547. // Called by child items to let us know when they are clicked in.
  548. // (static)
  549. //
  550. ////////////////////////////////////////////////////////////////////////
  551. void RMsgBox::ItemBtnUpCall(RGuiItem* pgui)
  552. {
  553. ASSERT(pgui->m_ulUserInstance != NULL);
  554. RMsgBox* pmb = (RMsgBox*)(pgui->m_ulUserInstance);
  555. // Store item ID.
  556. pmb->m_ulId = pgui->m_ulUserData;
  557. // Set focus to.
  558. pmb->SetFocus(pgui);
  559. }
  560. ////////////////////////////////////////////////////////////////////////
  561. // Internal.
  562. ////////////////////////////////////////////////////////////////////////
  563. ////////////////////////////////////////////////////////////////////////
  564. //
  565. // Add a GUI item already allocated by this RMsgBox.
  566. //
  567. ////////////////////////////////////////////////////////////////////////
  568. short RMsgBox::AddItem( // Returns 0 on success.
  569. RGuiItem* pgui, // Item to add.
  570. char* pszText, // Text for item.
  571. short sX, // X position in RMsgBox dlg.
  572. short sY, // Y position in RMsgBox dlg.
  573. ULONG ulId, // ID to return if this item is chosen.
  574. // There will be no response to this item
  575. // if lId is 0.
  576. short sAddW /*= 0*/, // Additional width for guis that require more.
  577. short sAddH /*= 0*/) // Additional height for guis that require more.
  578. {
  579. short sRes = 0; // Assume success.
  580. // Copy settings.
  581. CopyParms(pgui);
  582. // Store ID.
  583. pgui->m_ulUserData = ulId;
  584. // Set text.
  585. pgui->SetText(pszText);
  586. // Store text width.
  587. short sTextWidth = pgui->m_pprint->GetWidth(pszText);
  588. // Active when visible.
  589. pgui->m_sActive = TRUE;
  590. // Set font height for item.
  591. pgui->m_sFontCellHeight = m_sFontCellHeight;
  592. // Reserve space for borders, if there are any.
  593. short sTotalBorderThickness = pgui->GetTopLeftBorderThickness()
  594. + pgui->GetBottomRightBorderThickness();
  595. // Create to font/text appropriate size . . .
  596. if (pgui->Create( sX, sY,
  597. sTextWidth + sTotalBorderThickness + sAddW,
  598. m_sFontCellHeight + sTotalBorderThickness + sAddH,
  599. m_im.m_sDepth)
  600. == 0)
  601. {
  602. // Add item (i.e., set parent to us) . . .
  603. if (AddItem(pgui) != NULL)
  604. {
  605. // Add to our list of items to be deallocated later . . .
  606. if (m_listGuis.Add(pgui) == 0)
  607. {
  608. // Success.
  609. }
  610. else
  611. {
  612. TRACE("AddItem(): Failed to add item to list.\n");
  613. sRes = -3;
  614. }
  615. }
  616. else
  617. {
  618. TRACE("AddItem(): AddItem() failed for allocated item.\n");
  619. sRes = -2;
  620. }
  621. }
  622. else
  623. {
  624. TRACE("AddItem(): [RGuiItem::]Create failed.\n");
  625. sRes = -1;
  626. }
  627. return sRes;
  628. }
  629. ////////////////////////////////////////////////////////////////////////
  630. //
  631. // Copies parameters from RMsgBox into *pgui.
  632. //
  633. ////////////////////////////////////////////////////////////////////////
  634. void RMsgBox::CopyParms(RGuiItem* pgui)
  635. {
  636. pgui->m_drawcall = m_drawcall;
  637. pgui->m_backcall = m_backcall;
  638. pgui->m_u32BorderColor = m_u32BorderColor;
  639. pgui->m_u32BorderShadowColor = m_u32BorderShadowColor;
  640. pgui->m_u32BorderHighlightColor = m_u32BorderHighlightColor;
  641. pgui->m_u32BorderEdgeColor = m_u32BorderEdgeColor;
  642. pgui->m_u32TextColor = m_u32TextColor;
  643. pgui->m_u32BackColor = m_u32BackColor;
  644. pgui->m_u32TextShadowColor = m_u32TextShadowColor;
  645. pgui->m_sBorderThickness = m_sBorderThickness;
  646. // Use this to copy font stuff instead of stuff below:
  647. pgui->m_pprint = m_pprint;
  648. }
  649. //////////////////////////////////////////////////////////////////////////////
  650. // EOF
  651. //////////////////////////////////////////////////////////////////////////////