listpane.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. #include "pch.h"
  2. /////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Default ItemPainter
  5. //
  6. /////////////////////////////////////////////////////////////////////////////
  7. class DefaultItemPainter : public ItemPainter {
  8. public:
  9. int GetXSize()
  10. {
  11. return 1;
  12. }
  13. int GetYSize()
  14. {
  15. return 1;
  16. }
  17. void Paint(ItemID pitem, Surface* psurface, bool bSelected, bool bFocus)
  18. {
  19. }
  20. };
  21. /////////////////////////////////////////////////////////////////////////////
  22. //
  23. // List Pane
  24. //
  25. /////////////////////////////////////////////////////////////////////////////
  26. template<class Interface>
  27. class ListPaneImpl :
  28. public Interface, // should contain ListPane,
  29. public IEventSink,
  30. public IIntegerEventSink
  31. {
  32. private:
  33. TRef<List> m_plist;
  34. TRef<ItemPainter> m_ppainter;
  35. TRef<ScrollPane> m_pscroll;
  36. ItemID m_pitemSelection;
  37. ItemID m_pitemSelectionPrevious;
  38. TRef<IEventSink> m_peventSink;
  39. TRef<IIntegerEventSink> m_pintegerEventSink;
  40. TRef<IItemEvent::SourceImpl> m_peventSelection;
  41. TRef<EventSourceImpl> m_peventSingleClick;
  42. TRef<EventSourceImpl> m_peventDoubleClick;
  43. int m_indexSelection;
  44. int m_posScroll;
  45. WinPoint m_sizeMin;
  46. bool m_bHorizontal;
  47. TVector<ItemID> m_vectItemsOld;
  48. bool m_bNeedScrollUpdate;
  49. bool m_bNeedSelectionOnScreen;
  50. int m_iOldSelection;
  51. public:
  52. ListPaneImpl(
  53. const WinPoint& sizeMin,
  54. List* plist,
  55. ItemPainter* ppainter,
  56. ScrollPane* pscroll,
  57. bool bHorizontal
  58. ) :
  59. m_sizeMin(sizeMin),
  60. m_ppainter(ppainter),
  61. m_pscroll(pscroll),
  62. m_indexSelection(0),
  63. m_posScroll(0),
  64. m_pitemSelection(NULL),
  65. m_pitemSelectionPrevious(NULL),
  66. m_bHorizontal(bHorizontal),
  67. m_iOldSelection(-1),
  68. m_bNeedScrollUpdate(false),
  69. m_bNeedSelectionOnScreen(false)
  70. {
  71. m_peventSelection = new IItemEvent::SourceImpl();
  72. m_peventSingleClick = new EventSourceImpl();
  73. m_peventDoubleClick = new EventSourceImpl();
  74. if (m_ppainter == NULL) {
  75. m_ppainter = new DefaultItemPainter();
  76. }
  77. if (m_pscroll) {
  78. m_pscroll->GetEventSource()->AddSink(
  79. m_pintegerEventSink = IIntegerEventSink::CreateDelegate(this)
  80. );
  81. }
  82. if (plist == NULL) {
  83. SetList(new EmptyList());
  84. } else {
  85. SetList(plist);
  86. }
  87. UpdateScrollBar();
  88. }
  89. ~ListPaneImpl()
  90. {
  91. m_plist->GetChangedEvent()->RemoveSink(m_peventSink);
  92. if (m_pscroll) {
  93. m_pscroll->GetEventSource()->RemoveSink(m_pintegerEventSink);
  94. }
  95. }
  96. const int GetSignificantSize() // returns size of the significant dimension
  97. {
  98. if (m_bHorizontal)
  99. {
  100. return GetSize().X();
  101. }
  102. else
  103. {
  104. return GetSize().Y();
  105. }
  106. }
  107. const int GetSignificantSize(ItemPainter & itempainter) // returns size of the significant dimension
  108. {
  109. if (m_bHorizontal)
  110. {
  111. return itempainter.GetXSize();
  112. }
  113. else
  114. {
  115. return itempainter.GetYSize();
  116. }
  117. }
  118. int GetScrollPos()
  119. {
  120. return m_posScroll;
  121. }
  122. void SetScrollPos(int pos)
  123. {
  124. m_posScroll =
  125. max(min(pos, m_plist->GetCount() * GetSignificantSize(*m_ppainter) - GetSignificantSize()), 0);
  126. if (m_pscroll) {
  127. m_pscroll->SetPos(m_posScroll);
  128. }
  129. }
  130. void UpdateScrollBar()
  131. {
  132. if (m_pscroll) {
  133. m_pscroll->SetLineSize(GetSignificantSize(*m_ppainter));//1);
  134. m_pscroll->SetSizes(
  135. m_plist->GetCount() * GetSignificantSize(*m_ppainter),
  136. GetSignificantSize()/* / GetSignificantSize(*m_ppainter)*/
  137. );
  138. }
  139. }
  140. ScrollPane * GetScrollPane()
  141. {
  142. return m_pscroll;
  143. }
  144. void UpdateScrollPos()
  145. {
  146. m_bNeedScrollUpdate = true;
  147. }
  148. void NextItem()
  149. {
  150. if (m_indexSelection < m_plist->GetCount() - 1) {
  151. m_indexSelection++;
  152. m_pitemSelection = m_plist->GetNext(m_pitemSelection);
  153. NeedPaint();
  154. SelectionChanged();
  155. m_bNeedScrollUpdate = true;
  156. m_bNeedSelectionOnScreen = true;
  157. }
  158. }
  159. void PreviousItem()
  160. {
  161. if (m_indexSelection != 0) {
  162. m_indexSelection--;
  163. m_pitemSelection = m_plist->GetItem(m_indexSelection);
  164. NeedPaint();
  165. SelectionChanged();
  166. m_bNeedScrollUpdate = true;
  167. m_bNeedSelectionOnScreen = true;
  168. }
  169. }
  170. void PageUp()
  171. {
  172. int delta = GetSignificantSize() / GetSignificantSize(*m_ppainter);
  173. while (delta > 0) {
  174. PreviousItem();
  175. delta--;
  176. }
  177. }
  178. void PageDown()
  179. {
  180. int delta = GetSignificantSize() / GetSignificantSize(*m_ppainter);
  181. while (delta > 0) {
  182. NextItem();
  183. delta--;
  184. }
  185. }
  186. void SelectionChanged()
  187. {
  188. if (m_pitemSelectionPrevious != m_pitemSelection) {
  189. m_peventSelection->Trigger(m_pitemSelection);
  190. m_pitemSelectionPrevious = m_pitemSelection;
  191. }
  192. }
  193. void ListChanged()
  194. {
  195. int index;
  196. if (m_pitemSelection != NULL)
  197. index = m_plist->GetIndex(m_pitemSelection);
  198. else
  199. index = -1;
  200. if (index == -1)
  201. {
  202. m_pitemSelection = NULL;
  203. m_iOldSelection = -1;
  204. }
  205. m_indexSelection = index;
  206. UpdateScrollBar();
  207. UpdateScrollPos();
  208. NeedLayout();
  209. NeedPaint();
  210. SelectionChanged();
  211. }
  212. void ScrollBarChanged()
  213. {
  214. m_posScroll = m_pscroll->GetPos()/* * GetSignificantSize(*m_ppainter)*/;
  215. NeedPaint();
  216. }
  217. //
  218. // ListPane Methods
  219. //
  220. void SetList(List* plist)
  221. {
  222. if (plist != m_plist) {
  223. if (m_plist != NULL) {
  224. m_plist->GetChangedEvent()->RemoveSink(m_peventSink);
  225. }
  226. if (plist == NULL) {
  227. m_plist = new EmptyList();
  228. } else {
  229. m_plist = plist;
  230. }
  231. m_plist->GetChangedEvent()->AddSink(
  232. m_peventSink = IEventSink::CreateDelegate(this)
  233. );
  234. ListChanged();
  235. }
  236. }
  237. void SetItemPainter(ItemPainter* ppainter)
  238. {
  239. if (ppainter == NULL) {
  240. m_ppainter = new DefaultItemPainter();
  241. } else {
  242. m_ppainter = ppainter;
  243. }
  244. UpdateScrollBar();
  245. UpdateScrollPos();
  246. NeedLayout();
  247. NeedPaint();
  248. }
  249. void SetSelection(ItemID pitem)
  250. {
  251. if (pitem != m_pitemSelection)
  252. {
  253. if (pitem)
  254. {
  255. m_indexSelection = m_plist->GetIndex(pitem);
  256. if (m_indexSelection == -1)
  257. {
  258. assert(false);
  259. pitem = NULL;
  260. }
  261. }
  262. else
  263. m_indexSelection = -1;
  264. m_pitemSelection = pitem;
  265. if (m_bNeedScrollUpdate)
  266. m_iOldSelection = -1;
  267. else
  268. m_iOldSelection = m_indexSelection;
  269. SelectionChanged();
  270. NeedPaint();
  271. }
  272. }
  273. void SetSelection(int nIndex)
  274. {
  275. SetSelection(m_plist->GetItem(nIndex));
  276. }
  277. virtual ItemID GetSelection()
  278. {
  279. return m_pitemSelection;
  280. }
  281. IItemEvent::Source* GetSelectionEventSource()
  282. {
  283. return m_peventSelection;
  284. }
  285. IEventSource* GetDoubleClickEventSource()
  286. {
  287. return m_peventDoubleClick;
  288. }
  289. IEventSource* GetSingleClickEventSource()
  290. {
  291. return m_peventSingleClick;
  292. }
  293. void ScrollToItem(ItemID pitem)
  294. {
  295. int index = 0;
  296. if (pitem != NULL)
  297. index = m_plist->GetIndex(pitem);
  298. // try to center the selected item
  299. SetScrollPos(((2 * index + 1) * GetSignificantSize(*m_ppainter) - GetSignificantSize())/2);
  300. }
  301. void ForceRefresh()
  302. {
  303. NeedPaint();
  304. }
  305. //
  306. // IEventSink Methods
  307. //
  308. bool OnEvent(IEventSource* pevent)
  309. {
  310. ListChanged();
  311. return true;
  312. }
  313. bool OnEvent(IIntegerEventSource* pevent, int value)
  314. {
  315. ScrollBarChanged();
  316. return true;
  317. }
  318. //
  319. // Pane Methods
  320. //
  321. void UpdateLayout()
  322. {
  323. InternalSetSize(
  324. WinPoint(
  325. max(m_ppainter->GetXSize(), m_sizeMin.X()),
  326. max( GetExpand().Y(), m_sizeMin.Y())
  327. )
  328. );
  329. UpdateScrollBar();
  330. }
  331. void VerifyScrollPos()
  332. {
  333. if (m_bNeedScrollUpdate) {
  334. m_bNeedScrollUpdate = false;
  335. if (m_bNeedSelectionOnScreen) {
  336. m_bNeedSelectionOnScreen = false;
  337. //
  338. // Figure out where the selection is
  339. //
  340. int nItemSize = GetSignificantSize(*m_ppainter);
  341. int ySelection = m_indexSelection * nItemSize - GetScrollPos();
  342. //
  343. // Make sure the selection is in the window
  344. //
  345. if (ySelection + GetSignificantSize(*m_ppainter) >= GetSignificantSize()) {
  346. ySelection = GetSignificantSize() - GetSignificantSize(*m_ppainter);
  347. }
  348. if (ySelection < 0) {
  349. ySelection = 0;
  350. }
  351. //
  352. // Adjust the scroll bar so that the selection doesn't move
  353. //
  354. if (m_pscroll && m_plist->GetCount() * GetSignificantSize(*m_ppainter) > GetSignificantSize()) {
  355. SetScrollPos(m_indexSelection * GetSignificantSize(*m_ppainter) - ySelection);
  356. } else {
  357. SetScrollPos(0);
  358. }
  359. } else {
  360. //
  361. // find the top item in the old list
  362. //
  363. int nItemSize = GetSignificantSize(*m_ppainter);
  364. int iOldTop = GetScrollPos() / nItemSize;
  365. //
  366. // use the selected item as the basis if it was visible, otherwise use
  367. // the top item
  368. //
  369. int nLinesPerScreen = GetSignificantSize() / nItemSize;
  370. int iOldBasis;
  371. if (
  372. m_iOldSelection >= iOldTop
  373. && m_iOldSelection < iOldTop + nLinesPerScreen
  374. ) {
  375. //
  376. // visible
  377. //
  378. iOldBasis = m_iOldSelection;
  379. } else {
  380. iOldBasis = iOldTop;
  381. }
  382. //
  383. // get the scroll offset from the basis to the top, so we can try
  384. // to keep the basis perfectly stable.
  385. //
  386. int nTopFromBasis = GetScrollPos() - iOldBasis * nItemSize;
  387. //
  388. // find the new basis...
  389. //
  390. int iNewBasis = FindNearestNewIndex(iOldBasis);
  391. //
  392. // set the scroll position relative to the new basis
  393. //
  394. SetScrollPos(iNewBasis * nItemSize + nTopFromBasis);
  395. }
  396. //
  397. // update m_vectItemsOld to contain the new contents
  398. //
  399. int nNewCount = m_plist->GetCount();
  400. m_vectItemsOld.SetCount(nNewCount);
  401. for (int i = 0; i < nNewCount; i++) {
  402. m_vectItemsOld.Set(i, m_plist->GetItem(i));
  403. }
  404. m_iOldSelection = m_indexSelection;
  405. }
  406. }
  407. int FindNearestNewIndex(int nOldIndex)
  408. {
  409. if (nOldIndex == -1 || m_vectItemsOld.GetCount() == 0)
  410. return -1;
  411. ZAssert(nOldIndex >= 0 && nOldIndex < m_vectItemsOld.GetCount());
  412. int nNewIndex;
  413. // check to see if the old item exists in the new list
  414. nNewIndex = m_plist->GetIndex(m_vectItemsOld[nOldIndex]);
  415. // if we haven't found a new index yet, try searching the items around it
  416. int iDelta = 1;
  417. while (nNewIndex == -1
  418. && (nOldIndex - iDelta >= 0
  419. || nOldIndex + iDelta < m_vectItemsOld.GetCount()))
  420. {
  421. if (nOldIndex - iDelta >= 0)
  422. nNewIndex = m_plist->GetIndex(m_vectItemsOld[nOldIndex - iDelta]);
  423. if (nNewIndex != -1 && nOldIndex + iDelta < m_vectItemsOld.GetCount())
  424. nNewIndex = m_plist->GetIndex(m_vectItemsOld[nOldIndex - iDelta]);
  425. ++iDelta;
  426. }
  427. // if we still haven't found a new index, default to the first item
  428. if (nNewIndex == -1)
  429. {
  430. nNewIndex = 0;
  431. }
  432. return nNewIndex;
  433. }
  434. void Paint(Surface* psurface)
  435. {
  436. VerifyScrollPos();
  437. //
  438. // Find the item at the top of the list
  439. //
  440. int ysize = GetSignificantSize(*m_ppainter);
  441. int index = GetScrollPos() / ysize;
  442. int y = index * ysize - GetScrollPos();
  443. ItemID pitem = m_plist->GetItem(index);
  444. while (
  445. pitem != NULL
  446. && y < GetSignificantSize()
  447. ) {
  448. if (m_bHorizontal)
  449. psurface->Offset(WinPoint(y, 0));
  450. else
  451. psurface->Offset(WinPoint(0, y));
  452. m_ppainter->Paint(
  453. pitem,
  454. psurface,
  455. pitem == m_pitemSelection,
  456. false
  457. );
  458. if (m_bHorizontal)
  459. psurface->Offset(WinPoint(-y, 0));
  460. else
  461. psurface->Offset(WinPoint(0, -y));
  462. y += ysize;
  463. pitem = m_plist->GetNext(pitem);
  464. }
  465. }
  466. //
  467. // IMouseInput
  468. //
  469. MouseResult Button(
  470. IInputProvider* pprovider,
  471. const Point& point,
  472. int button,
  473. bool bCaptured,
  474. bool bInside,
  475. bool bDown
  476. ) {
  477. VerifyScrollPos();
  478. if (button == 0 && bDown) {
  479. int nSize = GetSignificantSize(*m_ppainter);
  480. int nSignificantMouseDim = (int)(m_bHorizontal ? point.X(): point.Y());
  481. SetSelection(m_plist->GetItem((nSignificantMouseDim + GetScrollPos()) / nSize));
  482. NeedPaint();
  483. SelectionChanged();
  484. if (pprovider->IsDoubleClick()) {
  485. m_peventDoubleClick->Trigger();
  486. }
  487. else {
  488. m_peventSingleClick->Trigger();
  489. }
  490. }
  491. return MouseResult();
  492. }
  493. //
  494. // IKeyboardInput
  495. //
  496. bool OnKey(IInputProvider* pprovider, const KeyState& ks, bool& fForceTranslate)
  497. {
  498. VerifyScrollPos();
  499. if (ks.bDown) {
  500. switch (ks.vk) {
  501. case VK_DOWN:
  502. NextItem();
  503. SelectionChanged();
  504. return true;
  505. case VK_UP:
  506. PreviousItem();
  507. SelectionChanged();
  508. return true;
  509. case VK_PRIOR: // page up
  510. PageUp();
  511. SelectionChanged();
  512. return true;
  513. case VK_NEXT: // page down
  514. PageDown();
  515. SelectionChanged();
  516. return true;
  517. }
  518. }
  519. return false;
  520. }
  521. };
  522. /////////////////////////////////////////////////////////////////////////////
  523. //
  524. // Constructor
  525. //
  526. /////////////////////////////////////////////////////////////////////////////
  527. TRef<ListPane> CreateListPane(
  528. const WinPoint& sizeMin,
  529. List* plist,
  530. ItemPainter* ppainter,
  531. ScrollPane* pscroll,
  532. bool bHorizontal
  533. ) {
  534. return new ListPaneImpl<ListPane>(sizeMin, plist, ppainter, pscroll, bHorizontal);
  535. }
  536. /////////////////////////////////////////////////////////////////////////////
  537. //
  538. // StringList
  539. //
  540. /////////////////////////////////////////////////////////////////////////////
  541. class StringListImpl :
  542. public StringList
  543. {
  544. private:
  545. //////////////////////////////////////////////////////////////////////////////
  546. //
  547. // Data members
  548. //
  549. //////////////////////////////////////////////////////////////////////////////
  550. TRef<IEngineFont> m_pfont;
  551. Color m_color;
  552. Color m_colorSelected;
  553. int m_xsize;
  554. TRef<EventSourceImpl> m_peventSource;
  555. TRef<StringListItem> m_pitem;
  556. int m_count;
  557. public:
  558. //////////////////////////////////////////////////////////////////////////////
  559. //
  560. // Constructor
  561. //
  562. //////////////////////////////////////////////////////////////////////////////
  563. StringListImpl(
  564. IEngineFont* pfont,
  565. const Color& color,
  566. const Color& colorSelected,
  567. int xsize
  568. ) :
  569. m_pfont(pfont),
  570. m_color(color),
  571. m_colorSelected(colorSelected),
  572. m_xsize(xsize),
  573. m_count(0)
  574. {
  575. m_peventSource = new EventSourceImpl();
  576. }
  577. //////////////////////////////////////////////////////////////////////////////
  578. //
  579. // StringList Methods
  580. //
  581. //////////////////////////////////////////////////////////////////////////////
  582. void AddItem(const ZString& str)
  583. {
  584. m_count++;
  585. m_pitem = new StringListItem(str, m_pitem);
  586. m_peventSource->Trigger();
  587. }
  588. void SetEmpty()
  589. {
  590. m_count = 0;
  591. m_pitem = NULL;
  592. m_peventSource->Trigger();
  593. }
  594. //////////////////////////////////////////////////////////////////////////////
  595. //
  596. // List Methods
  597. //
  598. //////////////////////////////////////////////////////////////////////////////
  599. int GetCount()
  600. {
  601. return m_count;
  602. }
  603. ItemID GetItem(int index)
  604. {
  605. ZAssert(index >= 0);
  606. if (index < m_count) {
  607. StringListItem* pitem = m_pitem;
  608. while (index > 0) {
  609. pitem = pitem->GetNext();
  610. index--;
  611. }
  612. return pitem;
  613. } else {
  614. return NULL;
  615. }
  616. }
  617. int GetIndex(ItemID pitemFind)
  618. {
  619. StringListItem* pitem = m_pitem;
  620. int index = 0;
  621. while (pitem != NULL) {
  622. if ((ItemID)pitem == pitemFind) {
  623. return index;
  624. }
  625. pitem = pitem->GetNext();
  626. index++;
  627. }
  628. return -1;
  629. }
  630. ItemID GetNext(ItemID pitem)
  631. {
  632. return ((StringListItem*)pitem)->GetNext();
  633. }
  634. IEventSource* GetChangedEvent()
  635. {
  636. return m_peventSource;
  637. }
  638. //////////////////////////////////////////////////////////////////////////////
  639. //
  640. // ItemPainter Methods
  641. //
  642. //////////////////////////////////////////////////////////////////////////////
  643. int GetXSize()
  644. {
  645. return m_xsize;
  646. }
  647. int GetYSize()
  648. {
  649. return m_pfont->GetHeight();
  650. }
  651. void Paint(ItemID pitemArg, Surface* psurface, bool bSelected, bool bFocus)
  652. {
  653. StringListItem* pitem = (StringListItem*)pitemArg;
  654. if (bSelected) {
  655. psurface->FillRect(
  656. WinRect(0, 0, GetXSize(), GetYSize()),
  657. m_colorSelected
  658. );
  659. }
  660. psurface->DrawString(m_pfont, m_color, WinPoint(0, 0), pitem->GetString());
  661. }
  662. };
  663. TRef<StringList> CreateStringList(
  664. IEngineFont* pfont,
  665. const Color& color,
  666. const Color& colorSelected,
  667. int xsize
  668. ) {
  669. return
  670. new StringListImpl(
  671. pfont,
  672. color,
  673. colorSelected,
  674. xsize
  675. );
  676. }
  677. /////////////////////////////////////////////////////////////////////////////
  678. //
  679. // StringListPane
  680. //
  681. /////////////////////////////////////////////////////////////////////////////
  682. class StringListPaneImpl:
  683. public ListPaneImpl<StringListPane>
  684. {
  685. public:
  686. StringListPaneImpl(
  687. const WinPoint& sizeMin,
  688. List* plist,
  689. ItemPainter* ppainter,
  690. ScrollPane* pscroll,
  691. bool bHorizontal,
  692. IEngineFont* pfont,
  693. const Color& color,
  694. const Color& colorSelected
  695. ) :
  696. ListPaneImpl<StringListPane>(sizeMin, plist, ppainter, pscroll, bHorizontal)
  697. {
  698. m_pStringList = CreateStringList(pfont, color, colorSelected, sizeMin.X());
  699. SetList(m_pStringList);
  700. SetItemPainter(m_pStringList);
  701. }
  702. TRef<StringList> GetStringList()
  703. {
  704. return m_pStringList;
  705. }
  706. private:
  707. TRef<StringList> m_pStringList;
  708. };
  709. TRef<StringListPane> CreateStringListPane(
  710. const WinPoint& sizeMin,
  711. List* plist,
  712. ItemPainter* ppainter,
  713. ScrollPane* pscroll,
  714. bool bHorizontal,
  715. IEngineFont* pfont,
  716. const Color& color,
  717. const Color& colorSelected
  718. )
  719. {
  720. return new StringListPaneImpl(sizeMin, plist, ppainter, pscroll, bHorizontal, pfont, color, colorSelected);
  721. }