controls.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681
  1. #include "pch.h"
  2. /////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Justify Pane
  5. //
  6. /////////////////////////////////////////////////////////////////////////////
  7. JustifyPane::JustifyPane(int layout, const WinPoint& size, Pane* pchild) :
  8. Pane(pchild),
  9. m_bigSize(size),
  10. m_layout(layout)
  11. {
  12. }
  13. void JustifyPane::UpdateLayout()
  14. {
  15. if (Child()) {
  16. InternalSetSize(
  17. WinPoint(
  18. max(XExpand(), m_bigSize.X()),
  19. max(YExpand(), m_bigSize.Y())
  20. )
  21. );
  22. InternalSetExpand(Child(), GetSize());
  23. Child()->UpdateLayout();
  24. InternalSetSize(WinPoint(
  25. max(XSize(), Child()->XSize()),
  26. max(YSize(), Child()->YSize())
  27. ));
  28. int dx = XSize() - Child()->XSize();
  29. int dy = YSize() - Child()->YSize();
  30. InternalSetOffset(
  31. Child(),
  32. WinPoint(
  33. m_layout & Left ? 0 : (m_layout & Right ? dx : dx / 2),
  34. m_layout & Top ? 0 : (m_layout & Bottom ? dy : dy / 2)
  35. )
  36. );
  37. } else {
  38. InternalSetSize(
  39. WinPoint(
  40. max(XExpand(), m_bigSize.X()),
  41. max(YExpand(), m_bigSize.Y())
  42. ));
  43. }
  44. }
  45. /////////////////////////////////////////////////////////////////////////////
  46. //
  47. // Fill Pane
  48. //
  49. /////////////////////////////////////////////////////////////////////////////
  50. FillPane::FillPane(const WinPoint& sizeMin, const Color& color) :
  51. m_sizeMin(sizeMin),
  52. m_color(color)
  53. {
  54. SetOpaque(true);
  55. }
  56. void FillPane::SetColor(const Color& color)
  57. {
  58. m_color = color;
  59. NeedPaint();
  60. }
  61. void FillPane::UpdateLayout()
  62. {
  63. InternalSetSize(
  64. WinPoint(
  65. max(m_sizeMin.X(), XExpand()),
  66. max(m_sizeMin.Y(), YExpand())
  67. )
  68. );
  69. }
  70. void FillPane::Paint(Surface* psurface)
  71. {
  72. psurface->FillSurface(m_color);
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. //
  76. // Border Pane
  77. //
  78. /////////////////////////////////////////////////////////////////////////////
  79. BorderPane::BorderPane(int width, const Color& color, Pane* pchild) :
  80. Pane(pchild),
  81. m_xborder(width),
  82. m_yborder(width),
  83. m_color(color),
  84. m_colorSelected(color)
  85. {
  86. SetOpaque(true);
  87. }
  88. BorderPane::BorderPane(int xborder, int yborder, const Color& color, Pane* pchild) :
  89. Pane(pchild),
  90. m_xborder(xborder),
  91. m_yborder(yborder),
  92. m_color(color),
  93. m_colorSelected(color)
  94. {
  95. SetOpaque(true);
  96. }
  97. void BorderPane::SetColor(const Color& color)
  98. {
  99. m_color = color;
  100. NeedPaint();
  101. }
  102. void BorderPane::SetColorSelected(const Color& color)
  103. {
  104. m_colorSelected = color;
  105. NeedPaint();
  106. }
  107. void BorderPane::UpdateLayout()
  108. {
  109. if (Child()) {
  110. InternalSetExpand(
  111. Child(),
  112. WinPoint(
  113. XExpand() == 0 ? 0 : XExpand() - m_xborder * 2,
  114. YExpand() == 0 ? 0 : YExpand() - m_yborder * 2
  115. )
  116. );
  117. Child()->UpdateLayout();
  118. InternalSetSize(WinPoint(
  119. Child()->XSize() + m_xborder * 2,
  120. Child()->YSize() + m_yborder * 2
  121. ));
  122. InternalSetOffset(Child(), WinPoint(m_xborder, m_yborder));
  123. } else {
  124. InternalSetSize(
  125. WinPoint(
  126. max(m_xborder * 2, XExpand()),
  127. max(m_yborder * 2, YExpand())
  128. )
  129. );
  130. }
  131. }
  132. void BorderPane::Paint(Surface* psurface)
  133. {
  134. if (IsSelected()) {
  135. psurface->FillSurface(m_colorSelected);
  136. } else {
  137. psurface->FillSurface(m_color);
  138. }
  139. }
  140. /////////////////////////////////////////////////////////////////////////////
  141. //
  142. // Edge Pane
  143. //
  144. /////////////////////////////////////////////////////////////////////////////
  145. EdgePane::EdgePane(Pane* pchild, bool bUp) :
  146. Pane(pchild),
  147. m_bUp(bUp)
  148. {
  149. }
  150. void EdgePane::UpdateLayout()
  151. {
  152. int width = 3; // m_bUp ? 3 : 4;
  153. if (Child()) {
  154. InternalSetExpand(
  155. Child(),
  156. WinPoint(
  157. XExpand() == 0 ? 0 : XExpand() - width,
  158. YExpand() == 0 ? 0 : YExpand() - width
  159. )
  160. );
  161. Child()->UpdateLayout();
  162. InternalSetSize(WinPoint(
  163. Child()->XSize() + width,
  164. Child()->YSize() + width
  165. ));
  166. InternalSetOffset(Child(), WinPoint(width - 2, width - 2));
  167. } else {
  168. InternalSetSize(WinPoint(width, width));
  169. }
  170. }
  171. void EdgePane::Paint(Surface* psurface)
  172. {
  173. if (m_bUp) {
  174. // top
  175. psurface->FillRect(WinRect(0, 0, XSize() - 1, 1), GetSystemColor(SystemColor3DHighLight));
  176. // left
  177. psurface->FillRect(WinRect(0, 0, 1, YSize() - 1), GetSystemColor(SystemColor3DHighLight));
  178. // bottom
  179. psurface->FillRect(WinRect(1, YSize() - 2, XSize() - 1, YSize() - 1), GetSystemColor(SystemColor3DShadow));
  180. psurface->FillRect(WinRect(0, YSize() - 1, XSize(), YSize() ), GetSystemColor(SystemColor3DDKShadow));
  181. // right
  182. psurface->FillRect(WinRect(XSize() - 2, 1, XSize() - 1, YSize() - 1), GetSystemColor(SystemColor3DShadow));
  183. psurface->FillRect(WinRect(XSize() - 1, 0, XSize(), YSize() ), GetSystemColor(SystemColor3DDKShadow));
  184. } else {
  185. // top
  186. psurface->FillRect(WinRect(0, 0, XSize() - 1, 1), GetSystemColor(SystemColor3DDKShadow));
  187. psurface->FillRect(WinRect(1, 1, XSize() - 1, 2), GetSystemColor(SystemColor3DShadow));
  188. // left
  189. psurface->FillRect(WinRect(0, 0, 1, YSize() - 1), GetSystemColor(SystemColor3DDKShadow));
  190. psurface->FillRect(WinRect(1, 1, 2, YSize() - 2), GetSystemColor(SystemColor3DShadow));
  191. // bottom
  192. psurface->FillRect(WinRect(0, YSize() - 1, XSize(), YSize()), GetSystemColor(SystemColor3DHighLight));
  193. // right
  194. psurface->FillRect(WinRect(XSize() - 1, 0, XSize(), YSize()), GetSystemColor(SystemColor3DHighLight));
  195. }
  196. }
  197. /////////////////////////////////////////////////////////////////////////////
  198. //
  199. // Column Pane
  200. //
  201. /////////////////////////////////////////////////////////////////////////////
  202. ColumnPane::ColumnPane(bool bShowGrid) :
  203. m_bShowGrid(bShowGrid)
  204. {}
  205. ColumnPane::ColumnPane(Pane* ppane0, bool bShowGrid) :
  206. m_bShowGrid(bShowGrid)
  207. {
  208. InsertAtBottom(ppane0);
  209. }
  210. ColumnPane::ColumnPane(Pane* ppane0, Pane* ppane1, bool bShowGrid) :
  211. m_bShowGrid(bShowGrid)
  212. {
  213. InsertAtBottom(ppane0);
  214. InsertAtBottom(ppane1);
  215. }
  216. ColumnPane::ColumnPane(Pane* ppane0, Pane* ppane1, Pane* ppane2, bool bShowGrid) :
  217. m_bShowGrid(bShowGrid)
  218. {
  219. InsertAtBottom(ppane0);
  220. InsertAtBottom(ppane1);
  221. InsertAtBottom(ppane2);
  222. }
  223. void ColumnPane::ShowGrid(bool bShowGrid)
  224. {
  225. m_bShowGrid = bShowGrid;
  226. NeedLayout();
  227. NeedPaint();
  228. }
  229. void ColumnPane::UpdateLayout()
  230. {
  231. int xsize = 0;
  232. int ysize = 0;
  233. //
  234. // first calculate the non-y expanded size
  235. //
  236. Pane* ppane;
  237. for(ppane = Child(); ppane != NULL; ppane = ppane->Next()) {
  238. if (!ppane->IsHidden()) {
  239. InternalSetExpand(ppane, WinPoint(XExpand(), 0));
  240. ppane->UpdateLayout();
  241. InternalSetOffset(ppane, WinPoint(0, ysize));
  242. xsize = max(ppane->XSize(), xsize);
  243. ysize += ppane->YSize() + (m_bShowGrid ? 1 : 0);
  244. }
  245. }
  246. //
  247. // If the ysize is less than YExpand() try to expand the child panes
  248. //
  249. int yextra = YExpand() - ysize;
  250. if (yextra > 0 || ysize > YExpand()) {
  251. bool bExpandLeftFirst = true;
  252. if (yextra < 0) {
  253. yextra = 0;
  254. }
  255. ysize = 0;
  256. for(ppane = Child(); ppane != NULL; ppane = ppane->Next()) {
  257. if (!ppane->IsHidden()) {
  258. int ysizeOld = ppane->YSize();
  259. if (bExpandLeftFirst) {
  260. InternalSetExpand(ppane, WinPoint(xsize, ysizeOld + yextra));
  261. } else {
  262. // !!! expand right first
  263. }
  264. ppane->UpdateLayout();
  265. InternalSetOffset(ppane, WinPoint(0, ysize));
  266. yextra -= ppane->YSize() - ysizeOld;
  267. ysize += ppane->YSize() + (m_bShowGrid ? 1 : 0);
  268. }
  269. }
  270. }
  271. if (Child() && m_bShowGrid) {
  272. ysize--;
  273. }
  274. InternalSetSize(WinPoint(xsize, ysize));
  275. }
  276. void ColumnPane::Paint(Surface* psurface)
  277. {
  278. if (m_bShowGrid) {
  279. int y = -1;
  280. for(Pane* ppane = Child();
  281. ppane != NULL && ppane->Next() != NULL;
  282. ppane = ppane->Next()
  283. ) {
  284. y += ppane->YSize() + (m_bShowGrid ? 1 : 0);
  285. psurface->FillRect(WinRect(0, y, XSize(), y + 1), Color::Black());
  286. }
  287. }
  288. }
  289. /////////////////////////////////////////////////////////////////////////////
  290. //
  291. // Row Pane
  292. //
  293. /////////////////////////////////////////////////////////////////////////////
  294. RowPane::RowPane(bool bShowGrid) :
  295. m_bShowGrid(bShowGrid)
  296. {}
  297. RowPane::RowPane(Pane* ppane0, bool bShowGrid) :
  298. m_bShowGrid(bShowGrid)
  299. {
  300. InsertAtBottom(ppane0);
  301. }
  302. RowPane::RowPane(Pane* ppane0, Pane* ppane1, bool bShowGrid) :
  303. m_bShowGrid(bShowGrid)
  304. {
  305. InsertAtBottom(ppane0);
  306. InsertAtBottom(ppane1);
  307. }
  308. void RowPane::ShowGrid(bool bShowGrid)
  309. {
  310. m_bShowGrid = bShowGrid;
  311. NeedLayout();
  312. NeedPaint();
  313. }
  314. void RowPane::UpdateLayout()
  315. {
  316. int xsize = 0;
  317. int ysize = 0;
  318. bool bEvenHeight = false;
  319. //
  320. // first calculate the non-x expanded size
  321. //
  322. Pane* ppane;
  323. for(ppane = Child(); ppane != NULL; ppane = ppane->Next()) {
  324. if (!ppane->IsHidden()) {
  325. InternalSetExpand(ppane, WinPoint(0, YExpand()));
  326. ppane->UpdateLayout();
  327. InternalSetOffset(ppane, WinPoint(xsize, 0));
  328. xsize += ppane->XSize() + (m_bShowGrid ? 1 : 0);
  329. ysize = max(ppane->YSize(), ysize);
  330. bEvenHeight |= ppane->NeedEvenHeight();
  331. }
  332. }
  333. if (bEvenHeight && ((ysize & 1) != 0)) {
  334. ysize++;
  335. }
  336. //
  337. // If the xsize is less than XExpand() try to expand the child panes
  338. //
  339. int xextra = XExpand() - xsize;
  340. if (xextra > 0 || ysize > YExpand()) {
  341. bool bExpandLeftFirst = true;
  342. if (xextra < 0) {
  343. xextra = 0;
  344. }
  345. xsize = 0;
  346. int ysizeNew = 0;
  347. for(ppane = Child(); ppane != NULL; ppane = ppane->Next()) {
  348. if (!ppane->IsHidden()) {
  349. int xsizeOld = ppane->XSize();
  350. if (bExpandLeftFirst) {
  351. InternalSetExpand(ppane, WinPoint(xsizeOld + xextra, ysize));
  352. } else {
  353. // !!! expand right first
  354. }
  355. ppane->UpdateLayout();
  356. InternalSetOffset(ppane, WinPoint(xsize, 0));
  357. xextra -= ppane->XSize() - xsizeOld;
  358. xsize += ppane->XSize() + (m_bShowGrid ? 1 : 0);
  359. ysizeNew = max(ppane->YSize(), ysizeNew);
  360. }
  361. }
  362. ysize = ysizeNew;
  363. }
  364. if (Child() && m_bShowGrid) {
  365. xsize--;
  366. }
  367. InternalSetSize(WinPoint(xsize, ysize));
  368. }
  369. void RowPane::Paint(Surface* psurface)
  370. {
  371. if (m_bShowGrid) {
  372. int x = -1;
  373. for(Pane* ppane = Child();
  374. ppane != NULL && ppane->Next() != NULL;
  375. ppane = ppane->Next()
  376. ) {
  377. x += ppane->XSize() + 1;
  378. psurface->FillRect(WinRect(x, 0, x + 1, YSize()), Color::Black());
  379. }
  380. }
  381. }
  382. /////////////////////////////////////////////////////////////////////////////
  383. //
  384. // String Pane
  385. //
  386. /////////////////////////////////////////////////////////////////////////////
  387. StringPane::StringPane(const ZString& str, IEngineFont* pfont) :
  388. m_str(str),
  389. m_textColor(GetSystemColor(SystemColorWindowText)),
  390. m_textColorSelected(GetSystemColor(SystemColorHighLightText)),
  391. m_pfont(pfont),
  392. m_bClipped(false),
  393. m_justification(JustifyLeft())
  394. {
  395. }
  396. StringPane::StringPane(
  397. const ZString& str,
  398. IEngineFont* pfont,
  399. WinPoint ptSize,
  400. Justification justification
  401. ) :
  402. m_str(str),
  403. m_textColor(GetSystemColor(SystemColorWindowText)),
  404. m_textColorSelected(GetSystemColor(SystemColorHighLightText)),
  405. m_pfont(pfont),
  406. m_bClipped(true),
  407. m_ptSize(ptSize),
  408. m_justification(justification)
  409. {
  410. }
  411. void StringPane::SetFont(IEngineFont* pfont)
  412. {
  413. m_pfont = pfont;
  414. }
  415. void StringPane::SetTextColor(const Color& color)
  416. {
  417. if (color != m_textColor) {
  418. m_textColor = color;
  419. if (!IsSelected()) {
  420. NeedPaint();
  421. }
  422. }
  423. }
  424. void StringPane::SetTextColorSelected(const Color& color)
  425. {
  426. if (m_textColorSelected != color) {
  427. m_textColorSelected = color;
  428. if (IsSelected()) {
  429. NeedPaint();
  430. }
  431. }
  432. }
  433. void StringPane::Paint(Surface* psurface)
  434. {
  435. ZString strClipped;
  436. if (m_bClipped) {
  437. if (m_justification == JustifyRight() || m_justification == JustifyLeftClipRight())
  438. strClipped = m_str.Right(GetFont()->GetMaxTextLength(m_str, m_ptSize.X(), false));
  439. else
  440. strClipped = m_str.Left(GetFont()->GetMaxTextLength(m_str, m_ptSize.X(), true ));
  441. } else {
  442. strClipped = m_str;
  443. }
  444. int nXStart;
  445. if (m_justification == JustifyRight()) {
  446. ZAssert(m_bClipped);
  447. nXStart = m_ptSize.X() - m_pfont->GetTextExtent(strClipped).X();
  448. } else if (m_justification == JustifyCenter()) {
  449. ZAssert(m_bClipped);
  450. nXStart = (m_ptSize.X() - m_pfont->GetTextExtent(strClipped).X())/2;
  451. } else {
  452. ZAssert(m_justification == JustifyLeft() || m_justification == JustifyLeftClipRight());
  453. nXStart = 0;
  454. }
  455. psurface->DrawString(
  456. m_pfont,
  457. IsSelected() ? m_textColorSelected : m_textColor,
  458. WinPoint(nXStart, 0),
  459. strClipped
  460. );
  461. }
  462. void StringPane::SetString(const ZString& str)
  463. {
  464. if (str != m_str) {
  465. m_str = str;
  466. NeedLayout();
  467. NeedPaint();
  468. }
  469. }
  470. void StringPane::SetJustification(Justification justification)
  471. {
  472. ZAssert(m_bClipped);
  473. m_justification = justification;
  474. }
  475. void StringPane::UpdateLayout()
  476. {
  477. if (m_bClipped) {
  478. InternalSetSize(m_ptSize);
  479. } else {
  480. InternalSetSize(m_pfont->GetTextExtent(m_str));
  481. }
  482. }
  483. /////////////////////////////////////////////////////////////////////////////
  484. //
  485. // EditPane
  486. //
  487. /////////////////////////////////////////////////////////////////////////////
  488. class EditPaneImpl :
  489. public EditPane,
  490. public Value
  491. {
  492. protected:
  493. ZString m_str;
  494. ZString m_strDisplay;
  495. ZString m_strClipped;
  496. Color m_textColor;
  497. TRef<IEngineFont> m_pfont;
  498. int m_xsizeCursor;
  499. bool m_bFocus;
  500. bool m_bReadOnly;
  501. bool m_bCursorOn;
  502. EditPaneType m_type;
  503. int m_maxLength;
  504. float m_timeLast;
  505. TRef<EventSourceImpl> m_peventSource;
  506. TRef<StringEventSourceImpl> m_peventSourceZString;
  507. Number* GetTime() { return (Number*)GetChild(0); }
  508. public:
  509. EditPaneImpl(const ZString& str, IEngineFont* pfont, Number* ptime) :
  510. Value(ptime),
  511. m_pfont(pfont),
  512. m_textColor(Color::White()),
  513. m_bFocus(false),
  514. m_type(Normal),
  515. m_bReadOnly(false),
  516. m_maxLength(-1),
  517. m_timeLast(ptime->GetValue())
  518. {
  519. m_xsizeCursor = pfont->GetTextExtent("o").X();
  520. m_peventSource = new EventSourceImpl();
  521. m_peventSourceZString = new StringEventSourceImpl();
  522. SetString(str);
  523. }
  524. void UpdateStrings()
  525. {
  526. if (m_type == Password) {
  527. m_strDisplay = ZString('*', m_str.GetLength());
  528. } else {
  529. m_strDisplay = m_str;
  530. }
  531. if (m_bFocus && !m_bReadOnly) {
  532. m_strClipped =
  533. m_strDisplay.Right(
  534. m_pfont->GetMaxTextLength(
  535. m_strDisplay,
  536. GetSize().X() - m_xsizeCursor,
  537. false
  538. )
  539. );
  540. } else {
  541. m_strClipped =
  542. m_strDisplay.Left(
  543. m_pfont->GetMaxTextLength(
  544. m_strDisplay,
  545. GetSize().X(),
  546. true
  547. )
  548. );
  549. }
  550. }
  551. /////////////////////////////////////////////////////////////////////////////
  552. //
  553. // EditPane methods
  554. //
  555. /////////////////////////////////////////////////////////////////////////////
  556. TRef<IEventSource> GetClickEvent()
  557. {
  558. return m_peventSource;
  559. }
  560. TRef<IStringEventSource> GetChangeEvent()
  561. {
  562. return m_peventSourceZString;
  563. }
  564. const ZString& GetString()
  565. {
  566. return m_str;
  567. }
  568. void SetTextColor(const Color& color)
  569. {
  570. m_textColor = color;
  571. NeedPaint();
  572. }
  573. void SetFont(IEngineFont* pfont)
  574. {
  575. m_pfont = pfont;
  576. NeedPaint();
  577. }
  578. void SetReadOnly(bool bReadOnly)
  579. {
  580. m_bReadOnly = bReadOnly;
  581. UpdateStrings();
  582. }
  583. bool IsReadOnly()
  584. {
  585. return m_bReadOnly;
  586. }
  587. void SetString(const ZString& str)
  588. {
  589. if (str != m_str) {
  590. m_str = str;
  591. UpdateStrings();
  592. NeedPaint();
  593. }
  594. }
  595. void SetType(EditPaneType type)
  596. {
  597. m_type = type;
  598. UpdateStrings();
  599. NeedPaint();
  600. }
  601. void SetMaxLength(int length)
  602. {
  603. m_maxLength = length;
  604. if (m_str.GetLength() > m_maxLength) {
  605. SetString(m_str.Left(m_maxLength));
  606. }
  607. }
  608. /////////////////////////////////////////////////////////////////////////////
  609. //
  610. // IKeyboardInput methods
  611. //
  612. /////////////////////////////////////////////////////////////////////////////
  613. bool OnKey(IInputProvider* pprovider, const KeyState& ks, bool& fForceTranslate)
  614. {
  615. fForceTranslate = true;
  616. return false;
  617. }
  618. bool OnChar(IInputProvider* pprovider, const KeyState& ks)
  619. {
  620. if (m_bReadOnly)
  621. return true;
  622. if (ks.vk == 13) {
  623. m_peventSourceZString->Trigger(m_str);
  624. } else if (ks.vk == 8) {
  625. if (m_str.GetLength() > 0) {
  626. SetString(m_str.LeftOf(1));
  627. NeedPaint();
  628. }
  629. } else {
  630. char ch = ks.vk;
  631. //
  632. // Unblink the cursor
  633. //
  634. m_timeLast = GetTime()->GetValue();
  635. //
  636. // Only allow numbers in a Numeric edit pane
  637. //
  638. if (m_type == Numeric && (ch < '0' || ch > '9' )) {
  639. return true;
  640. }
  641. //
  642. // Limit the length
  643. //
  644. if (m_maxLength != -1 && m_str.GetLength() == m_maxLength) {
  645. return true;
  646. }
  647. //
  648. // Everythings ok add the character
  649. //
  650. SetString(m_str + ZString(ch, 1));
  651. NeedPaint();
  652. }
  653. return true;
  654. }
  655. void SetFocusState(bool bFocus)
  656. {
  657. m_bFocus = bFocus;
  658. UpdateStrings();
  659. NeedPaint();
  660. }
  661. /////////////////////////////////////////////////////////////////////////////
  662. //
  663. // IMouseInput methods
  664. //
  665. /////////////////////////////////////////////////////////////////////////////
  666. MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
  667. {
  668. if (!m_bReadOnly)
  669. {
  670. if (button == 0) {
  671. if (bDown) {
  672. m_peventSource->Trigger();
  673. }
  674. }
  675. }
  676. return MouseResult();
  677. }
  678. /////////////////////////////////////////////////////////////////////////////
  679. //
  680. // Pane methods
  681. //
  682. /////////////////////////////////////////////////////////////////////////////
  683. void Paint(Surface* psurface)
  684. {
  685. psurface->DrawString(m_pfont, m_textColor, WinPoint(0, 0), m_strClipped);
  686. //
  687. // Draw the cursor
  688. //
  689. WinPoint size = m_pfont->GetTextExtent(m_strClipped);
  690. if (m_bFocus && m_bCursorOn) {
  691. psurface->FillRect(
  692. WinRect(
  693. size.X() + 1,
  694. 1,
  695. size.X() + m_xsizeCursor,
  696. GetSize().Y() - 2
  697. ),
  698. m_textColor
  699. );
  700. }
  701. }
  702. void UpdateLayout()
  703. {
  704. }
  705. /////////////////////////////////////////////////////////////////////////////
  706. //
  707. // Value methods
  708. //
  709. /////////////////////////////////////////////////////////////////////////////
  710. void ChildChanged(Value* pvalue, Value* pvalueNew)
  711. {
  712. Value::ChildChanged(pvalue, pvalueNew);
  713. float time = GetTime()->GetValue();
  714. bool bOn = mod((time - m_timeLast), 1.0f) < 0.5f;
  715. if (m_bCursorOn != bOn) {
  716. m_bCursorOn = bOn;
  717. NeedPaint();
  718. }
  719. }
  720. };
  721. TRef<EditPane> CreateEditPane(const ZString& str, IEngineFont* pfont, Number* ptime)
  722. {
  723. return new EditPaneImpl(str, pfont, ptime);
  724. }
  725. /////////////////////////////////////////////////////////////////////////////
  726. //
  727. // AnimatedImage Pane
  728. //
  729. /////////////////////////////////////////////////////////////////////////////
  730. AnimatedImagePane::AnimatedImagePane(Image* pimage, const Rect& rect) :
  731. Value(pimage),
  732. m_rect(rect),
  733. m_bFixedRect(true),
  734. m_ysizeSurface(m_rect.YSize())
  735. {
  736. }
  737. AnimatedImagePane::AnimatedImagePane(Image* pimage) :
  738. Value(pimage),
  739. m_bFixedRect(false)
  740. {
  741. }
  742. void AnimatedImagePane::ChildChanged(Value* pvalue, Value* pvalueNew)
  743. {
  744. Value::ChildChanged(pvalue, pvalueNew);
  745. NeedPaint();
  746. NeedLayout();
  747. }
  748. void AnimatedImagePane::UpdateLayout()
  749. {
  750. Update();
  751. if (!m_bFixedRect) {
  752. m_rect = GetImage()->GetBounds().GetRect();
  753. m_ysizeSurface = m_rect.YSize();
  754. }
  755. InternalSetSize(WinPoint::Cast(m_rect.Size()));
  756. Pane::UpdateLayout();
  757. }
  758. void AnimatedImagePane::Paint(Surface* psurface)
  759. {
  760. if (XSize() > 0 && YSize() > 0) {
  761. Update();
  762. Point offset = Point::Cast(GetOffsetFrom(NULL));
  763. m_ysizeSurface = float(psurface->GetSize().Y());
  764. TRef<Context> pcontext = psurface->GetContext();
  765. if (pcontext) {
  766. pcontext->Clip(
  767. Rect(
  768. offset.X(),
  769. m_ysizeSurface - (offset.Y() + YSize()),
  770. offset.X() + XSize(),
  771. m_ysizeSurface - offset.Y()
  772. )
  773. );
  774. pcontext->Translate(
  775. Point(
  776. offset.X(),
  777. m_ysizeSurface - offset.Y() - m_rect.YMax()
  778. )
  779. );
  780. GetImage()->Render(pcontext);
  781. psurface->ReleaseContext(pcontext);
  782. }
  783. }
  784. }
  785. Point AnimatedImagePane::GetImagePoint(const Point& point)
  786. {
  787. //
  788. // Flip the coordinates
  789. //
  790. float x = point.X();
  791. float y = (float)GetSize().Y() - 1.0f - point.Y();
  792. //
  793. // Translate
  794. //
  795. //
  796. // There is a hack here, we are using the saved surface size
  797. // from the last time that we painted the window
  798. //
  799. //Point offset = Point::Cast(GetOffsetFrom(NULL));
  800. return m_rect.Min() + Point(x, y);
  801. /*
  802. Point(
  803. x + m_rect.XMin() + offset.X(),
  804. y + m_ysizeSurface - (float)offset.Y() - m_rect.YMax()
  805. );
  806. */
  807. }
  808. MouseResult AnimatedImagePane::HitTest(IInputProvider* pprovider, const Point& point, bool bCaptured)
  809. {
  810. Point pointImage = GetImagePoint(point);
  811. if (m_bFixedRect) {
  812. if (!m_rect.Inside(pointImage)) {
  813. return MouseResult();
  814. }
  815. }
  816. return GetImage()->HitTest(pprovider, GetImagePoint(point), bCaptured);
  817. }
  818. void AnimatedImagePane::MouseMove(IInputProvider* pprovider, const Point& point, bool bCaptured, bool bInside)
  819. {
  820. GetImage()->MouseMove(pprovider, GetImagePoint(point), bCaptured, bInside);
  821. }
  822. void AnimatedImagePane::MouseEnter(IInputProvider* pprovider, const Point& point)
  823. {
  824. GetImage()->MouseEnter(pprovider, GetImagePoint(point));
  825. }
  826. void AnimatedImagePane::MouseLeave(IInputProvider* pprovider)
  827. {
  828. GetImage()->MouseLeave(pprovider);
  829. }
  830. MouseResult AnimatedImagePane::Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
  831. {
  832. return GetImage()->Button(pprovider, GetImagePoint(point), button, bCaptured, bInside, bDown);
  833. }
  834. /////////////////////////////////////////////////////////////////////////////
  835. //
  836. // Image Pane
  837. //
  838. /////////////////////////////////////////////////////////////////////////////
  839. ImagePane::ImagePane(Image* pimage) :
  840. Value(pimage)
  841. {
  842. }
  843. void ImagePane::ChildChanged(Value* pvalue, Value* pvalueNew)
  844. {
  845. Value::ChildChanged(pvalue, pvalueNew);
  846. NeedPaint();
  847. NeedLayout();
  848. }
  849. void ImagePane::UpdateLayout()
  850. {
  851. Update();
  852. InternalSetSize(
  853. WinPoint::Cast(GetImage()->GetBounds().GetRect().Size())
  854. );
  855. Pane::UpdateLayout();
  856. }
  857. void ImagePane::Paint(Surface* psurface)
  858. {
  859. TRef<Surface> psurfaceSource = GetImage()->GetSurface();
  860. psurface->BitBlt(WinPoint(0, 0), psurfaceSource);
  861. }
  862. /////////////////////////////////////////////////////////////////////////////
  863. //
  864. // Surface Pane
  865. //
  866. /////////////////////////////////////////////////////////////////////////////
  867. SurfacePane::SurfacePane(Surface* psurface) :
  868. m_psurface(psurface)
  869. {
  870. InternalSetSize(psurface->GetSize());
  871. }
  872. void SurfacePane::Paint(Surface* psurface)
  873. {
  874. psurface->BitBlt(WinPoint(0, 0), m_psurface);
  875. }
  876. void SurfacePane::SetSurface(Surface* psurface)
  877. {
  878. m_psurface = psurface;
  879. if (m_psurface->GetSize() != GetSize()) {
  880. NeedLayout();
  881. }
  882. NeedPaint();
  883. }
  884. /////////////////////////////////////////////////////////////////////////////
  885. //
  886. // TroughPane
  887. //
  888. /////////////////////////////////////////////////////////////////////////////
  889. typedef WinPoint (PFNMakePoint)(int x, int y);
  890. WinPoint MakePoint(int x, int y)
  891. {
  892. return WinPoint(x, y);
  893. }
  894. WinPoint MakePointFlipped(int x, int y)
  895. {
  896. return WinPoint(y, x);
  897. }
  898. class TroughPane : public Pane, IEventSink {
  899. private:
  900. TRef<IntegerEventSourceImpl> m_peventSource;
  901. TRef<Pane> m_ppaneThumb;
  902. TRef<ButtonPane> m_ppaneLeft;
  903. TRef<ButtonPane> m_ppaneRight;
  904. TRef<IEventSource> m_peventSourceLeft;
  905. TRef<IEventSource> m_peventSourceRight;
  906. TRef<IEventSink> m_psinkLeft;
  907. TRef<IEventSink> m_psinkRight;
  908. bool m_bHorizontal;
  909. bool m_bICaptured;
  910. int m_size;
  911. int m_sizePage;
  912. int m_sizeLine;
  913. int m_pos;
  914. int m_sizeThumb;
  915. int m_sizePixels;
  916. Point m_pointTrack;
  917. public:
  918. /////////////////////////////////////////////////////////////////////////////
  919. //
  920. // Constructor
  921. //
  922. /////////////////////////////////////////////////////////////////////////////
  923. TroughPane(
  924. Pane* ppaneThumb,
  925. Pane* ppaneLeft,
  926. Pane* ppaneRight,
  927. bool bHorizontal,
  928. float repeatRate,
  929. int size,
  930. int sizePage,
  931. int sizeLine,
  932. int pos
  933. ) :
  934. m_ppaneThumb(ppaneThumb),
  935. m_bHorizontal(bHorizontal),
  936. m_size(size),
  937. m_sizePage(sizePage),
  938. m_sizeLine(sizeLine),
  939. m_pos(0),
  940. m_peventSource(new IntegerEventSourceImpl()),
  941. m_bICaptured(false)
  942. {
  943. // , should pass the buttons in and have ScrollPane handle the events
  944. m_ppaneLeft = CreateButton(ppaneLeft, NULL, false, repeatRate);
  945. m_ppaneRight = CreateButton(ppaneRight, NULL, false, repeatRate);
  946. m_peventSourceLeft = m_ppaneLeft->GetEventSource();
  947. m_peventSourceRight = m_ppaneRight->GetEventSource();
  948. m_peventSourceLeft->AddSink( IEventSink::CreateDelegate(this));
  949. m_peventSourceRight->AddSink(IEventSink::CreateDelegate(this));
  950. InsertAtBottom(m_ppaneLeft);
  951. InsertAtBottom(m_ppaneThumb);
  952. InsertAtBottom(m_ppaneRight);
  953. SetPos(pos);
  954. }
  955. /////////////////////////////////////////////////////////////////////////////
  956. //
  957. // Destructor
  958. //
  959. /////////////////////////////////////////////////////////////////////////////
  960. ~TroughPane()
  961. {
  962. m_peventSourceLeft->RemoveSink( m_psinkLeft = IEventSink::CreateDelegate(this));
  963. m_peventSourceRight->RemoveSink(m_psinkRight = IEventSink::CreateDelegate(this));
  964. }
  965. /////////////////////////////////////////////////////////////////////////////
  966. //
  967. // TroughPane Methods
  968. //
  969. /////////////////////////////////////////////////////////////////////////////
  970. void SetSizes(int size, int sizePage)
  971. {
  972. ZAssert(size >= 0);
  973. ZAssert(sizePage >= 0);
  974. if (
  975. m_size != size
  976. || m_sizePage != sizePage
  977. ) {
  978. m_size = size;
  979. m_sizePage = sizePage;
  980. //
  981. // ensure m_pos is still within proper bounds
  982. //
  983. SetPos(m_pos);
  984. NeedLayout();
  985. NeedPaint();
  986. }
  987. }
  988. void SetLineSize(int sizeLine)
  989. {
  990. if (m_sizeLine != sizeLine) {
  991. m_sizeLine = sizeLine;
  992. NeedLayout();
  993. NeedPaint();
  994. }
  995. }
  996. void SetPos(int pos)
  997. {
  998. if (pos < 0) {
  999. pos = 0;
  1000. }
  1001. if (pos > m_size - m_sizePage) {
  1002. pos = max(m_size - m_sizePage, 0);
  1003. }
  1004. if (m_pos != pos) {
  1005. m_pos = pos;
  1006. NeedLayout();
  1007. NeedPaint();
  1008. m_peventSource->Trigger(m_pos);
  1009. }
  1010. }
  1011. void SetMousePos(int x)
  1012. {
  1013. if (m_sizePixels - m_sizeThumb != 0) {
  1014. SetPos(x * (m_size - m_sizePage) / (m_sizePixels - m_sizeThumb));
  1015. } else {
  1016. SetPos(0);
  1017. }
  1018. }
  1019. void PageUp()
  1020. {
  1021. SetPos(m_pos - m_sizePage);
  1022. }
  1023. void PageDown()
  1024. {
  1025. SetPos(m_pos + m_sizePage);
  1026. }
  1027. void LineUp()
  1028. {
  1029. SetPos(m_pos - m_sizeLine);
  1030. }
  1031. void LineDown()
  1032. {
  1033. SetPos(m_pos + m_sizeLine);
  1034. }
  1035. IIntegerEventSource* GetEventSource()
  1036. {
  1037. return m_peventSource;
  1038. }
  1039. int GetSize() { return m_size; }
  1040. int GetPageSize() { return m_sizePage; }
  1041. int GetLineSize() { return m_sizeLine; }
  1042. int GetPos() { return m_pos; }
  1043. bool IsHorizontal(){ return m_bHorizontal; }
  1044. /////////////////////////////////////////////////////////////////////////////
  1045. //
  1046. // Pane methods
  1047. //
  1048. /////////////////////////////////////////////////////////////////////////////
  1049. void UpdateLayout()
  1050. {
  1051. InternalSetSize(GetExpand());
  1052. //
  1053. // Set the thumb size
  1054. //
  1055. PFNMakePoint* pfnMakePoint;
  1056. int sizePixelsOther;
  1057. if (m_bHorizontal) {
  1058. pfnMakePoint = MakePoint;
  1059. m_sizePixels = XSize();
  1060. sizePixelsOther = YSize();
  1061. } else {
  1062. pfnMakePoint = MakePointFlipped;
  1063. m_sizePixels = YSize();
  1064. sizePixelsOther = XSize();
  1065. }
  1066. if (m_sizePage >= m_size) {
  1067. m_sizeThumb = m_sizePixels;
  1068. } else if (m_sizePage == 0) {
  1069. m_sizeThumb = sizePixelsOther;
  1070. } else {
  1071. m_sizeThumb = m_sizePixels * m_sizePage / m_size;
  1072. }
  1073. InternalSetExpand(
  1074. m_ppaneThumb,
  1075. pfnMakePoint(m_sizeThumb, sizePixelsOther)
  1076. );
  1077. m_ppaneThumb->UpdateLayout();
  1078. int otherThumb;
  1079. if (m_bHorizontal) {
  1080. m_sizeThumb = m_ppaneThumb->XSize();
  1081. otherThumb = m_ppaneThumb->YSize();
  1082. } else {
  1083. m_sizeThumb = m_ppaneThumb->YSize();
  1084. otherThumb = m_ppaneThumb->XSize();
  1085. }
  1086. //
  1087. // Adjust the left and right trough
  1088. //
  1089. int left;
  1090. int right;
  1091. if (m_sizeThumb > m_sizePixels) {
  1092. left = 0;
  1093. right = 0;
  1094. } else {
  1095. if (m_sizePage >= m_size) {
  1096. left = 0;
  1097. } else {
  1098. left = m_pos * (m_sizePixels - m_sizeThumb) / (m_size - m_sizePage);
  1099. }
  1100. right = m_sizePixels - m_sizeThumb - left;
  1101. }
  1102. InternalSetOffset(m_ppaneThumb, pfnMakePoint(left, 0));
  1103. //
  1104. // left and right trough
  1105. //
  1106. if (left == 0) {
  1107. InternalSetHidden(m_ppaneLeft, true);
  1108. } else {
  1109. InternalSetHidden(m_ppaneLeft, false);
  1110. InternalSetExpand(m_ppaneLeft, pfnMakePoint(left, otherThumb));
  1111. m_ppaneLeft->UpdateLayout();
  1112. }
  1113. if (right == 0) {
  1114. InternalSetHidden(m_ppaneRight, true);
  1115. } else {
  1116. InternalSetHidden(m_ppaneRight, false);
  1117. InternalSetExpand(m_ppaneRight, pfnMakePoint(right, otherThumb));
  1118. m_ppaneRight->UpdateLayout();
  1119. InternalSetOffset(m_ppaneRight, pfnMakePoint(left + m_sizeThumb, 0));
  1120. }
  1121. InternalSetSize(pfnMakePoint(left + m_sizeThumb + right, otherThumb));
  1122. }
  1123. /////////////////////////////////////////////////////////////////////////////
  1124. //
  1125. // IMouseInput methods
  1126. //
  1127. /////////////////////////////////////////////////////////////////////////////
  1128. void MouseMove(IInputProvider* pprovider, const Point& point, bool bCaptured, bool bInside)
  1129. {
  1130. if (bCaptured && GetCapturePane() == NULL) {
  1131. if (m_bHorizontal) {
  1132. SetMousePos((int)(point.X() - m_pointTrack.X()));
  1133. } else {
  1134. SetMousePos((int)(point.Y() - m_pointTrack.Y()));
  1135. }
  1136. }
  1137. }
  1138. MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown)
  1139. {
  1140. if (button == 0) {
  1141. if (bDown) {
  1142. Pane* ppaneHit = GetHitPane();
  1143. if (ppaneHit == m_ppaneThumb) {
  1144. m_pointTrack = point - Point::Cast(ppaneHit->GetOffset());
  1145. return MouseResultCapture();
  1146. }
  1147. } else if (bCaptured && GetCapturePane() == NULL) {
  1148. return MouseResultRelease();
  1149. }
  1150. }
  1151. return Pane::Button(pprovider, point, button, bCaptured, bInside, bDown);
  1152. }
  1153. /////////////////////////////////////////////////////////////////////////////
  1154. //
  1155. // IEventSink methods
  1156. //
  1157. /////////////////////////////////////////////////////////////////////////////
  1158. bool OnEvent(IEventSource* pevent)
  1159. {
  1160. if (pevent == m_peventSourceLeft) {
  1161. PageUp();
  1162. } else if (pevent == m_peventSourceRight) {
  1163. PageDown();
  1164. }
  1165. return true;
  1166. }
  1167. };
  1168. /////////////////////////////////////////////////////////////////////////////
  1169. //
  1170. // ScrollPane
  1171. //
  1172. /////////////////////////////////////////////////////////////////////////////
  1173. class ScrollPaneImpl :
  1174. public ScrollPane,
  1175. public IEventSink
  1176. {
  1177. public:
  1178. TRef<IEventSource> m_peventLeft;
  1179. TRef<IEventSource> m_peventRight;
  1180. TRef<TroughPane> m_ptroughPane;
  1181. TRef<IEventSink> m_psinkLeft;
  1182. TRef<IEventSink> m_psinkRight;
  1183. WinPoint m_sizeMin;
  1184. ScrollPaneImpl(
  1185. Pane* ppaneBackground,
  1186. Pane* ppaneThumb,
  1187. Pane* ppaneLeft,
  1188. IEventSource* peventLeft,
  1189. Pane* ppaneRight,
  1190. IEventSource* peventRight,
  1191. bool bHorizontal,
  1192. float repeatRatePage,
  1193. int size,
  1194. int sizePage,
  1195. int sizeLine,
  1196. int pos,
  1197. const WinPoint sizeMin
  1198. ) :
  1199. m_peventLeft(peventLeft),
  1200. m_peventRight(peventRight),
  1201. m_sizeMin(sizeMin)
  1202. {
  1203. m_peventLeft->AddSink( m_psinkLeft = IEventSink::CreateDelegate(this));
  1204. m_peventRight->AddSink(m_psinkRight = IEventSink::CreateDelegate(this));
  1205. //
  1206. // Create the trough
  1207. //
  1208. ppaneBackground->InsertAtTop(
  1209. m_ptroughPane = new TroughPane(
  1210. ppaneThumb,
  1211. //new BorderPane(0, RGB(255, 0, 0)),
  1212. //new BorderPane(0, RGB(0, 255, 0)),
  1213. new JustifyPane(),
  1214. new JustifyPane(),
  1215. bHorizontal,
  1216. repeatRatePage,
  1217. size,
  1218. sizePage,
  1219. sizeLine,
  1220. pos
  1221. )
  1222. );
  1223. //
  1224. // stick the buttons and the trough together
  1225. //
  1226. TRef<Pane> prow;
  1227. if (bHorizontal) {
  1228. prow = new RowPane();
  1229. } else {
  1230. prow = new ColumnPane();
  1231. }
  1232. prow->InsertAtBottom(ppaneLeft);
  1233. prow->InsertAtBottom(ppaneBackground);
  1234. prow->InsertAtBottom(ppaneRight);
  1235. InsertAtTop(prow);
  1236. }
  1237. ~ScrollPaneImpl()
  1238. {
  1239. m_peventLeft-> RemoveSink(m_psinkLeft );
  1240. m_peventRight->RemoveSink(m_psinkRight);
  1241. }
  1242. IIntegerEventSource* GetEventSource()
  1243. {
  1244. return m_ptroughPane->GetEventSource();
  1245. }
  1246. int GetSize() { return m_ptroughPane->GetSize(); }
  1247. int GetPageSize() { return m_ptroughPane->GetPageSize(); }
  1248. int GetLineSize() { return m_ptroughPane->GetLineSize(); }
  1249. int GetPos() { return m_ptroughPane->GetPos(); }
  1250. bool IsHorizontal(){ return m_ptroughPane->IsHorizontal();}
  1251. void SetSizes(int size, int sizePage)
  1252. {
  1253. m_ptroughPane->SetSizes(size, sizePage);
  1254. }
  1255. void SetSize(int size)
  1256. {
  1257. m_ptroughPane->SetSizes(size, m_ptroughPane->GetPageSize());
  1258. }
  1259. void SetPageSize(int sizePage)
  1260. {
  1261. m_ptroughPane->SetSizes(m_ptroughPane->GetSize(), sizePage);
  1262. }
  1263. void SetLineSize(int sizeLine)
  1264. {
  1265. m_ptroughPane->SetLineSize(sizeLine);
  1266. }
  1267. void SetPos(int pos)
  1268. {
  1269. m_ptroughPane->SetPos(pos);
  1270. }
  1271. void PageUp()
  1272. {
  1273. m_ptroughPane->PageUp();
  1274. }
  1275. void PageDown()
  1276. {
  1277. m_ptroughPane->PageDown();
  1278. }
  1279. void LineUp()
  1280. {
  1281. m_ptroughPane->LineUp();
  1282. }
  1283. void LineDown()
  1284. {
  1285. m_ptroughPane->LineDown();
  1286. }
  1287. //
  1288. // IEventSink methods
  1289. //
  1290. bool OnEvent(IEventSource* pevent)
  1291. {
  1292. if (pevent == m_peventLeft) {
  1293. LineUp();
  1294. } else if (pevent == m_peventRight) {
  1295. LineDown();
  1296. }
  1297. return true;
  1298. }
  1299. //
  1300. // Value Methods
  1301. //
  1302. void UpdateLayout()
  1303. {
  1304. InternalSetExpand(
  1305. WinPoint(
  1306. max(m_sizeMin.X(), GetExpand().X()),
  1307. max(m_sizeMin.Y(), GetExpand().Y())
  1308. )
  1309. );
  1310. DefaultUpdateLayout();
  1311. }
  1312. };
  1313. /////////////////////////////////////////////////////////////////////////////
  1314. //
  1315. // Easy ScrollPane Constructor
  1316. //
  1317. /////////////////////////////////////////////////////////////////////////////
  1318. TRef<ScrollPane> CreateScrollPane(
  1319. Pane* ppaneBackground,
  1320. Pane* ppaneThumb,
  1321. Pane* ppaneLeft,
  1322. IEventSource* peventLeft,
  1323. Pane* ppaneRight,
  1324. IEventSource* peventRight,
  1325. bool bHorizontal,
  1326. float repeatRatePage,
  1327. int size,
  1328. int sizePage,
  1329. int sizeLine,
  1330. int pos,
  1331. const WinPoint sizeMin
  1332. ) {
  1333. return
  1334. new ScrollPaneImpl(
  1335. ppaneBackground,
  1336. ppaneThumb,
  1337. ppaneLeft,
  1338. peventLeft,
  1339. ppaneRight,
  1340. peventRight,
  1341. bHorizontal,
  1342. repeatRatePage,
  1343. size,
  1344. sizePage,
  1345. sizeLine,
  1346. pos,
  1347. sizeMin
  1348. );
  1349. }
  1350. TRef<Pane> CreateScrollPane(
  1351. const WinPoint& point,
  1352. int size,
  1353. int pageSize,
  1354. int lineSize,
  1355. int pos,
  1356. TRef<ScrollPane>& pscrollPane,
  1357. TRef<IIntegerEventSource>& pevent
  1358. ) {
  1359. bool bHorizontal = true;
  1360. int buttonSize = point.Y();
  1361. if (point.X() < buttonSize) {
  1362. bHorizontal = false;
  1363. buttonSize = point.X();
  1364. }
  1365. TRef<ButtonPane> pbuttonUp = CreateButton(buttonSize);
  1366. TRef<ButtonPane> pbuttonDown = CreateButton(buttonSize);
  1367. pscrollPane =
  1368. CreateScrollPane(
  1369. new JustifyPane(),
  1370. new EdgePane(
  1371. new BorderPane(0, Color(0.5, 0.5, 0.5))
  1372. ),
  1373. pbuttonUp,
  1374. pbuttonUp->GetEventSource(),
  1375. pbuttonDown,
  1376. pbuttonDown->GetEventSource(),
  1377. bHorizontal,
  1378. 0.25f,
  1379. size,
  1380. pageSize,
  1381. lineSize,
  1382. pos
  1383. );
  1384. pevent = pscrollPane->GetEventSource();
  1385. return
  1386. new BorderPane(
  1387. 0,
  1388. Color(0.5, 0.5, 0.5),
  1389. new EdgePane(
  1390. new JustifyPane(
  1391. JustifyPane::Center,
  1392. point,
  1393. pscrollPane
  1394. )
  1395. )
  1396. );
  1397. }