UIContainer.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. #include "StdAfx.h"
  2. namespace DuiLib
  3. {
  4. /////////////////////////////////////////////////////////////////////////////////////
  5. //
  6. //
  7. CContainerUI::CContainerUI()
  8. : m_iChildPadding(0),
  9. m_bAutoDestroy(true),
  10. m_bDelayedDestroy(true),
  11. m_bMouseChildEnabled(true),
  12. m_pVerticalScrollBar(NULL),
  13. m_pHorizontalScrollBar(NULL),
  14. m_bScrollProcess(false),
  15. m_iItemFont (-1)
  16. {
  17. ::ZeroMemory(&m_rcInset, sizeof(m_rcInset));
  18. }
  19. CContainerUI::~CContainerUI ()
  20. {
  21. m_bDelayedDestroy = false;
  22. RemoveAll();
  23. if( m_pVerticalScrollBar ) delete m_pVerticalScrollBar;
  24. if( m_pHorizontalScrollBar ) delete m_pHorizontalScrollBar;
  25. }
  26. LPCTSTR CContainerUI::GetClass() const
  27. {
  28. return _T("ContainerUI");
  29. }
  30. LPVOID CContainerUI::GetInterface(LPCTSTR pstrName)
  31. {
  32. if( _tcscmp(pstrName, _T("IContainer")) == 0 ) return static_cast<IContainerUI*>(this);
  33. else if( _tcscmp(pstrName, DUI_CTR_CONTAINER) == 0 ) return static_cast<CContainerUI*>(this);
  34. return CControlUI::GetInterface(pstrName);
  35. }
  36. CControlUI* CContainerUI::GetItemAt(int iIndex) const
  37. {
  38. if( iIndex < 0 || iIndex >= m_items.GetSize() ) return NULL;
  39. return static_cast<CControlUI*>(m_items[iIndex]);
  40. }
  41. int CContainerUI::GetItemIndex(CControlUI* pControl) const
  42. {
  43. for( int it = 0; it < m_items.GetSize(); it++ ) {
  44. if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
  45. return it;
  46. }
  47. }
  48. return -1;
  49. }
  50. bool CContainerUI::SetItemIndex(CControlUI* pControl, int iIndex)
  51. {
  52. for( int it = 0; it < m_items.GetSize(); it++ ) {
  53. if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
  54. NeedUpdate();
  55. m_items.Remove(it);
  56. return m_items.InsertAt(iIndex, pControl);
  57. }
  58. }
  59. return false;
  60. }
  61. int CContainerUI::GetCount() const
  62. {
  63. return m_items.GetSize();
  64. }
  65. bool CContainerUI::Add(CControlUI* pControl)
  66. {
  67. if( pControl == NULL) return false;
  68. if( m_pManager != NULL ) m_pManager->InitControls(pControl, this);
  69. if( IsVisible() ) NeedUpdate();
  70. else pControl->SetInternVisible(false);
  71. return m_items.Add(pControl);
  72. }
  73. CControlUI* CContainerUI::Add (LPCTSTR lpXMLFile, LPCTSTR name)
  74. {
  75. if (lpXMLFile)
  76. {
  77. DuiLib::CDialogBuilder builder;
  78. auto element = builder.Create (lpXMLFile);
  79. if(element)
  80. {
  81. if(name != nullptr)
  82. {
  83. element->SetName (name);
  84. }
  85. if(Add (element))
  86. return element;
  87. }
  88. }
  89. return nullptr;
  90. }
  91. bool CContainerUI::AddAt (CControlUI* pControl, int iIndex)
  92. {
  93. if( pControl == NULL) return false;
  94. if( m_pManager != NULL ) m_pManager->InitControls(pControl, this);
  95. if( IsVisible() ) NeedUpdate();
  96. else pControl->SetInternVisible(false);
  97. return m_items.InsertAt(iIndex, pControl);
  98. }
  99. DuiLib::CControlUI* CContainerUI::AddAt (LPCTSTR lpXMLFile, int iIndex, LPCTSTR name /*= nullptr*/)
  100. {
  101. DuiLib::CDialogBuilder builder;
  102. auto element = builder.Create (lpXMLFile);
  103. if(element)
  104. {
  105. if(name != nullptr)
  106. {
  107. element->SetName (name);
  108. }
  109. if(AddAt (element, iIndex))
  110. return element;
  111. }
  112. return nullptr;
  113. }
  114. bool CContainerUI::Remove (CControlUI* pControl)
  115. {
  116. if( pControl == NULL) return false;
  117. for( int it = 0; it < m_items.GetSize(); it++ ) {
  118. if( static_cast<CControlUI*>(m_items[it]) == pControl ) {
  119. NeedUpdate();
  120. if( m_bAutoDestroy ) {
  121. if( m_bDelayedDestroy && m_pManager ) m_pManager->AddDelayedCleanup(pControl);
  122. else delete pControl;
  123. }
  124. return m_items.Remove(it);
  125. }
  126. }
  127. return false;
  128. }
  129. bool CContainerUI::RemoveAt(int iIndex)
  130. {
  131. CControlUI* pControl = GetItemAt(iIndex);
  132. if (pControl != NULL) {
  133. return CContainerUI::Remove(pControl);
  134. }
  135. return false;
  136. }
  137. void CContainerUI::RemoveAll()
  138. {
  139. for( int it = 0; m_bAutoDestroy && it < m_items.GetSize(); it++ ) {
  140. if(m_bDelayedDestroy && m_pManager)
  141. {
  142. m_pManager->AddDelayedCleanup (static_cast<CControlUI*>(m_items[it]));
  143. }
  144. else
  145. {
  146. auto p = static_cast<CControlUI*>(m_items[it]);
  147. delete static_cast<CControlUI*>(m_items[it]);
  148. }
  149. }
  150. m_items.Empty();
  151. NeedUpdate();
  152. }
  153. bool CContainerUI::IsAutoDestroy() const
  154. {
  155. return m_bAutoDestroy;
  156. }
  157. void CContainerUI::SetAutoDestroy(bool bAuto)
  158. {
  159. m_bAutoDestroy = bAuto;
  160. }
  161. bool CContainerUI::IsDelayedDestroy() const
  162. {
  163. return m_bDelayedDestroy;
  164. }
  165. void CContainerUI::SetDelayedDestroy(bool bDelayed)
  166. {
  167. m_bDelayedDestroy = bDelayed;
  168. }
  169. RECT CContainerUI::GetInset() const
  170. {
  171. return m_rcInset;
  172. }
  173. void CContainerUI::SetInset(RECT rcInset)
  174. {
  175. m_rcInset = rcInset;
  176. NeedUpdate();
  177. }
  178. int CContainerUI::GetChildPadding() const
  179. {
  180. return m_iChildPadding;
  181. }
  182. void CContainerUI::SetChildPadding(int iPadding)
  183. {
  184. m_iChildPadding = iPadding;
  185. NeedUpdate();
  186. }
  187. bool CContainerUI::IsMouseChildEnabled() const
  188. {
  189. return m_bMouseChildEnabled;
  190. }
  191. void CContainerUI::SetMouseChildEnabled(bool bEnable)
  192. {
  193. m_bMouseChildEnabled = bEnable;
  194. }
  195. void CContainerUI::SetVisible(bool bVisible)
  196. {
  197. if( m_bVisible == bVisible ) return;
  198. CControlUI::SetVisible(bVisible);
  199. for( int it = 0; it < m_items.GetSize(); it++ ) {
  200. static_cast<CControlUI*>(m_items[it])->SetInternVisible(IsVisible());
  201. }
  202. }
  203. // 逻辑上,对于Container控件不公开此方法
  204. // 调用此方法的结果是,内部子控件隐藏,控件本身依然显示,背景等效果存在
  205. void CContainerUI::SetInternVisible(bool bVisible)
  206. {
  207. CControlUI::SetInternVisible(bVisible);
  208. if( m_items.IsEmpty() ) return;
  209. for( int it = 0; it < m_items.GetSize(); it++ ) {
  210. // 控制子控件显示状态
  211. // InternVisible状态应由子控件自己控制
  212. static_cast<CControlUI*>(m_items[it])->SetInternVisible(IsVisible());
  213. }
  214. }
  215. void CContainerUI::SetMouseEnabled(bool bEnabled)
  216. {
  217. if( m_pVerticalScrollBar != NULL ) m_pVerticalScrollBar->SetMouseEnabled(bEnabled);
  218. if( m_pHorizontalScrollBar != NULL ) m_pHorizontalScrollBar->SetMouseEnabled(bEnabled);
  219. CControlUI::SetMouseEnabled(bEnabled);
  220. }
  221. void CContainerUI::DoEvent(TEventUI& event)
  222. {
  223. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  224. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  225. else CControlUI::DoEvent(event);
  226. return;
  227. }
  228. if( event.Type == UIEVENT_SETFOCUS )
  229. {
  230. m_bFocused = true;
  231. return;
  232. }
  233. if( event.Type == UIEVENT_KILLFOCUS )
  234. {
  235. m_bFocused = false;
  236. return;
  237. }
  238. if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() && m_pVerticalScrollBar->IsEnabled() )
  239. {
  240. if( event.Type == UIEVENT_KEYDOWN )
  241. {
  242. switch( event.chKey ) {
  243. case VK_DOWN:
  244. LineDown();
  245. return;
  246. case VK_UP:
  247. LineUp();
  248. return;
  249. case VK_NEXT:
  250. PageDown();
  251. return;
  252. case VK_PRIOR:
  253. PageUp();
  254. return;
  255. case VK_HOME:
  256. HomeUp();
  257. return;
  258. case VK_END:
  259. EndDown();
  260. return;
  261. }
  262. }
  263. else if( event.Type == UIEVENT_SCROLLWHEEL )
  264. {
  265. switch( LOWORD(event.wParam) ) {
  266. case SB_LINEUP:
  267. LineUp();
  268. return;
  269. case SB_LINEDOWN:
  270. LineDown();
  271. return;
  272. }
  273. }
  274. }
  275. else if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() && m_pHorizontalScrollBar->IsEnabled() ) {
  276. if( event.Type == UIEVENT_KEYDOWN )
  277. {
  278. switch( event.chKey ) {
  279. case VK_DOWN:
  280. LineRight();
  281. return;
  282. case VK_UP:
  283. LineLeft();
  284. return;
  285. case VK_NEXT:
  286. PageRight();
  287. return;
  288. case VK_PRIOR:
  289. PageLeft();
  290. return;
  291. case VK_HOME:
  292. HomeLeft();
  293. return;
  294. case VK_END:
  295. EndRight();
  296. return;
  297. }
  298. }
  299. else if( event.Type == UIEVENT_SCROLLWHEEL )
  300. {
  301. switch( LOWORD(event.wParam) ) {
  302. case SB_LINEUP:
  303. LineLeft();
  304. return;
  305. case SB_LINEDOWN:
  306. LineRight();
  307. return;
  308. }
  309. }
  310. }
  311. CControlUI::DoEvent(event);
  312. }
  313. SIZE CContainerUI::GetScrollPos() const
  314. {
  315. SIZE sz = {0, 0};
  316. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) sz.cy = m_pVerticalScrollBar->GetScrollPos();
  317. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) sz.cx = m_pHorizontalScrollBar->GetScrollPos();
  318. return sz;
  319. }
  320. SIZE CContainerUI::GetScrollRange() const
  321. {
  322. SIZE sz = {0, 0};
  323. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) sz.cy = m_pVerticalScrollBar->GetScrollRange();
  324. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) sz.cx = m_pHorizontalScrollBar->GetScrollRange();
  325. return sz;
  326. }
  327. void CContainerUI::SetScrollPos(SIZE szPos)
  328. {
  329. int cx = 0;
  330. int cy = 0;
  331. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  332. int iLastScrollPos = m_pVerticalScrollBar->GetScrollPos();
  333. m_pVerticalScrollBar->SetScrollPos(szPos.cy);
  334. cy = m_pVerticalScrollBar->GetScrollPos() - iLastScrollPos;
  335. }
  336. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  337. int iLastScrollPos = m_pHorizontalScrollBar->GetScrollPos();
  338. m_pHorizontalScrollBar->SetScrollPos(szPos.cx);
  339. cx = m_pHorizontalScrollBar->GetScrollPos() - iLastScrollPos;
  340. }
  341. if( cx == 0 && cy == 0 ) return;
  342. for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
  343. CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
  344. if( !pControl->IsVisible() ) continue;
  345. if( pControl->IsFloat() ) continue;
  346. pControl->Move(CDuiSize(-cx, -cy), false);
  347. }
  348. Invalidate();
  349. }
  350. void CContainerUI::LineUp()
  351. {
  352. int cyLine = 8;
  353. if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8;
  354. SIZE sz = GetScrollPos();
  355. sz.cy -= cyLine;
  356. SetScrollPos(sz);
  357. }
  358. void CContainerUI::LineDown()
  359. {
  360. int cyLine = 8;
  361. if( m_pManager ) cyLine = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 8;
  362. SIZE sz = GetScrollPos();
  363. sz.cy += cyLine;
  364. SetScrollPos(sz);
  365. }
  366. void CContainerUI::PageUp()
  367. {
  368. SIZE sz = GetScrollPos();
  369. int iOffset = m_rcItem.bottom - m_rcItem.top - m_rcInset.top - m_rcInset.bottom;
  370. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
  371. sz.cy -= iOffset;
  372. SetScrollPos(sz);
  373. }
  374. void CContainerUI::PageDown()
  375. {
  376. SIZE sz = GetScrollPos();
  377. int iOffset = m_rcItem.bottom - m_rcItem.top - m_rcInset.top - m_rcInset.bottom;
  378. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
  379. sz.cy += iOffset;
  380. SetScrollPos(sz);
  381. }
  382. void CContainerUI::HomeUp()
  383. {
  384. SIZE sz = GetScrollPos();
  385. sz.cy = 0;
  386. SetScrollPos(sz);
  387. }
  388. void CContainerUI::EndDown()
  389. {
  390. SIZE sz = GetScrollPos();
  391. sz.cy = GetScrollRange().cy;
  392. SetScrollPos(sz);
  393. }
  394. void CContainerUI::LineLeft()
  395. {
  396. SIZE sz = GetScrollPos();
  397. sz.cx -= 8;
  398. SetScrollPos(sz);
  399. }
  400. void CContainerUI::LineRight()
  401. {
  402. SIZE sz = GetScrollPos();
  403. sz.cx += 8;
  404. SetScrollPos(sz);
  405. }
  406. void CContainerUI::PageLeft()
  407. {
  408. SIZE sz = GetScrollPos();
  409. int iOffset = m_rcItem.right - m_rcItem.left - m_rcInset.left - m_rcInset.right;
  410. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) iOffset -= m_pVerticalScrollBar->GetFixedWidth();
  411. sz.cx -= iOffset;
  412. SetScrollPos(sz);
  413. }
  414. void CContainerUI::PageRight()
  415. {
  416. SIZE sz = GetScrollPos();
  417. int iOffset = m_rcItem.right - m_rcItem.left - m_rcInset.left - m_rcInset.right;
  418. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) iOffset -= m_pVerticalScrollBar->GetFixedWidth();
  419. sz.cx += iOffset;
  420. SetScrollPos(sz);
  421. }
  422. void CContainerUI::HomeLeft()
  423. {
  424. SIZE sz = GetScrollPos();
  425. sz.cx = 0;
  426. SetScrollPos(sz);
  427. }
  428. void CContainerUI::EndRight()
  429. {
  430. SIZE sz = GetScrollPos();
  431. sz.cx = GetScrollRange().cx;
  432. SetScrollPos(sz);
  433. }
  434. void CContainerUI::EnableScrollBar(bool bEnableVertical, bool bEnableHorizontal)
  435. {
  436. if( bEnableVertical && !m_pVerticalScrollBar ) {
  437. m_pVerticalScrollBar = new CScrollBarUI;
  438. m_pVerticalScrollBar->SetOwner(this);
  439. m_pVerticalScrollBar->SetManager(m_pManager, NULL, false);
  440. if ( m_pManager ) {
  441. LPCTSTR pDefaultAttributes = m_pManager->GetDefaultAttributeList(_T("VScrollBar"));
  442. if( pDefaultAttributes ) {
  443. m_pVerticalScrollBar->ApplyAttributeList(pDefaultAttributes);
  444. }
  445. }
  446. }
  447. else if( !bEnableVertical && m_pVerticalScrollBar ) {
  448. delete m_pVerticalScrollBar;
  449. m_pVerticalScrollBar = NULL;
  450. }
  451. if( bEnableHorizontal && !m_pHorizontalScrollBar ) {
  452. m_pHorizontalScrollBar = new CScrollBarUI;
  453. m_pHorizontalScrollBar->SetHorizontal(true);
  454. m_pHorizontalScrollBar->SetOwner(this);
  455. m_pHorizontalScrollBar->SetManager(m_pManager, NULL, false);
  456. if ( m_pManager ) {
  457. LPCTSTR pDefaultAttributes = m_pManager->GetDefaultAttributeList(_T("HScrollBar"));
  458. if( pDefaultAttributes ) {
  459. m_pHorizontalScrollBar->ApplyAttributeList(pDefaultAttributes);
  460. }
  461. }
  462. }
  463. else if( !bEnableHorizontal && m_pHorizontalScrollBar ) {
  464. delete m_pHorizontalScrollBar;
  465. m_pHorizontalScrollBar = NULL;
  466. }
  467. NeedUpdate();
  468. }
  469. CScrollBarUI* CContainerUI::GetVerticalScrollBar() const
  470. {
  471. return m_pVerticalScrollBar;
  472. }
  473. CScrollBarUI* CContainerUI::GetHorizontalScrollBar() const
  474. {
  475. return m_pHorizontalScrollBar;
  476. }
  477. void CContainerUI::SetItemFont (int iIndex)
  478. {
  479. m_iItemFont = iIndex;
  480. }
  481. int CContainerUI::GetItemFont () const
  482. {
  483. return m_iItemFont;
  484. }
  485. int CContainerUI::FindSelectable (int iIndex, bool bForward /*= true*/) const
  486. {
  487. // NOTE: This is actually a helper-function for the list/combo/ect controls
  488. // that allow them to find the next enabled/available selectable item
  489. if( GetCount() == 0 ) return -1;
  490. iIndex = CLAMP(iIndex, 0, GetCount() - 1);
  491. if( bForward ) {
  492. for( int i = iIndex; i < GetCount(); i++ ) {
  493. if( GetItemAt(i)->GetInterface(_T("ListItem")) != NULL
  494. && GetItemAt(i)->IsVisible()
  495. && GetItemAt(i)->IsEnabled() ) return i;
  496. }
  497. return -1;
  498. }
  499. else {
  500. for( int i = iIndex; i >= 0; --i ) {
  501. if( GetItemAt(i)->GetInterface(_T("ListItem")) != NULL
  502. && GetItemAt(i)->IsVisible()
  503. && GetItemAt(i)->IsEnabled() ) return i;
  504. }
  505. return FindSelectable(0, true);
  506. }
  507. }
  508. RECT CContainerUI::GetClientPos() const
  509. {
  510. RECT rc = m_rcItem;
  511. rc.left += m_rcInset.left;
  512. rc.top += m_rcInset.top;
  513. rc.right -= m_rcInset.right;
  514. rc.bottom -= m_rcInset.bottom;
  515. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  516. rc.top -= m_pVerticalScrollBar->GetScrollPos();
  517. rc.bottom -= m_pVerticalScrollBar->GetScrollPos();
  518. rc.bottom += m_pVerticalScrollBar->GetScrollRange();
  519. rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  520. }
  521. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  522. rc.left -= m_pHorizontalScrollBar->GetScrollPos();
  523. rc.right -= m_pHorizontalScrollBar->GetScrollPos();
  524. rc.right += m_pHorizontalScrollBar->GetScrollRange();
  525. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  526. }
  527. return rc;
  528. }
  529. void CContainerUI::SetPos(RECT rc, bool bNeedInvalidate)
  530. {
  531. CControlUI::SetPos(rc, bNeedInvalidate);
  532. if( m_items.IsEmpty() ) return;
  533. rc = m_rcItem;
  534. rc.left += m_rcInset.left;
  535. rc.top += m_rcInset.top;
  536. rc.right -= m_rcInset.right;
  537. rc.bottom -= m_rcInset.bottom;
  538. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  539. rc.top -= m_pVerticalScrollBar->GetScrollPos();
  540. rc.bottom -= m_pVerticalScrollBar->GetScrollPos();
  541. rc.bottom += m_pVerticalScrollBar->GetScrollRange();
  542. rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  543. }
  544. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  545. rc.left -= m_pHorizontalScrollBar->GetScrollPos();
  546. rc.right -= m_pHorizontalScrollBar->GetScrollPos();
  547. rc.right += m_pHorizontalScrollBar->GetScrollRange();
  548. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  549. }
  550. for( int it = 0; it < m_items.GetSize(); it++ ) {
  551. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  552. if( !pControl->IsVisible() ) continue;
  553. if( pControl->IsFloat() ) {
  554. SetFloatPos(it);
  555. }
  556. else {
  557. SIZE sz = { rc.right - rc.left, rc.bottom - rc.top };
  558. if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
  559. if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
  560. if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
  561. if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
  562. RECT rcCtrl = { rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy };
  563. pControl->SetPos(rcCtrl, false);
  564. }
  565. }
  566. }
  567. void CContainerUI::Move(SIZE szOffset, bool bNeedInvalidate)
  568. {
  569. CControlUI::Move(szOffset, bNeedInvalidate);
  570. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) m_pVerticalScrollBar->Move(szOffset, false);
  571. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) m_pHorizontalScrollBar->Move(szOffset, false);
  572. for( int it = 0; it < m_items.GetSize(); it++ ) {
  573. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  574. if( pControl != NULL && pControl->IsVisible() ) pControl->Move(szOffset, false);
  575. }
  576. }
  577. void CContainerUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  578. {
  579. if( _tcscmp(pstrName, _T("inset")) == 0 ) {
  580. RECT rcInset = { 0 };
  581. LPTSTR pstr = NULL;
  582. rcInset.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  583. rcInset.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  584. rcInset.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  585. rcInset.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  586. SetInset(rcInset);
  587. }
  588. else if( _tcscmp(pstrName, _T("mousechild")) == 0 ) SetMouseChildEnabled(_tcscmp(pstrValue, _T("true")) == 0);
  589. else if( _tcscmp(pstrName, _T("vscrollbar")) == 0 ) {
  590. EnableScrollBar(_tcscmp(pstrValue, _T("true")) == 0, GetHorizontalScrollBar() != NULL);
  591. }
  592. else if( _tcscmp(pstrName, _T("vscrollbarstyle")) == 0 ) {
  593. EnableScrollBar(true, GetHorizontalScrollBar() != NULL);
  594. if( GetVerticalScrollBar() ) GetVerticalScrollBar()->ApplyAttributeList(pstrValue);
  595. }
  596. else if( _tcscmp(pstrName, _T("hscrollbar")) == 0 ) {
  597. EnableScrollBar(GetVerticalScrollBar() != NULL, _tcscmp(pstrValue, _T("true")) == 0);
  598. }
  599. else if( _tcscmp(pstrName, _T("hscrollbarstyle")) == 0 ) {
  600. EnableScrollBar(GetVerticalScrollBar() != NULL, true);
  601. if( GetHorizontalScrollBar() ) GetHorizontalScrollBar()->ApplyAttributeList(pstrValue);
  602. }
  603. else if(_tcscmp (pstrName, _T ("childpadding")) == 0)
  604. {
  605. SetChildPadding (_ttoi (pstrValue));
  606. }
  607. else if(_tcscmp (pstrName, _T ("itemfont")) == 0)
  608. {
  609. SetItemFont (_ttoi (pstrValue));
  610. }
  611. else CControlUI::SetAttribute(pstrName, pstrValue);
  612. }
  613. void CContainerUI::SetManager(CPaintManagerUI* pManager, CControlUI* pParent, bool bInit)
  614. {
  615. for( int it = 0; it < m_items.GetSize(); it++ ) {
  616. static_cast<CControlUI*>(m_items[it])->SetManager(pManager, this, bInit);
  617. }
  618. if( m_pVerticalScrollBar != NULL ) m_pVerticalScrollBar->SetManager(pManager, this, bInit);
  619. if( m_pHorizontalScrollBar != NULL ) m_pHorizontalScrollBar->SetManager(pManager, this, bInit);
  620. CControlUI::SetManager(pManager, pParent, bInit);
  621. }
  622. CControlUI* CContainerUI::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags)
  623. {
  624. // Check if this guy is valid
  625. if( (uFlags & UIFIND_VISIBLE) != 0 && !IsVisible() ) return NULL;
  626. if( (uFlags & UIFIND_ENABLED) != 0 && !IsEnabled() ) return NULL;
  627. if( (uFlags & UIFIND_HITTEST) != 0 && !::PtInRect(&m_rcItem, *(static_cast<LPPOINT>(pData))) ) return NULL;
  628. if( (uFlags & UIFIND_UPDATETEST) != 0 && Proc(this, pData) != NULL ) return NULL;
  629. CControlUI* pResult = NULL;
  630. if( (uFlags & UIFIND_ME_FIRST) != 0 ) {
  631. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData);
  632. }
  633. if( pResult == NULL && m_pVerticalScrollBar != NULL ) {
  634. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = m_pVerticalScrollBar->FindControl(Proc, pData, uFlags);
  635. }
  636. if( pResult == NULL && m_pHorizontalScrollBar != NULL ) {
  637. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = m_pHorizontalScrollBar->FindControl(Proc, pData, uFlags);
  638. }
  639. if( pResult != NULL ) return pResult;
  640. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseChildEnabled() ) {
  641. RECT rc = m_rcItem;
  642. rc.left += m_rcInset.left;
  643. rc.top += m_rcInset.top;
  644. rc.right -= m_rcInset.right;
  645. rc.bottom -= m_rcInset.bottom;
  646. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  647. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  648. if( (uFlags & UIFIND_TOP_FIRST) != 0 ) {
  649. for( int it = m_items.GetSize() - 1; it >= 0; it-- ) {
  650. pResult = static_cast<CControlUI*>(m_items[it])->FindControl(Proc, pData, uFlags);
  651. if( pResult != NULL ) {
  652. if( (uFlags & UIFIND_HITTEST) != 0 && !pResult->IsFloat() && !::PtInRect(&rc, *(static_cast<LPPOINT>(pData))) )
  653. continue;
  654. else
  655. return pResult;
  656. }
  657. }
  658. }
  659. else {
  660. for( int it = 0; it < m_items.GetSize(); it++ ) {
  661. pResult = static_cast<CControlUI*>(m_items[it])->FindControl(Proc, pData, uFlags);
  662. if( pResult != NULL ) {
  663. if( (uFlags & UIFIND_HITTEST) != 0 && !pResult->IsFloat() && !::PtInRect(&rc, *(static_cast<LPPOINT>(pData))) )
  664. continue;
  665. else
  666. return pResult;
  667. }
  668. }
  669. }
  670. }
  671. pResult = NULL;
  672. if( pResult == NULL && (uFlags & UIFIND_ME_FIRST) == 0 ) {
  673. if( (uFlags & UIFIND_HITTEST) == 0 || IsMouseEnabled() ) pResult = Proc(this, pData);
  674. }
  675. return pResult;
  676. }
  677. void CContainerUI::DoPaint(HDC hDC, const RECT& rcPaint)
  678. {
  679. RECT rcTemp = { 0 };
  680. if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return;
  681. CRenderClip clip;
  682. CRenderClip::GenerateClip(hDC, rcTemp, clip);
  683. CControlUI::DoPaint(hDC, rcPaint);
  684. if( m_items.GetSize() > 0 ) {
  685. RECT rc = m_rcItem;
  686. rc.left += m_rcInset.left;
  687. rc.top += m_rcInset.top;
  688. rc.right -= m_rcInset.right;
  689. rc.bottom -= m_rcInset.bottom;
  690. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  691. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  692. if( !::IntersectRect(&rcTemp, &rcPaint, &rc) ) {
  693. for( int it = 0; it < m_items.GetSize(); it++ ) {
  694. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  695. if( !pControl->IsVisible() ) continue;
  696. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  697. if( pControl ->IsFloat() ) {
  698. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  699. pControl->Paint(hDC, rcPaint);
  700. }
  701. }
  702. }
  703. else {
  704. CRenderClip childClip;
  705. CRenderClip::GenerateClip(hDC, rcTemp, childClip);
  706. for( int it = 0; it < m_items.GetSize(); it++ ) {
  707. CControlUI* pControl = static_cast<CControlUI*>(m_items[it]);
  708. if( !pControl->IsVisible() ) continue;
  709. if( !::IntersectRect(&rcTemp, &rcPaint, &pControl->GetPos()) ) continue;
  710. if( pControl ->IsFloat() ) {
  711. if( !::IntersectRect(&rcTemp, &m_rcItem, &pControl->GetPos()) ) continue;
  712. CRenderClip::UseOldClipBegin(hDC, childClip);
  713. pControl->Paint(hDC, rcPaint);
  714. CRenderClip::UseOldClipEnd(hDC, childClip);
  715. }
  716. else {
  717. if( !::IntersectRect(&rcTemp, &rc, &pControl->GetPos()) ) continue;
  718. pControl->Paint(hDC, rcPaint);
  719. }
  720. }
  721. }
  722. }
  723. if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsVisible() ) {
  724. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pVerticalScrollBar->GetPos()) ) {
  725. m_pVerticalScrollBar->Paint(hDC, rcPaint);
  726. }
  727. }
  728. if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() ) {
  729. if( ::IntersectRect(&rcTemp, &rcPaint, &m_pHorizontalScrollBar->GetPos()) ) {
  730. m_pHorizontalScrollBar->Paint(hDC, rcPaint);
  731. }
  732. }
  733. }
  734. void CContainerUI::SetFloatPos(int iIndex)
  735. {
  736. // 因为CControlUI::SetPos对float的操作影响,这里不能对float组件添加滚动条的影响
  737. if( iIndex < 0 || iIndex >= m_items.GetSize() ) return;
  738. CControlUI* pControl = static_cast<CControlUI*>(m_items[iIndex]);
  739. if( !pControl->IsVisible() ) return;
  740. if( !pControl->IsFloat() ) return;
  741. SIZE szXY = pControl->GetFixedXY();
  742. SIZE sz = {pControl->GetFixedWidth(), pControl->GetFixedHeight()};
  743. TPercentInfo rcPercent = pControl->GetFloatPercent();
  744. LONG width = m_rcItem.right - m_rcItem.left;
  745. LONG height = m_rcItem.bottom - m_rcItem.top;
  746. RECT rcCtrl = { 0 };
  747. rcCtrl.left = (LONG)(width*rcPercent.left) + szXY.cx;
  748. rcCtrl.top = (LONG)(height*rcPercent.top) + szXY.cy;
  749. rcCtrl.right = (LONG)(width*rcPercent.right) + szXY.cx + sz.cx;
  750. rcCtrl.bottom = (LONG)(height*rcPercent.bottom) + szXY.cy + sz.cy;
  751. pControl->SetPos(rcCtrl, false);
  752. }
  753. void CContainerUI::ProcessScrollBar(RECT rc, int cxRequired, int cyRequired)
  754. {
  755. if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsVisible() ) {
  756. RECT rcScrollBarPos = { rc.left, rc.bottom, rc.right, rc.bottom + m_pHorizontalScrollBar->GetFixedHeight()};
  757. m_pHorizontalScrollBar->SetPos(rcScrollBarPos, false);
  758. }
  759. if( m_pVerticalScrollBar == NULL ) return;
  760. if( cyRequired > rc.bottom - rc.top && !m_pVerticalScrollBar->IsVisible() ) {
  761. m_pVerticalScrollBar->SetVisible(true);
  762. m_pVerticalScrollBar->SetScrollRange(cyRequired - (rc.bottom - rc.top));
  763. m_pVerticalScrollBar->SetScrollPos(0);
  764. m_bScrollProcess = true;
  765. if( !IsFloat() ) SetPos(GetPos());
  766. else SetPos(GetRelativePos());
  767. m_bScrollProcess = false;
  768. return;
  769. }
  770. // No scrollbar required
  771. if( !m_pVerticalScrollBar->IsVisible() ) return;
  772. // Scroll not needed anymore?
  773. int cyScroll = cyRequired - (rc.bottom - rc.top);
  774. if( cyScroll <= 0 && !m_bScrollProcess) {
  775. m_pVerticalScrollBar->SetVisible(false);
  776. m_pVerticalScrollBar->SetScrollPos(0);
  777. m_pVerticalScrollBar->SetScrollRange(0);
  778. if( !IsFloat() ) SetPos(GetPos());
  779. else SetPos(GetRelativePos());
  780. }
  781. else
  782. {
  783. RECT rcScrollBarPos = { rc.right, rc.top, rc.right + m_pVerticalScrollBar->GetFixedWidth(), rc.bottom };
  784. m_pVerticalScrollBar->SetPos(rcScrollBarPos, false);
  785. if( m_pVerticalScrollBar->GetScrollRange() != cyScroll ) {
  786. int iScrollPos = m_pVerticalScrollBar->GetScrollPos();
  787. m_pVerticalScrollBar->SetScrollRange(::abs(cyScroll));
  788. if( m_pVerticalScrollBar->GetScrollRange() == 0 ) {
  789. m_pVerticalScrollBar->SetVisible(false);
  790. m_pVerticalScrollBar->SetScrollPos(0);
  791. }
  792. if( iScrollPos > m_pVerticalScrollBar->GetScrollPos() ) {
  793. if( !IsFloat() ) SetPos(GetPos(), false);
  794. else SetPos(GetRelativePos(), false);
  795. }
  796. }
  797. }
  798. }
  799. LPCTSTR CContainerUI::GetChildXmlFile () const
  800. {
  801. return nullptr;
  802. }
  803. void CContainerUI::DoInit ()
  804. {
  805. Add (GetChildXmlFile ());
  806. }
  807. bool CContainerUI::SetSubControlText (LPCTSTR pstrSubControlName, LPCTSTR pstrText)
  808. {
  809. CControlUI* pSubControl=NULL;
  810. pSubControl=this->FindSubControl(pstrSubControlName);
  811. if (pSubControl!=NULL)
  812. {
  813. pSubControl->SetText(pstrText);
  814. return TRUE;
  815. }
  816. else
  817. return FALSE;
  818. }
  819. bool CContainerUI::SetSubControlFixedHeight( LPCTSTR pstrSubControlName,int cy )
  820. {
  821. CControlUI* pSubControl=NULL;
  822. pSubControl=this->FindSubControl(pstrSubControlName);
  823. if (pSubControl!=NULL)
  824. {
  825. pSubControl->SetFixedHeight(cy);
  826. return TRUE;
  827. }
  828. else
  829. return FALSE;
  830. }
  831. bool CContainerUI::SetSubControlFixedWdith( LPCTSTR pstrSubControlName,int cx )
  832. {
  833. CControlUI* pSubControl=NULL;
  834. pSubControl=this->FindSubControl(pstrSubControlName);
  835. if (pSubControl!=NULL)
  836. {
  837. pSubControl->SetFixedWidth(cx);
  838. return TRUE;
  839. }
  840. else
  841. return FALSE;
  842. }
  843. bool CContainerUI::SetSubControlUserData( LPCTSTR pstrSubControlName,LPCTSTR pstrText )
  844. {
  845. CControlUI* pSubControl=NULL;
  846. pSubControl=this->FindSubControl(pstrSubControlName);
  847. if (pSubControl!=NULL)
  848. {
  849. pSubControl->SetUserData(pstrText);
  850. return TRUE;
  851. }
  852. else
  853. return FALSE;
  854. }
  855. CDuiString CContainerUI::GetSubControlText( LPCTSTR pstrSubControlName )
  856. {
  857. CControlUI* pSubControl=NULL;
  858. pSubControl=this->FindSubControl(pstrSubControlName);
  859. if (pSubControl==NULL)
  860. return _T("");
  861. else
  862. return pSubControl->GetText();
  863. }
  864. int CContainerUI::GetSubControlFixedHeight( LPCTSTR pstrSubControlName )
  865. {
  866. CControlUI* pSubControl=NULL;
  867. pSubControl=this->FindSubControl(pstrSubControlName);
  868. if (pSubControl==NULL)
  869. return -1;
  870. else
  871. return pSubControl->GetFixedHeight();
  872. }
  873. int CContainerUI::GetSubControlFixedWdith( LPCTSTR pstrSubControlName )
  874. {
  875. CControlUI* pSubControl=NULL;
  876. pSubControl=this->FindSubControl(pstrSubControlName);
  877. if (pSubControl==NULL)
  878. return -1;
  879. else
  880. return pSubControl->GetFixedWidth();
  881. }
  882. const CDuiString CContainerUI::GetSubControlUserData( LPCTSTR pstrSubControlName )
  883. {
  884. CControlUI* pSubControl=NULL;
  885. pSubControl=this->FindSubControl(pstrSubControlName);
  886. if (pSubControl==NULL)
  887. return _T("");
  888. else
  889. return pSubControl->GetUserData();
  890. }
  891. CControlUI* CContainerUI::FindSubControl( LPCTSTR pstrSubControlName )
  892. {
  893. CControlUI* pSubControl=NULL;
  894. pSubControl=static_cast<CControlUI*>(GetManager()->FindSubControlByName(this,pstrSubControlName));
  895. return pSubControl;
  896. }
  897. CControlUI* CContainerUI::FindItemFromGroup (LPCTSTR pstrGroup, UINT_PTR tag)
  898. {
  899. for(auto i = 0; i < m_items.GetSize ();i++)
  900. {
  901. CControlUI* item = reinterpret_cast<CControlUI*>(m_items.GetAt(i));
  902. if (_tcscmp(item->GetClass(),L"OptionUI")==0)
  903. {
  904. COptionUI* op = reinterpret_cast<COptionUI*>(item);
  905. if(op->GetTag()==tag&&_tcscmp(op->GetGroup (),pstrGroup)==0)
  906. {
  907. return item;
  908. }
  909. }
  910. }
  911. return nullptr;
  912. }
  913. } // namespace DuiLib