UIList.cpp 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442
  1. #include "StdAfx.h"
  2. namespace DuiLib {
  3. /////////////////////////////////////////////////////////////////////////////////////
  4. //
  5. //
  6. CListUI::CListUI() : m_pCallback(NULL), m_bScrollSelect(false), m_iCurSel(-1), m_iExpandedItem(-1)
  7. {
  8. m_pList = new CListBodyUI(this);
  9. m_pHeader = new CListHeaderUI;
  10. Add(m_pHeader);
  11. CVerticalLayoutUI::Add(m_pList);
  12. m_ListInfo.nColumns = 0;
  13. m_ListInfo.nFont = -1;
  14. m_ListInfo.uTextStyle = DT_VCENTER; // m_uTextStyle(DT_VCENTER | DT_END_ELLIPSIS)
  15. m_ListInfo.dwTextColor = 0xFF000000;
  16. m_ListInfo.dwBkColor = 0;
  17. m_ListInfo.bAlternateBk = false;
  18. m_ListInfo.dwSelectedTextColor = 0xFF000000;
  19. m_ListInfo.dwSelectedBkColor = 0xFFC1E3FF;
  20. m_ListInfo.dwHotTextColor = 0xFF000000;
  21. m_ListInfo.dwHotBkColor = 0xFFE9F5FF;
  22. m_ListInfo.dwDisabledTextColor = 0xFFCCCCCC;
  23. m_ListInfo.dwDisabledBkColor = 0xFFFFFFFF;
  24. m_ListInfo.dwLineColor = 0;
  25. m_ListInfo.bShowHtml = false;
  26. m_ListInfo.bMultiExpandable = false;
  27. ::ZeroMemory(&m_ListInfo.rcTextPadding, sizeof(m_ListInfo.rcTextPadding));
  28. ::ZeroMemory(&m_ListInfo.rcColumn, sizeof(m_ListInfo.rcColumn));
  29. }
  30. LPCTSTR CListUI::GetClass() const
  31. {
  32. return _T("ListUI");
  33. }
  34. UINT CListUI::GetControlFlags() const
  35. {
  36. return UIFLAG_TABSTOP;
  37. }
  38. LPVOID CListUI::GetInterface(LPCTSTR pstrName)
  39. {
  40. if( _tcscmp(pstrName, DUI_CTR_LIST) == 0 ) return static_cast<CListUI*>(this);
  41. if( _tcscmp(pstrName, _T("IList")) == 0 ) return static_cast<IListUI*>(this);
  42. if( _tcscmp(pstrName, _T("IListOwner")) == 0 ) return static_cast<IListOwnerUI*>(this);
  43. return CVerticalLayoutUI::GetInterface(pstrName);
  44. }
  45. CControlUI* CListUI::GetItemAt(int iIndex) const
  46. {
  47. return m_pList->GetItemAt(iIndex);
  48. }
  49. int CListUI::GetItemIndex(CControlUI* pControl) const
  50. {
  51. if( pControl->GetInterface(_T("ListHeader")) != NULL ) return CVerticalLayoutUI::GetItemIndex(pControl);
  52. // We also need to recognize header sub-items
  53. if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) return m_pHeader->GetItemIndex(pControl);
  54. return m_pList->GetItemIndex(pControl);
  55. }
  56. bool CListUI::SetItemIndex(CControlUI* pControl, int iIndex)
  57. {
  58. if( pControl->GetInterface(_T("ListHeader")) != NULL ) return CVerticalLayoutUI::SetItemIndex(pControl, iIndex);
  59. // We also need to recognize header sub-items
  60. if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) return m_pHeader->SetItemIndex(pControl, iIndex);
  61. int iOrginIndex = m_pList->GetItemIndex(pControl);
  62. if( iOrginIndex == -1 ) return false;
  63. if( iOrginIndex == iIndex ) return true;
  64. IListItemUI* pSelectedListItem = NULL;
  65. if( m_iCurSel >= 0 ) pSelectedListItem =
  66. static_cast<IListItemUI*>(GetItemAt(m_iCurSel)->GetInterface(_T("ListItem")));
  67. if( !m_pList->SetItemIndex(pControl, iIndex) ) return false;
  68. int iMinIndex = min(iOrginIndex, iIndex);
  69. int iMaxIndex = max(iOrginIndex, iIndex);
  70. for(int i = iMinIndex; i < iMaxIndex + 1; ++i) {
  71. CControlUI* p = m_pList->GetItemAt(i);
  72. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(_T("ListItem")));
  73. if( pListItem != NULL ) {
  74. pListItem->SetIndex(i);
  75. }
  76. }
  77. if( m_iCurSel >= 0 && pSelectedListItem != NULL ) m_iCurSel = pSelectedListItem->GetIndex();
  78. return true;
  79. }
  80. int CListUI::GetCount() const
  81. {
  82. return m_pList->GetCount();
  83. }
  84. bool CListUI::Add(CControlUI* pControl)
  85. {
  86. // Override the Add() method so we can add items specifically to
  87. // the intended widgets. Headers are assumed to be
  88. // answer the correct interface so we can add multiple list headers.
  89. if( pControl->GetInterface(_T("ListHeader")) != NULL ) {
  90. if( m_pHeader != pControl && m_pHeader->GetCount() == 0 ) {
  91. CVerticalLayoutUI::Remove(m_pHeader);
  92. m_pHeader = static_cast<CListHeaderUI*>(pControl);
  93. }
  94. m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
  95. return CVerticalLayoutUI::AddAt(pControl, 0);
  96. }
  97. // We also need to recognize header sub-items
  98. if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) {
  99. bool ret = m_pHeader->Add(pControl);
  100. m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
  101. return ret;
  102. }
  103. // The list items should know about us
  104. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
  105. if( pListItem != NULL ) {
  106. pListItem->SetOwner(this);
  107. pListItem->SetIndex(GetCount());
  108. }
  109. return m_pList->Add(pControl);
  110. }
  111. CControlUI* CListUI::Add (LPCTSTR lpXMLFile)
  112. {
  113. return CContainerUI::Add (lpXMLFile);
  114. }
  115. bool CListUI::AddAt (CControlUI* pControl, int iIndex)
  116. {
  117. // Override the AddAt() method so we can add items specifically to
  118. // the intended widgets. Headers and are assumed to be
  119. // answer the correct interface so we can add multiple list headers.
  120. if( pControl->GetInterface(_T("ListHeader")) != NULL ) {
  121. if( m_pHeader != pControl && m_pHeader->GetCount() == 0 ) {
  122. CVerticalLayoutUI::Remove(m_pHeader);
  123. m_pHeader = static_cast<CListHeaderUI*>(pControl);
  124. }
  125. m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
  126. return CVerticalLayoutUI::AddAt(pControl, 0);
  127. }
  128. // We also need to recognize header sub-items
  129. if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) {
  130. bool ret = m_pHeader->AddAt(pControl, iIndex);
  131. m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
  132. return ret;
  133. }
  134. if (!m_pList->AddAt(pControl, iIndex)) return false;
  135. // The list items should know about us
  136. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
  137. if( pListItem != NULL ) {
  138. pListItem->SetOwner(this);
  139. pListItem->SetIndex(iIndex);
  140. }
  141. for(int i = iIndex + 1; i < m_pList->GetCount(); ++i) {
  142. CControlUI* p = m_pList->GetItemAt(i);
  143. pListItem = static_cast<IListItemUI*>(p->GetInterface(_T("ListItem")));
  144. if( pListItem != NULL ) {
  145. pListItem->SetIndex(i);
  146. }
  147. }
  148. if( m_iCurSel >= iIndex ) m_iCurSel += 1;
  149. return true;
  150. }
  151. bool CListUI::Remove(CControlUI* pControl)
  152. {
  153. if( pControl->GetInterface(_T("ListHeader")) != NULL ) return CVerticalLayoutUI::Remove(pControl);
  154. // We also need to recognize header sub-items
  155. if( _tcsstr(pControl->GetClass(), _T("ListHeaderItemUI")) != NULL ) return m_pHeader->Remove(pControl);
  156. int iIndex = m_pList->GetItemIndex(pControl);
  157. if (iIndex == -1) return false;
  158. if (!m_pList->RemoveAt(iIndex)) return false;
  159. for(int i = iIndex; i < m_pList->GetCount(); ++i) {
  160. CControlUI* p = m_pList->GetItemAt(i);
  161. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(_T("ListItem")));
  162. if( pListItem != NULL ) {
  163. pListItem->SetIndex(i);
  164. }
  165. }
  166. if( iIndex == m_iCurSel && m_iCurSel >= 0 ) {
  167. int iSel = m_iCurSel;
  168. m_iCurSel = -1;
  169. SelectItem(FindSelectable(iSel, false));
  170. }
  171. else if( iIndex < m_iCurSel ) m_iCurSel -= 1;
  172. return true;
  173. }
  174. bool CListUI::RemoveAt(int iIndex)
  175. {
  176. if (!m_pList->RemoveAt(iIndex)) return false;
  177. for(int i = iIndex; i < m_pList->GetCount(); ++i) {
  178. CControlUI* p = m_pList->GetItemAt(i);
  179. IListItemUI* pListItem = static_cast<IListItemUI*>(p->GetInterface(_T("ListItem")));
  180. if( pListItem != NULL ) pListItem->SetIndex(i);
  181. }
  182. if( iIndex == m_iCurSel && m_iCurSel >= 0 ) {
  183. int iSel = m_iCurSel;
  184. m_iCurSel = -1;
  185. SelectItem(FindSelectable(iSel, false));
  186. }
  187. else if( iIndex < m_iCurSel ) m_iCurSel -= 1;
  188. return true;
  189. }
  190. void CListUI::RemoveAll()
  191. {
  192. m_iCurSel = -1;
  193. m_iExpandedItem = -1;
  194. m_pList->RemoveAll();
  195. }
  196. void CListUI::SetPos(RECT rc, bool bNeedInvalidate)
  197. {
  198. if( m_pHeader != NULL ) { // 设置header各子元素x坐标,因为有些listitem的setpos需要用到(临时修复)
  199. int iLeft = rc.left + m_rcInset.left;
  200. int iRight = rc.right - m_rcInset.right;
  201. m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
  202. if( !m_pHeader->IsVisible() ) {
  203. for( int it = m_pHeader->GetCount() - 1; it >= 0; it-- ) {
  204. static_cast<CControlUI*>(m_pHeader->GetItemAt(it))->SetInternVisible(true);
  205. }
  206. }
  207. m_pHeader->SetPos(CDuiRect(iLeft, 0, iRight, 0), false);
  208. int iOffset = m_pList->GetScrollPos().cx;
  209. for( int i = 0; i < m_ListInfo.nColumns; i++ ) {
  210. CControlUI* pControl = static_cast<CControlUI*>(m_pHeader->GetItemAt(i));
  211. if( !pControl->IsVisible() ) continue;
  212. if( pControl->IsFloat() ) continue;
  213. RECT rcPos = pControl->GetPos();
  214. if( iOffset > 0 ) {
  215. rcPos.left -= iOffset;
  216. rcPos.right -= iOffset;
  217. pControl->SetPos(rcPos, false);
  218. }
  219. m_ListInfo.rcColumn[i] = pControl->GetPos();
  220. }
  221. if( !m_pHeader->IsVisible() ) {
  222. for( int it = m_pHeader->GetCount() - 1; it >= 0; it-- ) {
  223. static_cast<CControlUI*>(m_pHeader->GetItemAt(it))->SetInternVisible(false);
  224. }
  225. m_pHeader->SetInternVisible(false);
  226. }
  227. }
  228. CVerticalLayoutUI::SetPos(rc, bNeedInvalidate);
  229. if( m_pHeader == NULL ) return;
  230. rc = m_rcItem;
  231. rc.left += m_rcInset.left;
  232. rc.top += m_rcInset.top;
  233. rc.right -= m_rcInset.right;
  234. rc.bottom -= m_rcInset.bottom;
  235. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  236. rc.top -= m_pVerticalScrollBar->GetScrollPos();
  237. rc.bottom -= m_pVerticalScrollBar->GetScrollPos();
  238. rc.bottom += m_pVerticalScrollBar->GetScrollRange();
  239. rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  240. }
  241. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  242. rc.left -= m_pHorizontalScrollBar->GetScrollPos();
  243. rc.right -= m_pHorizontalScrollBar->GetScrollPos();
  244. rc.right += m_pHorizontalScrollBar->GetScrollRange();
  245. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  246. }
  247. m_ListInfo.nColumns = MIN(m_pHeader->GetCount(), UILIST_MAX_COLUMNS);
  248. if( !m_pHeader->IsVisible() ) {
  249. for( int it = m_pHeader->GetCount() - 1; it >= 0; it-- ) {
  250. static_cast<CControlUI*>(m_pHeader->GetItemAt(it))->SetInternVisible(true);
  251. }
  252. m_pHeader->SetPos(CDuiRect(rc.left, 0, rc.right, 0), false);
  253. }
  254. int iOffset = m_pList->GetScrollPos().cx;
  255. for( int i = 0; i < m_ListInfo.nColumns; i++ ) {
  256. CControlUI* pControl = static_cast<CControlUI*>(m_pHeader->GetItemAt(i));
  257. if( !pControl->IsVisible() ) continue;
  258. if( pControl->IsFloat() ) continue;
  259. RECT rcPos = pControl->GetPos();
  260. if( iOffset > 0 ) {
  261. rcPos.left -= iOffset;
  262. rcPos.right -= iOffset;
  263. pControl->SetPos(rcPos, false);
  264. }
  265. m_ListInfo.rcColumn[i] = pControl->GetPos();
  266. }
  267. if( !m_pHeader->IsVisible() ) {
  268. for( int it = m_pHeader->GetCount() - 1; it >= 0; it-- ) {
  269. static_cast<CControlUI*>(m_pHeader->GetItemAt(it))->SetInternVisible(false);
  270. }
  271. m_pHeader->SetInternVisible(false);
  272. }
  273. }
  274. void CListUI::Move(SIZE szOffset, bool bNeedInvalidate)
  275. {
  276. CVerticalLayoutUI::Move(szOffset, bNeedInvalidate);
  277. if( !m_pHeader->IsVisible() ) m_pHeader->Move(szOffset, false);
  278. }
  279. void CListUI::DoEvent(TEventUI& event)
  280. {
  281. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  282. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  283. else CVerticalLayoutUI::DoEvent(event);
  284. return;
  285. }
  286. if( event.Type == UIEVENT_SETFOCUS )
  287. {
  288. m_bFocused = true;
  289. return;
  290. }
  291. if( event.Type == UIEVENT_KILLFOCUS )
  292. {
  293. m_bFocused = false;
  294. return;
  295. }
  296. switch( event.Type ) {
  297. case UIEVENT_KEYDOWN:
  298. switch( event.chKey ) {
  299. case VK_UP:
  300. SelectItem(FindSelectable(m_iCurSel - 1, false), true);
  301. return;
  302. case VK_DOWN:
  303. SelectItem(FindSelectable(m_iCurSel + 1, true), true);
  304. return;
  305. case VK_PRIOR:
  306. PageUp();
  307. return;
  308. case VK_NEXT:
  309. PageDown();
  310. return;
  311. case VK_HOME:
  312. SelectItem(FindSelectable(0, false), true);
  313. return;
  314. case VK_END:
  315. SelectItem(FindSelectable(GetCount() - 1, true), true);
  316. return;
  317. case VK_RETURN:
  318. if( m_iCurSel != -1 ) GetItemAt(m_iCurSel)->Activate();
  319. return;
  320. }
  321. break;
  322. case UIEVENT_SCROLLWHEEL:
  323. {
  324. switch( LOWORD(event.wParam) ) {
  325. case SB_LINEUP:
  326. if( m_bScrollSelect ) SelectItem(FindSelectable(m_iCurSel - 1, false), true);
  327. else LineUp();
  328. return;
  329. case SB_LINEDOWN:
  330. if( m_bScrollSelect ) SelectItem(FindSelectable(m_iCurSel + 1, true), true);
  331. else LineDown();
  332. return;
  333. }
  334. }
  335. break;
  336. }
  337. CVerticalLayoutUI::DoEvent(event);
  338. }
  339. CListHeaderUI* CListUI::GetHeader() const
  340. {
  341. return m_pHeader;
  342. }
  343. CContainerUI* CListUI::GetList() const
  344. {
  345. return m_pList;
  346. }
  347. bool CListUI::GetScrollSelect()
  348. {
  349. return m_bScrollSelect;
  350. }
  351. void CListUI::SetScrollSelect(bool bScrollSelect)
  352. {
  353. m_bScrollSelect = bScrollSelect;
  354. }
  355. int CListUI::GetCurSel() const
  356. {
  357. return m_iCurSel;
  358. }
  359. bool CListUI::SelectItem(int iIndex, bool bTakeFocus, bool bTriggerEvent)
  360. {
  361. if( iIndex == m_iCurSel ) return true;
  362. int iOldSel = m_iCurSel;
  363. // We should first unselect the currently selected item
  364. if( m_iCurSel >= 0 ) {
  365. CControlUI* pControl = GetItemAt(m_iCurSel);
  366. if( pControl != NULL) {
  367. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
  368. if( pListItem != NULL ) pListItem->Select(false, bTriggerEvent);
  369. }
  370. m_iCurSel = -1;
  371. }
  372. if( iIndex < 0 ) return false;
  373. CControlUI* pControl = GetItemAt(iIndex);
  374. if( pControl == NULL ) return false;
  375. if( !pControl->IsVisible() ) return false;
  376. if( !pControl->IsEnabled() ) return false;
  377. IListItemUI* pListItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
  378. if( pListItem == NULL ) return false;
  379. m_iCurSel = iIndex;
  380. if( !pListItem->Select(true, bTriggerEvent) ) {
  381. m_iCurSel = -1;
  382. return false;
  383. }
  384. EnsureVisible(m_iCurSel);
  385. if( bTakeFocus ) pControl->SetFocus();
  386. if( m_pManager != NULL && bTriggerEvent ) {
  387. m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMSELECT, m_iCurSel, iOldSel);
  388. }
  389. return true;
  390. }
  391. TListInfoUI* CListUI::GetListInfo()
  392. {
  393. return &m_ListInfo;
  394. }
  395. int CListUI::GetChildPadding() const
  396. {
  397. return m_pList->GetChildPadding();
  398. }
  399. void CListUI::SetChildPadding(int iPadding)
  400. {
  401. m_pList->SetChildPadding(iPadding);
  402. }
  403. void CListUI::SetItemFont(int index)
  404. {
  405. m_ListInfo.nFont = index;
  406. NeedUpdate();
  407. }
  408. void CListUI::SetItemTextStyle(UINT uStyle)
  409. {
  410. m_ListInfo.uTextStyle = uStyle;
  411. NeedUpdate();
  412. }
  413. void CListUI::SetItemTextPadding(RECT rc)
  414. {
  415. m_ListInfo.rcTextPadding = rc;
  416. NeedUpdate();
  417. }
  418. RECT CListUI::GetItemTextPadding() const
  419. {
  420. return m_ListInfo.rcTextPadding;
  421. }
  422. void CListUI::SetItemTextColor(DWORD dwTextColor)
  423. {
  424. m_ListInfo.dwTextColor = dwTextColor;
  425. Invalidate();
  426. }
  427. void CListUI::SetItemBkColor(DWORD dwBkColor)
  428. {
  429. m_ListInfo.dwBkColor = dwBkColor;
  430. Invalidate();
  431. }
  432. void CListUI::SetItemBkImage(LPCTSTR pStrImage)
  433. {
  434. if( m_ListInfo.diBk.sDrawString == pStrImage && m_ListInfo.diBk.pImageInfo != NULL ) return;
  435. m_ListInfo.diBk.Clear();
  436. m_ListInfo.diBk.sDrawString = pStrImage;
  437. Invalidate();
  438. }
  439. bool CListUI::IsAlternateBk() const
  440. {
  441. return m_ListInfo.bAlternateBk;
  442. }
  443. void CListUI::SetAlternateBk(bool bAlternateBk)
  444. {
  445. m_ListInfo.bAlternateBk = bAlternateBk;
  446. Invalidate();
  447. }
  448. DWORD CListUI::GetItemTextColor() const
  449. {
  450. return m_ListInfo.dwTextColor;
  451. }
  452. DWORD CListUI::GetItemBkColor() const
  453. {
  454. return m_ListInfo.dwBkColor;
  455. }
  456. LPCTSTR CListUI::GetItemBkImage() const
  457. {
  458. return m_ListInfo.diBk.sDrawString;
  459. }
  460. void CListUI::SetSelectedItemTextColor(DWORD dwTextColor)
  461. {
  462. m_ListInfo.dwSelectedTextColor = dwTextColor;
  463. Invalidate();
  464. }
  465. void CListUI::SetSelectedItemBkColor(DWORD dwBkColor)
  466. {
  467. m_ListInfo.dwSelectedBkColor = dwBkColor;
  468. Invalidate();
  469. }
  470. void CListUI::SetSelectedItemImage(LPCTSTR pStrImage)
  471. {
  472. if( m_ListInfo.diSelected.sDrawString == pStrImage && m_ListInfo.diSelected.pImageInfo != NULL ) return;
  473. m_ListInfo.diSelected.Clear();
  474. m_ListInfo.diSelected.sDrawString = pStrImage;
  475. Invalidate();
  476. }
  477. DWORD CListUI::GetSelectedItemTextColor() const
  478. {
  479. return m_ListInfo.dwSelectedTextColor;
  480. }
  481. DWORD CListUI::GetSelectedItemBkColor() const
  482. {
  483. return m_ListInfo.dwSelectedBkColor;
  484. }
  485. LPCTSTR CListUI::GetSelectedItemImage() const
  486. {
  487. return m_ListInfo.diSelected.sDrawString;
  488. }
  489. void CListUI::SetHotItemTextColor(DWORD dwTextColor)
  490. {
  491. m_ListInfo.dwHotTextColor = dwTextColor;
  492. Invalidate();
  493. }
  494. void CListUI::SetHotItemBkColor(DWORD dwBkColor)
  495. {
  496. m_ListInfo.dwHotBkColor = dwBkColor;
  497. Invalidate();
  498. }
  499. void CListUI::SetHotItemImage(LPCTSTR pStrImage)
  500. {
  501. if( m_ListInfo.diHot.sDrawString == pStrImage && m_ListInfo.diHot.pImageInfo != NULL ) return;
  502. m_ListInfo.diHot.Clear();
  503. m_ListInfo.diHot.sDrawString = pStrImage;
  504. Invalidate();
  505. }
  506. DWORD CListUI::GetHotItemTextColor() const
  507. {
  508. return m_ListInfo.dwHotTextColor;
  509. }
  510. DWORD CListUI::GetHotItemBkColor() const
  511. {
  512. return m_ListInfo.dwHotBkColor;
  513. }
  514. LPCTSTR CListUI::GetHotItemImage() const
  515. {
  516. return m_ListInfo.diHot.sDrawString;
  517. }
  518. void CListUI::SetDisabledItemTextColor(DWORD dwTextColor)
  519. {
  520. m_ListInfo.dwDisabledTextColor = dwTextColor;
  521. Invalidate();
  522. }
  523. void CListUI::SetDisabledItemBkColor(DWORD dwBkColor)
  524. {
  525. m_ListInfo.dwDisabledBkColor = dwBkColor;
  526. Invalidate();
  527. }
  528. void CListUI::SetDisabledItemImage(LPCTSTR pStrImage)
  529. {
  530. if( m_ListInfo.diDisabled.sDrawString == pStrImage && m_ListInfo.diDisabled.pImageInfo != NULL ) return;
  531. m_ListInfo.diDisabled.Clear();
  532. m_ListInfo.diDisabled.sDrawString = pStrImage;
  533. Invalidate();
  534. }
  535. DWORD CListUI::GetDisabledItemTextColor() const
  536. {
  537. return m_ListInfo.dwDisabledTextColor;
  538. }
  539. DWORD CListUI::GetDisabledItemBkColor() const
  540. {
  541. return m_ListInfo.dwDisabledBkColor;
  542. }
  543. LPCTSTR CListUI::GetDisabledItemImage() const
  544. {
  545. return m_ListInfo.diDisabled.sDrawString;
  546. }
  547. DWORD CListUI::GetItemLineColor() const
  548. {
  549. return m_ListInfo.dwLineColor;
  550. }
  551. void CListUI::SetItemLineColor(DWORD dwLineColor)
  552. {
  553. m_ListInfo.dwLineColor = dwLineColor;
  554. Invalidate();
  555. }
  556. bool CListUI::IsItemShowHtml()
  557. {
  558. return m_ListInfo.bShowHtml;
  559. }
  560. void CListUI::SetItemShowHtml(bool bShowHtml)
  561. {
  562. if( m_ListInfo.bShowHtml == bShowHtml ) return;
  563. m_ListInfo.bShowHtml = bShowHtml;
  564. NeedUpdate();
  565. }
  566. void CListUI::SetMultiExpanding(bool bMultiExpandable)
  567. {
  568. m_ListInfo.bMultiExpandable = bMultiExpandable;
  569. }
  570. bool CListUI::ExpandItem(int iIndex, bool bExpand /*= true*/)
  571. {
  572. if( m_iExpandedItem >= 0 && !m_ListInfo.bMultiExpandable) {
  573. CControlUI* pControl = GetItemAt(m_iExpandedItem);
  574. if( pControl != NULL ) {
  575. IListItemUI* pItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
  576. if( pItem != NULL ) pItem->Expand(false);
  577. }
  578. m_iExpandedItem = -1;
  579. }
  580. if( bExpand ) {
  581. CControlUI* pControl = GetItemAt(iIndex);
  582. if( pControl == NULL ) return false;
  583. if( !pControl->IsVisible() ) return false;
  584. IListItemUI* pItem = static_cast<IListItemUI*>(pControl->GetInterface(_T("ListItem")));
  585. if( pItem == NULL ) return false;
  586. m_iExpandedItem = iIndex;
  587. if( !pItem->Expand(true) ) {
  588. m_iExpandedItem = -1;
  589. return false;
  590. }
  591. }
  592. NeedUpdate();
  593. return true;
  594. }
  595. int CListUI::GetExpandedItem() const
  596. {
  597. return m_iExpandedItem;
  598. }
  599. void CListUI::EnsureVisible(int iIndex)
  600. {
  601. if( m_iCurSel < 0 ) return;
  602. RECT rcItem = m_pList->GetItemAt(iIndex)->GetPos();
  603. RECT rcList = m_pList->GetPos();
  604. RECT rcListInset = m_pList->GetInset();
  605. rcList.left += rcListInset.left;
  606. rcList.top += rcListInset.top;
  607. rcList.right -= rcListInset.right;
  608. rcList.bottom -= rcListInset.bottom;
  609. CScrollBarUI* pHorizontalScrollBar = m_pList->GetHorizontalScrollBar();
  610. if( pHorizontalScrollBar && pHorizontalScrollBar->IsVisible() ) rcList.bottom -= pHorizontalScrollBar->GetFixedHeight();
  611. int iPos = m_pList->GetScrollPos().cy;
  612. if( rcItem.top >= rcList.top && rcItem.bottom < rcList.bottom ) return;
  613. int dx = 0;
  614. if( rcItem.top < rcList.top ) dx = rcItem.top - rcList.top;
  615. if( rcItem.bottom > rcList.bottom ) dx = rcItem.bottom - rcList.bottom;
  616. Scroll(0, dx);
  617. }
  618. void CListUI::Scroll(int dx, int dy)
  619. {
  620. if( dx == 0 && dy == 0 ) return;
  621. SIZE sz = m_pList->GetScrollPos();
  622. m_pList->SetScrollPos(CDuiSize(sz.cx + dx, sz.cy + dy));
  623. }
  624. void CListUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  625. {
  626. if( _tcscmp(pstrName, _T("header")) == 0 ) GetHeader()->SetVisible(_tcscmp(pstrValue, _T("hidden")) != 0);
  627. else if( _tcscmp(pstrName, _T("headerbkimage")) == 0 ) GetHeader()->SetBkImage(pstrValue);
  628. else if( _tcscmp(pstrName, _T("scrollselect")) == 0 ) SetScrollSelect(_tcscmp(pstrValue, _T("true")) == 0);
  629. else if( _tcscmp(pstrName, _T("multiexpanding")) == 0 ) SetMultiExpanding(_tcscmp(pstrValue, _T("true")) == 0);
  630. else if( _tcscmp(pstrName, _T("itemfont")) == 0 ) m_ListInfo.nFont = _ttoi(pstrValue);
  631. else if( _tcscmp(pstrName, _T("itemalign")) == 0 ) {
  632. if( _tcsstr(pstrValue, _T("left")) != NULL ) {
  633. m_ListInfo.uTextStyle &= ~(DT_CENTER | DT_RIGHT);
  634. m_ListInfo.uTextStyle |= DT_LEFT;
  635. }
  636. if( _tcsstr(pstrValue, _T("center")) != NULL ) {
  637. m_ListInfo.uTextStyle &= ~(DT_LEFT | DT_RIGHT);
  638. m_ListInfo.uTextStyle |= DT_CENTER;
  639. }
  640. if( _tcsstr(pstrValue, _T("right")) != NULL ) {
  641. m_ListInfo.uTextStyle &= ~(DT_LEFT | DT_CENTER);
  642. m_ListInfo.uTextStyle |= DT_RIGHT;
  643. }
  644. }
  645. else if( _tcscmp(pstrName, _T("itemendellipsis")) == 0 ) {
  646. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_ListInfo.uTextStyle |= DT_END_ELLIPSIS;
  647. else m_ListInfo.uTextStyle &= ~DT_END_ELLIPSIS;
  648. }
  649. if( _tcscmp(pstrName, _T("itemtextpadding")) == 0 ) {
  650. RECT rcTextPadding = { 0 };
  651. LPTSTR pstr = NULL;
  652. rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  653. rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  654. rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  655. rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  656. SetItemTextPadding(rcTextPadding);
  657. }
  658. else if( _tcscmp(pstrName, _T("itemtextcolor")) == 0 ) {
  659. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  660. LPTSTR pstr = NULL;
  661. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  662. SetItemTextColor(clrColor);
  663. }
  664. else if( _tcscmp(pstrName, _T("itembkcolor")) == 0 ) {
  665. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  666. LPTSTR pstr = NULL;
  667. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  668. SetItemBkColor(clrColor);
  669. }
  670. else if( _tcscmp(pstrName, _T("itembkimage")) == 0 ) SetItemBkImage(pstrValue);
  671. else if( _tcscmp(pstrName, _T("itemaltbk")) == 0 ) SetAlternateBk(_tcscmp(pstrValue, _T("true")) == 0);
  672. else if( _tcscmp(pstrName, _T("itemselectedtextcolor")) == 0 ) {
  673. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  674. LPTSTR pstr = NULL;
  675. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  676. SetSelectedItemTextColor(clrColor);
  677. }
  678. else if( _tcscmp(pstrName, _T("itemselectedbkcolor")) == 0 ) {
  679. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  680. LPTSTR pstr = NULL;
  681. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  682. SetSelectedItemBkColor(clrColor);
  683. }
  684. else if( _tcscmp(pstrName, _T("itemselectedimage")) == 0 ) SetSelectedItemImage(pstrValue);
  685. else if( _tcscmp(pstrName, _T("itemhottextcolor")) == 0 ) {
  686. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  687. LPTSTR pstr = NULL;
  688. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  689. SetHotItemTextColor(clrColor);
  690. }
  691. else if( _tcscmp(pstrName, _T("itemhotbkcolor")) == 0 ) {
  692. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  693. LPTSTR pstr = NULL;
  694. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  695. SetHotItemBkColor(clrColor);
  696. }
  697. else if( _tcscmp(pstrName, _T("itemhotimage")) == 0 ) SetHotItemImage(pstrValue);
  698. else if( _tcscmp(pstrName, _T("itemdisabledtextcolor")) == 0 ) {
  699. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  700. LPTSTR pstr = NULL;
  701. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  702. SetDisabledItemTextColor(clrColor);
  703. }
  704. else if( _tcscmp(pstrName, _T("itemdisabledbkcolor")) == 0 ) {
  705. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  706. LPTSTR pstr = NULL;
  707. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  708. SetDisabledItemBkColor(clrColor);
  709. }
  710. else if( _tcscmp(pstrName, _T("itemdisabledimage")) == 0 ) SetDisabledItemImage(pstrValue);
  711. else if( _tcscmp(pstrName, _T("itemlinecolor")) == 0 ) {
  712. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  713. LPTSTR pstr = NULL;
  714. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  715. SetItemLineColor(clrColor);
  716. }
  717. else if( _tcscmp(pstrName, _T("itemshowhtml")) == 0 ) SetItemShowHtml(_tcscmp(pstrValue, _T("true")) == 0);
  718. else CVerticalLayoutUI::SetAttribute(pstrName, pstrValue);
  719. }
  720. IListCallbackUI* CListUI::GetTextCallback() const
  721. {
  722. return m_pCallback;
  723. }
  724. void CListUI::SetTextCallback(IListCallbackUI* pCallback)
  725. {
  726. m_pCallback = pCallback;
  727. }
  728. SIZE CListUI::GetScrollPos() const
  729. {
  730. return m_pList->GetScrollPos();
  731. }
  732. SIZE CListUI::GetScrollRange() const
  733. {
  734. return m_pList->GetScrollRange();
  735. }
  736. void CListUI::SetScrollPos(SIZE szPos)
  737. {
  738. m_pList->SetScrollPos(szPos);
  739. }
  740. void CListUI::LineUp()
  741. {
  742. m_pList->LineUp();
  743. }
  744. void CListUI::LineDown()
  745. {
  746. m_pList->LineDown();
  747. }
  748. void CListUI::PageUp()
  749. {
  750. m_pList->PageUp();
  751. }
  752. void CListUI::PageDown()
  753. {
  754. m_pList->PageDown();
  755. }
  756. void CListUI::HomeUp()
  757. {
  758. m_pList->HomeUp();
  759. }
  760. void CListUI::EndDown()
  761. {
  762. m_pList->EndDown();
  763. }
  764. void CListUI::LineLeft()
  765. {
  766. m_pList->LineLeft();
  767. }
  768. void CListUI::LineRight()
  769. {
  770. m_pList->LineRight();
  771. }
  772. void CListUI::PageLeft()
  773. {
  774. m_pList->PageLeft();
  775. }
  776. void CListUI::PageRight()
  777. {
  778. m_pList->PageRight();
  779. }
  780. void CListUI::HomeLeft()
  781. {
  782. m_pList->HomeLeft();
  783. }
  784. void CListUI::EndRight()
  785. {
  786. m_pList->EndRight();
  787. }
  788. void CListUI::EnableScrollBar(bool bEnableVertical, bool bEnableHorizontal)
  789. {
  790. m_pList->EnableScrollBar(bEnableVertical, bEnableHorizontal);
  791. }
  792. CScrollBarUI* CListUI::GetVerticalScrollBar() const
  793. {
  794. return m_pList->GetVerticalScrollBar();
  795. }
  796. CScrollBarUI* CListUI::GetHorizontalScrollBar() const
  797. {
  798. return m_pList->GetHorizontalScrollBar();
  799. }
  800. BOOL CListUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData)
  801. {
  802. if (!m_pList)
  803. return FALSE;
  804. int iCurSel = m_iCurSel;
  805. BOOL bResult = m_pList->SortItems(pfnCompare, dwData, iCurSel);
  806. if (bResult) {
  807. m_iCurSel = iCurSel;
  808. EnsureVisible(m_iCurSel);
  809. NeedUpdate();
  810. }
  811. return bResult;
  812. }
  813. /////////////////////////////////////////////////////////////////////////////////////
  814. //
  815. //
  816. CListBodyUI::CListBodyUI(CListUI* pOwner) : m_pOwner(pOwner)
  817. {
  818. ASSERT(m_pOwner);
  819. }
  820. BOOL CListBodyUI::SortItems(PULVCompareFunc pfnCompare, UINT_PTR dwData, int& iCurSel)
  821. {
  822. if (!pfnCompare)
  823. return FALSE;
  824. m_pCompareFunc = pfnCompare;
  825. CControlUI *pCurSelControl = GetItemAt(iCurSel);
  826. CControlUI **pData = (CControlUI **)m_items.GetData();
  827. qsort_s(m_items.GetData(), m_items.GetSize(), sizeof(CControlUI*), CListBodyUI::ItemComareFunc, this);
  828. if (pCurSelControl) iCurSel = GetItemIndex(pCurSelControl);
  829. IListItemUI *pItem = NULL;
  830. for (int i = 0; i < m_items.GetSize(); ++i)
  831. {
  832. pItem = (IListItemUI*)(static_cast<CControlUI*>(m_items[i])->GetInterface(TEXT("ListItem")));
  833. if (pItem)
  834. {
  835. pItem->SetIndex(i);
  836. }
  837. }
  838. return TRUE;
  839. }
  840. int __cdecl CListBodyUI::ItemComareFunc(void *pvlocale, const void *item1, const void *item2)
  841. {
  842. CListBodyUI *pThis = (CListBodyUI*)pvlocale;
  843. if (!pThis || !item1 || !item2)
  844. return 0;
  845. return pThis->ItemComareFunc(item1, item2);
  846. }
  847. int __cdecl CListBodyUI::ItemComareFunc(const void *item1, const void *item2)
  848. {
  849. CControlUI *pControl1 = *(CControlUI**)item1;
  850. CControlUI *pControl2 = *(CControlUI**)item2;
  851. return m_pCompareFunc((UINT_PTR)pControl1, (UINT_PTR)pControl2, m_compareData);
  852. }
  853. void CListBodyUI::SetScrollPos(SIZE szPos)
  854. {
  855. int cx = 0;
  856. int cy = 0;
  857. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  858. int iLastScrollPos = m_pVerticalScrollBar->GetScrollPos();
  859. m_pVerticalScrollBar->SetScrollPos(szPos.cy);
  860. cy = m_pVerticalScrollBar->GetScrollPos() - iLastScrollPos;
  861. }
  862. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  863. int iLastScrollPos = m_pHorizontalScrollBar->GetScrollPos();
  864. m_pHorizontalScrollBar->SetScrollPos(szPos.cx);
  865. cx = m_pHorizontalScrollBar->GetScrollPos() - iLastScrollPos;
  866. }
  867. if( cx == 0 && cy == 0 ) return;
  868. for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
  869. CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
  870. if( !pControl->IsVisible() ) continue;
  871. if( pControl->IsFloat() ) continue;
  872. pControl->Move(CDuiSize(-cx, -cy), false);
  873. }
  874. Invalidate();
  875. if( cx != 0 && m_pOwner ) {
  876. CListHeaderUI* pHeader = m_pOwner->GetHeader();
  877. if( pHeader == NULL ) return;
  878. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  879. pInfo->nColumns = MIN(pHeader->GetCount(), UILIST_MAX_COLUMNS);
  880. for( int i = 0; i < pInfo->nColumns; i++ ) {
  881. CControlUI* pControl = static_cast<CControlUI*>(pHeader->GetItemAt(i));
  882. if( !pControl->IsVisible() ) continue;
  883. if( pControl->IsFloat() ) continue;
  884. pControl->Move(CDuiSize(-cx, -cy), false);
  885. pInfo->rcColumn[i] = pControl->GetPos();
  886. }
  887. pHeader->Invalidate();
  888. }
  889. }
  890. void CListBodyUI::SetPos(RECT rc, bool bNeedInvalidate)
  891. {
  892. CControlUI::SetPos(rc, bNeedInvalidate);
  893. rc = m_rcItem;
  894. // Adjust for inset
  895. rc.left += m_rcInset.left;
  896. rc.top += m_rcInset.top;
  897. rc.right -= m_rcInset.right;
  898. rc.bottom -= m_rcInset.bottom;
  899. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
  900. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  901. // Determine the minimum size
  902. SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };
  903. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() )
  904. szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange();
  905. int cxNeeded = 0;
  906. int nAdjustables = 0;
  907. int cyFixed = 0;
  908. int nEstimateNum = 0;
  909. for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) {
  910. CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
  911. if( !pControl->IsVisible() ) continue;
  912. if( pControl->IsFloat() ) continue;
  913. SIZE sz = pControl->EstimateSize(szAvailable);
  914. if( sz.cy == 0 ) {
  915. nAdjustables++;
  916. }
  917. else {
  918. if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
  919. if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
  920. }
  921. cyFixed += sz.cy + pControl->GetPadding().top + pControl->GetPadding().bottom;
  922. RECT rcPadding = pControl->GetPadding();
  923. sz.cx = MAX(sz.cx, 0);
  924. if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
  925. if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
  926. cxNeeded = MAX(cxNeeded, sz.cx);
  927. nEstimateNum++;
  928. }
  929. cyFixed += (nEstimateNum - 1) * m_iChildPadding;
  930. if( m_pOwner ) {
  931. CListHeaderUI* pHeader = m_pOwner->GetHeader();
  932. if( pHeader != NULL && pHeader->GetCount() > 0 ) {
  933. cxNeeded = MAX(0, pHeader->EstimateSize(CDuiSize(rc.right - rc.left, rc.bottom - rc.top)).cx);
  934. }
  935. }
  936. // Place elements
  937. int cyNeeded = 0;
  938. int cyExpand = 0;
  939. if( nAdjustables > 0 ) cyExpand = MAX(0, (szAvailable.cy - cyFixed) / nAdjustables);
  940. // Position the elements
  941. SIZE szRemaining = szAvailable;
  942. int iPosY = rc.top;
  943. if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
  944. iPosY -= m_pVerticalScrollBar->GetScrollPos();
  945. }
  946. int iPosX = rc.left;
  947. if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
  948. iPosX -= m_pHorizontalScrollBar->GetScrollPos();
  949. }
  950. int iAdjustable = 0;
  951. int cyFixedRemaining = cyFixed;
  952. for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
  953. CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
  954. if( !pControl->IsVisible() ) continue;
  955. if( pControl->IsFloat() ) {
  956. SetFloatPos(it2);
  957. continue;
  958. }
  959. RECT rcPadding = pControl->GetPadding();
  960. szRemaining.cy -= rcPadding.top;
  961. SIZE sz = pControl->EstimateSize(szRemaining);
  962. if( sz.cy == 0 ) {
  963. iAdjustable++;
  964. sz.cy = cyExpand;
  965. // Distribute remaining to last element (usually round-off left-overs)
  966. if( iAdjustable == nAdjustables ) {
  967. sz.cy = MAX(0, szRemaining.cy - rcPadding.bottom - cyFixedRemaining);
  968. }
  969. if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
  970. if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
  971. }
  972. else {
  973. if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
  974. if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
  975. cyFixedRemaining -= sz.cy;
  976. }
  977. sz.cx = MAX(cxNeeded, szAvailable.cx - rcPadding.left - rcPadding.right);
  978. if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
  979. if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
  980. RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.top + rcPadding.bottom };
  981. pControl->SetPos(rcCtrl, false);
  982. iPosY += sz.cy + m_iChildPadding + rcPadding.top + rcPadding.bottom;
  983. cyNeeded += sz.cy + rcPadding.top + rcPadding.bottom;
  984. szRemaining.cy -= sz.cy + m_iChildPadding + rcPadding.bottom;
  985. }
  986. cyNeeded += (nEstimateNum - 1) * m_iChildPadding;
  987. if( m_pHorizontalScrollBar != NULL ) {
  988. if( cxNeeded > rc.right - rc.left ) {
  989. if( m_pHorizontalScrollBar->IsVisible() ) {
  990. m_pHorizontalScrollBar->SetScrollRange(cxNeeded - (rc.right - rc.left));
  991. }
  992. else {
  993. m_pHorizontalScrollBar->SetVisible(true);
  994. m_pHorizontalScrollBar->SetScrollRange(cxNeeded - (rc.right - rc.left));
  995. m_pHorizontalScrollBar->SetScrollPos(0);
  996. rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
  997. }
  998. }
  999. else {
  1000. if( m_pHorizontalScrollBar->IsVisible() ) {
  1001. m_pHorizontalScrollBar->SetVisible(false);
  1002. m_pHorizontalScrollBar->SetScrollRange(0);
  1003. m_pHorizontalScrollBar->SetScrollPos(0);
  1004. rc.bottom += m_pHorizontalScrollBar->GetFixedHeight();
  1005. }
  1006. }
  1007. }
  1008. // Process the scrollbar
  1009. ProcessScrollBar(rc, cxNeeded, cyNeeded);
  1010. }
  1011. void CListBodyUI::DoEvent(TEventUI& event)
  1012. {
  1013. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  1014. if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
  1015. else CControlUI::DoEvent(event);
  1016. return;
  1017. }
  1018. if( m_pOwner != NULL ) m_pOwner->DoEvent(event); else CControlUI::DoEvent(event);
  1019. }
  1020. /////////////////////////////////////////////////////////////////////////////////////
  1021. //
  1022. //
  1023. CListHeaderUI::CListHeaderUI()
  1024. {
  1025. }
  1026. LPCTSTR CListHeaderUI::GetClass() const
  1027. {
  1028. return _T("ListHeaderUI");
  1029. }
  1030. LPVOID CListHeaderUI::GetInterface(LPCTSTR pstrName)
  1031. {
  1032. if( _tcscmp(pstrName, DUI_CTR_LISTHEADER) == 0 ) return this;
  1033. return CHorizontalLayoutUI::GetInterface(pstrName);
  1034. }
  1035. SIZE CListHeaderUI::EstimateSize(SIZE szAvailable)
  1036. {
  1037. SIZE cXY = {0, m_cxyFixed.cy};
  1038. if( cXY.cy == 0 && m_pManager != NULL ) {
  1039. for( int it = 0; it < m_items.GetSize(); it++ ) {
  1040. cXY.cy = MAX(cXY.cy,static_cast<CControlUI*>(m_items[it])->EstimateSize(szAvailable).cy);
  1041. }
  1042. int nMin = m_pManager->GetDefaultFontInfo()->tm.tmHeight + 6;
  1043. cXY.cy = MAX(cXY.cy,nMin);
  1044. }
  1045. for( int it = 0; it < m_items.GetSize(); it++ ) {
  1046. cXY.cx += static_cast<CControlUI*>(m_items[it])->EstimateSize(szAvailable).cx;
  1047. }
  1048. return cXY;
  1049. }
  1050. /////////////////////////////////////////////////////////////////////////////////////
  1051. //
  1052. //
  1053. CListHeaderItemUI::CListHeaderItemUI() : m_bDragable(true), m_uButtonState(0), m_iSepWidth(4),
  1054. m_uTextStyle(DT_VCENTER | DT_CENTER | DT_SINGLELINE), m_dwTextColor(0), m_iFont(-1), m_bShowHtml(false)
  1055. {
  1056. SetTextPadding(CDuiRect(2, 0, 2, 0));
  1057. ptLastMouse.x = ptLastMouse.y = 0;
  1058. SetMinWidth(16);
  1059. }
  1060. LPCTSTR CListHeaderItemUI::GetClass() const
  1061. {
  1062. return _T("ListHeaderItemUI");
  1063. }
  1064. LPVOID CListHeaderItemUI::GetInterface(LPCTSTR pstrName)
  1065. {
  1066. if( _tcscmp(pstrName, DUI_CTR_LISTHEADERITEM) == 0 ) return this;
  1067. return CControlUI::GetInterface(pstrName);
  1068. }
  1069. UINT CListHeaderItemUI::GetControlFlags() const
  1070. {
  1071. if( IsEnabled() && m_iSepWidth != 0 ) return UIFLAG_SETCURSOR;
  1072. else return 0;
  1073. }
  1074. void CListHeaderItemUI::SetEnabled(bool bEnable)
  1075. {
  1076. CControlUI::SetEnabled(bEnable);
  1077. if( !IsEnabled() ) {
  1078. m_uButtonState = 0;
  1079. }
  1080. }
  1081. bool CListHeaderItemUI::IsDragable() const
  1082. {
  1083. return m_bDragable;
  1084. }
  1085. void CListHeaderItemUI::SetDragable(bool bDragable)
  1086. {
  1087. m_bDragable = bDragable;
  1088. if ( !m_bDragable ) m_uButtonState &= ~UISTATE_CAPTURED;
  1089. }
  1090. DWORD CListHeaderItemUI::GetSepWidth() const
  1091. {
  1092. return m_iSepWidth;
  1093. }
  1094. void CListHeaderItemUI::SetSepWidth(int iWidth)
  1095. {
  1096. m_iSepWidth = iWidth;
  1097. }
  1098. DWORD CListHeaderItemUI::GetTextStyle() const
  1099. {
  1100. return m_uTextStyle;
  1101. }
  1102. void CListHeaderItemUI::SetTextStyle(UINT uStyle)
  1103. {
  1104. m_uTextStyle = uStyle;
  1105. Invalidate();
  1106. }
  1107. DWORD CListHeaderItemUI::GetTextColor() const
  1108. {
  1109. return m_dwTextColor;
  1110. }
  1111. void CListHeaderItemUI::SetTextColor(DWORD dwTextColor)
  1112. {
  1113. m_dwTextColor = dwTextColor;
  1114. }
  1115. RECT CListHeaderItemUI::GetTextPadding() const
  1116. {
  1117. return m_rcTextPadding;
  1118. }
  1119. void CListHeaderItemUI::SetTextPadding(RECT rc)
  1120. {
  1121. m_rcTextPadding = rc;
  1122. Invalidate();
  1123. }
  1124. void CListHeaderItemUI::SetFont(int index)
  1125. {
  1126. m_iFont = index;
  1127. }
  1128. bool CListHeaderItemUI::IsShowHtml()
  1129. {
  1130. return m_bShowHtml;
  1131. }
  1132. void CListHeaderItemUI::SetShowHtml(bool bShowHtml)
  1133. {
  1134. if( m_bShowHtml == bShowHtml ) return;
  1135. m_bShowHtml = bShowHtml;
  1136. Invalidate();
  1137. }
  1138. LPCTSTR CListHeaderItemUI::GetNormalImage() const
  1139. {
  1140. return m_diNormal.sDrawString;
  1141. }
  1142. void CListHeaderItemUI::SetNormalImage(LPCTSTR pStrImage)
  1143. {
  1144. if( m_diNormal.sDrawString == pStrImage && m_diNormal.pImageInfo != NULL ) return;
  1145. m_diNormal.Clear();
  1146. m_diNormal.sDrawString = pStrImage;
  1147. Invalidate();
  1148. }
  1149. LPCTSTR CListHeaderItemUI::GetHotImage() const
  1150. {
  1151. return m_diHot.sDrawString;
  1152. }
  1153. void CListHeaderItemUI::SetHotImage(LPCTSTR pStrImage)
  1154. {
  1155. if( m_diHot.sDrawString == pStrImage && m_diHot.pImageInfo != NULL ) return;
  1156. m_diHot.Clear();
  1157. m_diHot.sDrawString = pStrImage;
  1158. Invalidate();
  1159. }
  1160. LPCTSTR CListHeaderItemUI::GetPushedImage() const
  1161. {
  1162. return m_diPushed.sDrawString;
  1163. }
  1164. void CListHeaderItemUI::SetPushedImage(LPCTSTR pStrImage)
  1165. {
  1166. if( m_diPushed.sDrawString == pStrImage && m_diPushed.pImageInfo != NULL ) return;
  1167. m_diPushed.Clear();
  1168. m_diPushed.sDrawString = pStrImage;
  1169. Invalidate();
  1170. }
  1171. LPCTSTR CListHeaderItemUI::GetFocusedImage() const
  1172. {
  1173. return m_diFocused.sDrawString;
  1174. }
  1175. void CListHeaderItemUI::SetFocusedImage(LPCTSTR pStrImage)
  1176. {
  1177. if( m_diFocused.sDrawString == pStrImage && m_diFocused.pImageInfo != NULL ) return;
  1178. m_diFocused.Clear();
  1179. m_diFocused.sDrawString = pStrImage;
  1180. Invalidate();
  1181. }
  1182. LPCTSTR CListHeaderItemUI::GetSepImage() const
  1183. {
  1184. return m_diSep.sDrawString;
  1185. }
  1186. void CListHeaderItemUI::SetSepImage(LPCTSTR pStrImage)
  1187. {
  1188. if( m_diSep.sDrawString == pStrImage && m_diSep.pImageInfo != NULL ) return;
  1189. m_diSep.Clear();
  1190. m_diSep.sDrawString = pStrImage;
  1191. Invalidate();
  1192. }
  1193. void CListHeaderItemUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  1194. {
  1195. if( _tcscmp(pstrName, _T("dragable")) == 0 ) SetDragable(_tcscmp(pstrValue, _T("true")) == 0);
  1196. else if( _tcscmp(pstrName, _T("sepwidth")) == 0 ) SetSepWidth(_ttoi(pstrValue));
  1197. else if( _tcscmp(pstrName, _T("align")) == 0 ) {
  1198. if( _tcsstr(pstrValue, _T("left")) != NULL ) {
  1199. m_uTextStyle &= ~(DT_CENTER | DT_RIGHT);
  1200. m_uTextStyle |= DT_LEFT;
  1201. }
  1202. if( _tcsstr(pstrValue, _T("center")) != NULL ) {
  1203. m_uTextStyle &= ~(DT_LEFT | DT_RIGHT);
  1204. m_uTextStyle |= DT_CENTER;
  1205. }
  1206. if( _tcsstr(pstrValue, _T("right")) != NULL ) {
  1207. m_uTextStyle &= ~(DT_LEFT | DT_CENTER);
  1208. m_uTextStyle |= DT_RIGHT;
  1209. }
  1210. }
  1211. else if( _tcscmp(pstrName, _T("endellipsis")) == 0 ) {
  1212. if( _tcscmp(pstrValue, _T("true")) == 0 ) m_uTextStyle |= DT_END_ELLIPSIS;
  1213. else m_uTextStyle &= ~DT_END_ELLIPSIS;
  1214. }
  1215. else if( _tcscmp(pstrName, _T("font")) == 0 ) SetFont(_ttoi(pstrValue));
  1216. else if( _tcscmp(pstrName, _T("textcolor")) == 0 ) {
  1217. if( *pstrValue == _T('#')) pstrValue = ::CharNext(pstrValue);
  1218. LPTSTR pstr = NULL;
  1219. DWORD clrColor = _tcstoul(pstrValue, &pstr, 16);
  1220. SetTextColor(clrColor);
  1221. }
  1222. else if( _tcscmp(pstrName, _T("textpadding")) == 0 ) {
  1223. RECT rcTextPadding = { 0 };
  1224. LPTSTR pstr = NULL;
  1225. rcTextPadding.left = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr);
  1226. rcTextPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1227. rcTextPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1228. rcTextPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
  1229. SetTextPadding(rcTextPadding);
  1230. }
  1231. else if( _tcscmp(pstrName, _T("showhtml")) == 0 ) SetShowHtml(_tcscmp(pstrValue, _T("true")) == 0);
  1232. else if( _tcscmp(pstrName, _T("normalimage")) == 0 ) SetNormalImage(pstrValue);
  1233. else if( _tcscmp(pstrName, _T("hotimage")) == 0 ) SetHotImage(pstrValue);
  1234. else if( _tcscmp(pstrName, _T("pushedimage")) == 0 ) SetPushedImage(pstrValue);
  1235. else if( _tcscmp(pstrName, _T("focusedimage")) == 0 ) SetFocusedImage(pstrValue);
  1236. else if( _tcscmp(pstrName, _T("sepimage")) == 0 ) SetSepImage(pstrValue);
  1237. else CControlUI::SetAttribute(pstrName, pstrValue);
  1238. }
  1239. void CListHeaderItemUI::DoEvent(TEventUI& event)
  1240. {
  1241. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  1242. if( m_pParent != NULL ) m_pParent->DoEvent(event);
  1243. else CControlUI::DoEvent(event);
  1244. return;
  1245. }
  1246. if( event.Type == UIEVENT_SETFOCUS )
  1247. {
  1248. Invalidate();
  1249. }
  1250. if( event.Type == UIEVENT_KILLFOCUS )
  1251. {
  1252. Invalidate();
  1253. }
  1254. if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK )
  1255. {
  1256. if( !IsEnabled() ) return;
  1257. RECT rcSeparator = GetThumbRect();
  1258. if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动
  1259. rcSeparator.left-=4;
  1260. else
  1261. rcSeparator.right+=4;
  1262. if( ::PtInRect(&rcSeparator, event.ptMouse) ) {
  1263. if( m_bDragable ) {
  1264. m_uButtonState |= UISTATE_CAPTURED;
  1265. ptLastMouse = event.ptMouse;
  1266. }
  1267. }
  1268. else {
  1269. m_uButtonState |= UISTATE_PUSHED;
  1270. m_pManager->SendNotify(this, DUI_MSGTYPE_HEADERCLICK);
  1271. Invalidate();
  1272. }
  1273. return;
  1274. }
  1275. if( event.Type == UIEVENT_BUTTONUP )
  1276. {
  1277. if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
  1278. m_uButtonState &= ~UISTATE_CAPTURED;
  1279. if( GetParent() )
  1280. GetParent()->NeedParentUpdate();
  1281. }
  1282. else if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  1283. m_uButtonState &= ~UISTATE_PUSHED;
  1284. Invalidate();
  1285. }
  1286. return;
  1287. }
  1288. if( event.Type == UIEVENT_MOUSEMOVE )
  1289. {
  1290. if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
  1291. RECT rc = m_rcItem;
  1292. if( m_iSepWidth >= 0 ) {
  1293. rc.right -= ptLastMouse.x - event.ptMouse.x;
  1294. }
  1295. else {
  1296. rc.left -= ptLastMouse.x - event.ptMouse.x;
  1297. }
  1298. if( rc.right - rc.left > GetMinWidth() ) {
  1299. m_cxyFixed.cx = rc.right - rc.left;
  1300. ptLastMouse = event.ptMouse;
  1301. if( GetParent() )
  1302. GetParent()->NeedParentUpdate();
  1303. }
  1304. }
  1305. return;
  1306. }
  1307. if( event.Type == UIEVENT_SETCURSOR )
  1308. {
  1309. RECT rcSeparator = GetThumbRect();
  1310. if (m_iSepWidth>=0)//111024 by cddjr, 增加分隔符区域,方便用户拖动
  1311. rcSeparator.left-=4;
  1312. else
  1313. rcSeparator.right+=4;
  1314. if( IsEnabled() && m_bDragable && ::PtInRect(&rcSeparator, event.ptMouse) ) {
  1315. ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
  1316. return;
  1317. }
  1318. }
  1319. if( event.Type == UIEVENT_MOUSEENTER )
  1320. {
  1321. if( IsEnabled() ) {
  1322. m_uButtonState |= UISTATE_HOT;
  1323. Invalidate();
  1324. }
  1325. return;
  1326. }
  1327. if( event.Type == UIEVENT_MOUSELEAVE )
  1328. {
  1329. if( IsEnabled() ) {
  1330. m_uButtonState &= ~UISTATE_HOT;
  1331. Invalidate();
  1332. }
  1333. return;
  1334. }
  1335. CControlUI::DoEvent(event);
  1336. }
  1337. SIZE CListHeaderItemUI::EstimateSize(SIZE szAvailable)
  1338. {
  1339. if( m_cxyFixed.cy == 0 ) return CDuiSize(m_cxyFixed.cx, m_pManager->GetDefaultFontInfo()->tm.tmHeight + 14);
  1340. return CControlUI::EstimateSize(szAvailable);
  1341. }
  1342. RECT CListHeaderItemUI::GetThumbRect() const
  1343. {
  1344. if( m_iSepWidth >= 0 ) return CDuiRect(m_rcItem.right - m_iSepWidth, m_rcItem.top, m_rcItem.right, m_rcItem.bottom);
  1345. else return CDuiRect(m_rcItem.left, m_rcItem.top, m_rcItem.left - m_iSepWidth, m_rcItem.bottom);
  1346. }
  1347. void CListHeaderItemUI::PaintStatusImage(HDC hDC)
  1348. {
  1349. if( IsFocused() ) m_uButtonState |= UISTATE_FOCUSED;
  1350. else m_uButtonState &= ~ UISTATE_FOCUSED;
  1351. if( (m_uButtonState & UISTATE_PUSHED) != 0 ) {
  1352. if( !DrawImage(hDC, m_diPushed) ) DrawImage(hDC, m_diNormal);
  1353. }
  1354. else if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1355. if( !DrawImage(hDC, m_diHot) ) DrawImage(hDC, m_diNormal);
  1356. }
  1357. else if( (m_uButtonState & UISTATE_FOCUSED) != 0 ) {
  1358. if( !DrawImage(hDC, m_diFocused) ) DrawImage(hDC, m_diNormal);
  1359. }
  1360. else {
  1361. DrawImage(hDC, m_diNormal);
  1362. }
  1363. RECT rcThumb = GetThumbRect();
  1364. rcThumb.left -= m_rcItem.left;
  1365. rcThumb.top -= m_rcItem.top;
  1366. rcThumb.right -= m_rcItem.left;
  1367. rcThumb.bottom -= m_rcItem.top;
  1368. m_diSep.rcDestOffset = rcThumb;
  1369. DrawImage(hDC, m_diSep);
  1370. }
  1371. void CListHeaderItemUI::PaintText(HDC hDC)
  1372. {
  1373. if( m_dwTextColor == 0 ) m_dwTextColor = m_pManager->GetDefaultFontColor();
  1374. RECT rcText = m_rcItem;
  1375. rcText.left += m_rcTextPadding.left;
  1376. rcText.top += m_rcTextPadding.top;
  1377. rcText.right -= m_rcTextPadding.right;
  1378. rcText.bottom -= m_rcTextPadding.bottom;
  1379. if( m_sText.IsEmpty() ) return;
  1380. int nLinks = 0;
  1381. if( m_bShowHtml )
  1382. CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \
  1383. NULL, NULL, nLinks, DT_SINGLELINE | m_uTextStyle);
  1384. else
  1385. CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, m_dwTextColor, \
  1386. m_iFont, DT_SINGLELINE | m_uTextStyle);
  1387. }
  1388. /////////////////////////////////////////////////////////////////////////////////////
  1389. //
  1390. //
  1391. CListElementUI::CListElementUI() :
  1392. m_iIndex(-1),
  1393. m_pOwner(NULL),
  1394. m_bSelected(false),
  1395. m_uButtonState(0)
  1396. {
  1397. }
  1398. LPCTSTR CListElementUI::GetClass() const
  1399. {
  1400. return _T("ListElementUI");
  1401. }
  1402. UINT CListElementUI::GetControlFlags() const
  1403. {
  1404. return UIFLAG_WANTRETURN;
  1405. }
  1406. LPVOID CListElementUI::GetInterface(LPCTSTR pstrName)
  1407. {
  1408. if( _tcscmp(pstrName, DUI_CTR_LISTITEM) == 0 ) return static_cast<IListItemUI*>(this);
  1409. if( _tcscmp(pstrName, DUI_CTR_LISTELEMENT) == 0 ) return static_cast<CListElementUI*>(this);
  1410. return CControlUI::GetInterface(pstrName);
  1411. }
  1412. IListOwnerUI* CListElementUI::GetOwner()
  1413. {
  1414. return m_pOwner;
  1415. }
  1416. void CListElementUI::SetOwner(CControlUI* pOwner)
  1417. {
  1418. m_pOwner = static_cast<IListOwnerUI*>(pOwner->GetInterface(_T("IListOwner")));
  1419. }
  1420. void CListElementUI::SetVisible(bool bVisible)
  1421. {
  1422. CControlUI::SetVisible(bVisible);
  1423. if( !IsVisible() && m_bSelected)
  1424. {
  1425. m_bSelected = false;
  1426. if( m_pOwner != NULL ) m_pOwner->SelectItem(-1);
  1427. }
  1428. }
  1429. void CListElementUI::SetEnabled(bool bEnable)
  1430. {
  1431. CControlUI::SetEnabled(bEnable);
  1432. if( !IsEnabled() ) {
  1433. m_uButtonState = 0;
  1434. }
  1435. }
  1436. int CListElementUI::GetIndex() const
  1437. {
  1438. return m_iIndex;
  1439. }
  1440. void CListElementUI::SetIndex(int iIndex)
  1441. {
  1442. m_iIndex = iIndex;
  1443. }
  1444. void CListElementUI::Invalidate()
  1445. {
  1446. if( !IsVisible() ) return;
  1447. if( GetParent() ) {
  1448. CContainerUI* pParentContainer = static_cast<CContainerUI*>(GetParent()->GetInterface(_T("Container")));
  1449. if( pParentContainer ) {
  1450. RECT rc = pParentContainer->GetPos();
  1451. RECT rcInset = pParentContainer->GetInset();
  1452. rc.left += rcInset.left;
  1453. rc.top += rcInset.top;
  1454. rc.right -= rcInset.right;
  1455. rc.bottom -= rcInset.bottom;
  1456. CScrollBarUI* pVerticalScrollBar = pParentContainer->GetVerticalScrollBar();
  1457. if( pVerticalScrollBar && pVerticalScrollBar->IsVisible() ) rc.right -= pVerticalScrollBar->GetFixedWidth();
  1458. CScrollBarUI* pHorizontalScrollBar = pParentContainer->GetHorizontalScrollBar();
  1459. if( pHorizontalScrollBar && pHorizontalScrollBar->IsVisible() ) rc.bottom -= pHorizontalScrollBar->GetFixedHeight();
  1460. RECT invalidateRc = m_rcItem;
  1461. if( !::IntersectRect(&invalidateRc, &m_rcItem, &rc) )
  1462. {
  1463. return;
  1464. }
  1465. CControlUI* pParent = GetParent();
  1466. RECT rcTemp;
  1467. RECT rcParent;
  1468. while( pParent = pParent->GetParent() )
  1469. {
  1470. rcTemp = invalidateRc;
  1471. rcParent = pParent->GetPos();
  1472. if( !::IntersectRect(&invalidateRc, &rcTemp, &rcParent) )
  1473. {
  1474. return;
  1475. }
  1476. }
  1477. if( m_pManager != NULL ) m_pManager->Invalidate(invalidateRc);
  1478. }
  1479. else {
  1480. CControlUI::Invalidate();
  1481. }
  1482. }
  1483. else {
  1484. CControlUI::Invalidate();
  1485. }
  1486. }
  1487. bool CListElementUI::Activate()
  1488. {
  1489. if( !CControlUI::Activate() ) return false;
  1490. if( m_pManager != NULL ) m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMACTIVATE);
  1491. return true;
  1492. }
  1493. bool CListElementUI::IsSelected() const
  1494. {
  1495. return m_bSelected;
  1496. }
  1497. bool CListElementUI::Select(bool bSelect, bool bTriggerEvent)
  1498. {
  1499. if( !IsEnabled() ) return false;
  1500. if( bSelect == m_bSelected ) return true;
  1501. m_bSelected = bSelect;
  1502. if( bSelect && m_pOwner != NULL ) m_pOwner->SelectItem(m_iIndex, bTriggerEvent);
  1503. Invalidate();
  1504. return true;
  1505. }
  1506. bool CListElementUI::IsExpanded() const
  1507. {
  1508. return false;
  1509. }
  1510. bool CListElementUI::Expand(bool /*bExpand = true*/)
  1511. {
  1512. return false;
  1513. }
  1514. void CListElementUI::DoEvent(TEventUI& event)
  1515. {
  1516. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  1517. if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
  1518. else CControlUI::DoEvent(event);
  1519. return;
  1520. }
  1521. if( event.Type == UIEVENT_DBLCLICK )
  1522. {
  1523. if( IsEnabled() ) {
  1524. Activate();
  1525. Invalidate();
  1526. }
  1527. return;
  1528. }
  1529. if( event.Type == UIEVENT_KEYDOWN && IsEnabled() )
  1530. {
  1531. if( event.chKey == VK_RETURN ) {
  1532. Activate();
  1533. Invalidate();
  1534. return;
  1535. }
  1536. }
  1537. // An important twist: The list-item will send the event not to its immediate
  1538. // parent but to the "attached" list. A list may actually embed several components
  1539. // in its path to the item, but key-presses etc. needs to go to the actual list.
  1540. if( m_pOwner != NULL ) m_pOwner->DoEvent(event); else CControlUI::DoEvent(event);
  1541. }
  1542. void CListElementUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  1543. {
  1544. if( _tcscmp(pstrName, _T("selected")) == 0 ) Select();
  1545. else CControlUI::SetAttribute(pstrName, pstrValue);
  1546. }
  1547. void CListElementUI::DrawItemBk (HDC hDC, const RECT& rcItem)
  1548. {
  1549. ASSERT(m_pOwner);
  1550. if( m_pOwner == NULL ) return;
  1551. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  1552. if( pInfo == NULL ) return;
  1553. DWORD iBackColor = 0;
  1554. if(!pInfo->bAlternateBk || m_iIndex % 2 == 0) iBackColor = pInfo->dwBkColor;
  1555. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1556. iBackColor = pInfo->dwHotBkColor;
  1557. }
  1558. if( IsSelected() ) {
  1559. iBackColor = pInfo->dwSelectedBkColor;
  1560. }
  1561. if( !IsEnabled() ) {
  1562. iBackColor = pInfo->dwDisabledBkColor;
  1563. }
  1564. //addby Hong
  1565. if(m_dwBackColor != 0)
  1566. {
  1567. iBackColor = m_dwBackColor;
  1568. }
  1569. if ( iBackColor != 0 ) {
  1570. CRenderEngine::DrawColor(hDC, rcItem, GetAdjustColor(iBackColor));
  1571. }
  1572. if( !IsEnabled() ) {
  1573. if( DrawImage(hDC, pInfo->diDisabled) ) return;
  1574. }
  1575. if( IsSelected() ) {
  1576. if( DrawImage(hDC, pInfo->diSelected) ) return;
  1577. }
  1578. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1579. if( DrawImage(hDC, pInfo->diHot) ) return;
  1580. }
  1581. if( !DrawImage(hDC, m_diBk) ) {
  1582. if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) {
  1583. if( DrawImage(hDC, pInfo->diBk) ) return;
  1584. }
  1585. }
  1586. if ( pInfo->dwLineColor != 0 ) {
  1587. RECT rcLine = { rcItem.left, rcItem.bottom - 1, rcItem.right, rcItem.bottom - 1 };
  1588. CRenderEngine::DrawLine(hDC, rcLine, 1, GetAdjustColor(pInfo->dwLineColor));
  1589. }
  1590. }
  1591. /////////////////////////////////////////////////////////////////////////////////////
  1592. //
  1593. //
  1594. CListLabelElementUI::CListLabelElementUI()
  1595. {
  1596. }
  1597. LPCTSTR CListLabelElementUI::GetClass() const
  1598. {
  1599. return _T("ListLabelElementUI");
  1600. }
  1601. LPVOID CListLabelElementUI::GetInterface(LPCTSTR pstrName)
  1602. {
  1603. if( _tcscmp(pstrName, DUI_CTR_LISTLABELELEMENT) == 0 ) return static_cast<CListLabelElementUI*>(this);
  1604. return CListElementUI::GetInterface(pstrName);
  1605. }
  1606. void CListLabelElementUI::DoEvent(TEventUI& event)
  1607. {
  1608. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  1609. if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
  1610. else CListElementUI::DoEvent(event);
  1611. return;
  1612. }
  1613. if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_RBUTTONDOWN )
  1614. {
  1615. if( IsEnabled() ) {
  1616. m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCLICK);
  1617. Select();
  1618. Invalidate();
  1619. }
  1620. return;
  1621. }
  1622. if( event.Type == UIEVENT_MOUSEMOVE )
  1623. {
  1624. return;
  1625. }
  1626. if( event.Type == UIEVENT_BUTTONUP )
  1627. {
  1628. return;
  1629. }
  1630. if( event.Type == UIEVENT_MOUSEENTER )
  1631. {
  1632. if( IsEnabled() ) {
  1633. m_uButtonState |= UISTATE_HOT;
  1634. Invalidate();
  1635. }
  1636. return;
  1637. }
  1638. if( event.Type == UIEVENT_MOUSELEAVE )
  1639. {
  1640. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1641. m_uButtonState &= ~UISTATE_HOT;
  1642. Invalidate();
  1643. }
  1644. return;
  1645. }
  1646. CListElementUI::DoEvent(event);
  1647. }
  1648. SIZE CListLabelElementUI::EstimateSize(SIZE szAvailable)
  1649. {
  1650. if( m_pOwner == NULL ) return CDuiSize(0, 0);
  1651. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  1652. SIZE cXY = m_cxyFixed;
  1653. if( cXY.cy == 0 && m_pManager != NULL ) {
  1654. cXY.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8;
  1655. cXY.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom;
  1656. }
  1657. if( cXY.cx == 0 && m_pManager != NULL ) {
  1658. RECT rcText = { 0, 0, 9999, cXY.cy };
  1659. if( pInfo->bShowHtml ) {
  1660. int nLinks = 0;
  1661. CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, NULL, NULL, nLinks, DT_SINGLELINE | DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER);
  1662. }
  1663. else {
  1664. CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, m_sText, 0, pInfo->nFont, DT_SINGLELINE | DT_CALCRECT | pInfo->uTextStyle & ~DT_RIGHT & ~DT_CENTER);
  1665. }
  1666. cXY.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right;
  1667. }
  1668. return cXY;
  1669. }
  1670. void CListLabelElementUI::DoPaint(HDC hDC, const RECT& rcPaint)
  1671. {
  1672. if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return;
  1673. DrawItemBk(hDC, m_rcItem);
  1674. DrawItemText(hDC, m_rcItem);
  1675. }
  1676. void CListLabelElementUI::SetItemTextColor (DWORD dwTextcolor)
  1677. {
  1678. m_iTextColor = dwTextcolor;
  1679. }
  1680. DWORD CListLabelElementUI::GetItemTextColor () const
  1681. {
  1682. return m_iTextColor;
  1683. }
  1684. void CListLabelElementUI::DrawItemText (HDC hDC, const RECT& rcItem)
  1685. {
  1686. if( m_sText.IsEmpty() ) return;
  1687. if( m_pOwner == NULL ) return;
  1688. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  1689. DWORD iTextColor = pInfo->dwTextColor;
  1690. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1691. iTextColor = pInfo->dwHotTextColor;
  1692. }
  1693. if( IsSelected() ) {
  1694. iTextColor = pInfo->dwSelectedTextColor;
  1695. }
  1696. if( !IsEnabled() ) {
  1697. iTextColor = pInfo->dwDisabledTextColor;
  1698. }
  1699. if (m_iTextColor!=0)
  1700. {
  1701. iTextColor = m_iTextColor;
  1702. }
  1703. int nLinks = 0;
  1704. RECT rcText = rcItem;
  1705. rcText.left += pInfo->rcTextPadding.left;
  1706. rcText.right -= pInfo->rcTextPadding.right;
  1707. rcText.top += pInfo->rcTextPadding.top;
  1708. rcText.bottom -= pInfo->rcTextPadding.bottom;
  1709. if( pInfo->bShowHtml )
  1710. CRenderEngine::DrawHtmlText(hDC, m_pManager, rcText, m_sText, iTextColor, \
  1711. NULL, NULL, nLinks, DT_SINGLELINE | pInfo->uTextStyle);
  1712. else
  1713. CRenderEngine::DrawText(hDC, m_pManager, rcText, m_sText, iTextColor, \
  1714. pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
  1715. }
  1716. /////////////////////////////////////////////////////////////////////////////////////
  1717. //
  1718. //
  1719. CListTextElementUI::CListTextElementUI() : m_nLinks(0), m_nHoverLink(-1), m_pOwner(NULL)
  1720. {
  1721. ::ZeroMemory(&m_rcLinks, sizeof(m_rcLinks));
  1722. }
  1723. CListTextElementUI::~CListTextElementUI()
  1724. {
  1725. CDuiString* pText;
  1726. for( int it = 0; it < m_aTexts.GetSize(); it++ ) {
  1727. pText = static_cast<CDuiString*>(m_aTexts[it]);
  1728. if( pText ) delete pText;
  1729. }
  1730. m_aTexts.Empty();
  1731. }
  1732. LPCTSTR CListTextElementUI::GetClass() const
  1733. {
  1734. return _T("ListTextElementUI");
  1735. }
  1736. LPVOID CListTextElementUI::GetInterface(LPCTSTR pstrName)
  1737. {
  1738. if( _tcscmp(pstrName, DUI_CTR_LISTTEXTELEMENT) == 0 ) return static_cast<CListTextElementUI*>(this);
  1739. return CListLabelElementUI::GetInterface(pstrName);
  1740. }
  1741. UINT CListTextElementUI::GetControlFlags() const
  1742. {
  1743. return UIFLAG_WANTRETURN | ( (IsEnabled() && m_nLinks > 0) ? UIFLAG_SETCURSOR : 0);
  1744. }
  1745. LPCTSTR CListTextElementUI::GetText(int iIndex) const
  1746. {
  1747. CDuiString* pText = static_cast<CDuiString*>(m_aTexts.GetAt(iIndex));
  1748. if( pText ) return pText->GetData();
  1749. return NULL;
  1750. }
  1751. void CListTextElementUI::SetText(int iIndex, LPCTSTR pstrText)
  1752. {
  1753. if( m_pOwner == NULL ) return;
  1754. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  1755. if( iIndex < 0 || iIndex >= pInfo->nColumns ) return;
  1756. while( m_aTexts.GetSize() < pInfo->nColumns ) { m_aTexts.Add(NULL); }
  1757. CDuiString* pText = static_cast<CDuiString*>(m_aTexts[iIndex]);
  1758. if( (pText == NULL && pstrText == NULL) || (pText && *pText == pstrText) ) return;
  1759. if ( pText ) //by cddjr 2011/10/20
  1760. pText->Assign(pstrText);
  1761. else
  1762. m_aTexts.SetAt(iIndex, new CDuiString(pstrText));
  1763. Invalidate();
  1764. }
  1765. void CListTextElementUI::SetText(int iIndex, LPSTR pstrText)
  1766. {
  1767. CA2W txt(pstrText);
  1768. SetText(iIndex,txt);
  1769. }
  1770. void CListTextElementUI::SetText(int iIndex, LPCSTR pstrText)
  1771. {
  1772. CA2W txt(pstrText);
  1773. SetText(iIndex,txt);
  1774. }
  1775. void CListTextElementUI::SetOwner(CControlUI* pOwner)
  1776. {
  1777. CListElementUI::SetOwner(pOwner);
  1778. m_pOwner = static_cast<IListUI*>(pOwner->GetInterface(_T("IList")));
  1779. }
  1780. CDuiString* CListTextElementUI::GetLinkContent(int iIndex)
  1781. {
  1782. if( iIndex >= 0 && iIndex < m_nLinks ) return &m_sLinks[iIndex];
  1783. return NULL;
  1784. }
  1785. void CListTextElementUI::DoEvent(TEventUI& event)
  1786. {
  1787. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  1788. if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
  1789. else CListLabelElementUI::DoEvent(event);
  1790. return;
  1791. }
  1792. // When you hover over a link
  1793. if( event.Type == UIEVENT_SETCURSOR ) {
  1794. for( int i = 0; i < m_nLinks; i++ ) {
  1795. if( ::PtInRect(&m_rcLinks[i], event.ptMouse) ) {
  1796. ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
  1797. return;
  1798. }
  1799. }
  1800. }
  1801. if( event.Type == UIEVENT_BUTTONUP && IsEnabled() ) {
  1802. for( int i = 0; i < m_nLinks; i++ ) {
  1803. if( ::PtInRect(&m_rcLinks[i], event.ptMouse) ) {
  1804. m_pManager->SendNotify(this, DUI_MSGTYPE_LINK, i);
  1805. return;
  1806. }
  1807. }
  1808. }
  1809. if( m_nLinks > 0 && event.Type == UIEVENT_MOUSEMOVE ) {
  1810. int nHoverLink = -1;
  1811. for( int i = 0; i < m_nLinks; i++ ) {
  1812. if( ::PtInRect(&m_rcLinks[i], event.ptMouse) ) {
  1813. nHoverLink = i;
  1814. break;
  1815. }
  1816. }
  1817. if(m_nHoverLink != nHoverLink) {
  1818. Invalidate();
  1819. m_nHoverLink = nHoverLink;
  1820. }
  1821. }
  1822. if( m_nLinks > 0 && event.Type == UIEVENT_MOUSELEAVE ) {
  1823. if(m_nHoverLink != -1) {
  1824. Invalidate();
  1825. m_nHoverLink = -1;
  1826. }
  1827. }
  1828. CListLabelElementUI::DoEvent(event);
  1829. }
  1830. SIZE CListTextElementUI::EstimateSize(SIZE szAvailable)
  1831. {
  1832. TListInfoUI* pInfo = NULL;
  1833. if( m_pOwner ) pInfo = m_pOwner->GetListInfo();
  1834. SIZE cXY = m_cxyFixed;
  1835. if( cXY.cy == 0 && m_pManager != NULL ) {
  1836. cXY.cy = m_pManager->GetFontInfo(pInfo->nFont)->tm.tmHeight + 8;
  1837. if( pInfo ) cXY.cy += pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom;
  1838. }
  1839. return cXY;
  1840. }
  1841. void CListTextElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
  1842. {
  1843. if( m_pOwner == NULL ) return;
  1844. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  1845. DWORD iTextColor = pInfo->dwTextColor;
  1846. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  1847. iTextColor = pInfo->dwHotTextColor;
  1848. }
  1849. if( IsSelected() ) {
  1850. iTextColor = pInfo->dwSelectedTextColor;
  1851. }
  1852. if( !IsEnabled() ) {
  1853. iTextColor = pInfo->dwDisabledTextColor;
  1854. }
  1855. auto iUserTextColor = GetItemTextColor ();
  1856. if(iUserTextColor!=0)
  1857. {
  1858. iTextColor = iUserTextColor;
  1859. }
  1860. IListCallbackUI* pCallback = m_pOwner->GetTextCallback();
  1861. //ASSERT(pCallback);
  1862. //if( pCallback == NULL ) return;
  1863. m_nLinks = 0;
  1864. int nLinks = lengthof(m_rcLinks);
  1865. for( int i = 0; i < pInfo->nColumns; i++ )
  1866. {
  1867. RECT rcItem = { pInfo->rcColumn[i].left, m_rcItem.top, pInfo->rcColumn[i].right, m_rcItem.bottom };
  1868. rcItem.left += pInfo->rcTextPadding.left;
  1869. rcItem.right -= pInfo->rcTextPadding.right;
  1870. rcItem.top += pInfo->rcTextPadding.top;
  1871. rcItem.bottom -= pInfo->rcTextPadding.bottom;
  1872. CDuiString strText;//不使用LPCTSTR,否则限制太多 by cddjr 2011/10/20
  1873. if( pCallback ) strText = pCallback->GetItemText(this, m_iIndex, i);
  1874. else strText.Assign(GetText(i));
  1875. if( pInfo->bShowHtml )
  1876. CRenderEngine::DrawHtmlText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
  1877. &m_rcLinks[m_nLinks], &m_sLinks[m_nLinks], nLinks, DT_SINGLELINE | pInfo->uTextStyle);
  1878. else
  1879. CRenderEngine::DrawText(hDC, m_pManager, rcItem, strText.GetData(), iTextColor, \
  1880. pInfo->nFont, DT_SINGLELINE | pInfo->uTextStyle);
  1881. m_nLinks += nLinks;
  1882. nLinks = lengthof(m_rcLinks) - m_nLinks;
  1883. }
  1884. for( int i = m_nLinks; i < lengthof(m_rcLinks); i++ ) {
  1885. ::ZeroMemory(m_rcLinks + i, sizeof(RECT));
  1886. ((CDuiString*)(m_sLinks + i))->Empty();
  1887. }
  1888. }
  1889. /////////////////////////////////////////////////////////////////////////////////////
  1890. //
  1891. //
  1892. CListContainerElementUI::CListContainerElementUI() :
  1893. m_iIndex(-1),
  1894. m_pOwner(NULL),
  1895. m_bSelected(false),
  1896. m_uButtonState(0)
  1897. {
  1898. }
  1899. LPCTSTR CListContainerElementUI::GetClass() const
  1900. {
  1901. return _T("ListContainerElementUI");
  1902. }
  1903. UINT CListContainerElementUI::GetControlFlags() const
  1904. {
  1905. return UIFLAG_WANTRETURN;
  1906. }
  1907. LPVOID CListContainerElementUI::GetInterface(LPCTSTR pstrName)
  1908. {
  1909. if( _tcscmp(pstrName, DUI_CTR_LISTITEM) == 0 ) return static_cast<IListItemUI*>(this);
  1910. if( _tcscmp(pstrName, DUI_CTR_LISTCONTAINERELEMENT) == 0 ) return static_cast<CListContainerElementUI*>(this);
  1911. return CContainerUI::GetInterface(pstrName);
  1912. }
  1913. IListOwnerUI* CListContainerElementUI::GetOwner()
  1914. {
  1915. return m_pOwner;
  1916. }
  1917. void CListContainerElementUI::SetOwner(CControlUI* pOwner)
  1918. {
  1919. m_pOwner = static_cast<IListOwnerUI*>(pOwner->GetInterface(_T("IListOwner")));
  1920. }
  1921. void CListContainerElementUI::SetVisible(bool bVisible)
  1922. {
  1923. CContainerUI::SetVisible(bVisible);
  1924. if( !IsVisible() && m_bSelected)
  1925. {
  1926. m_bSelected = false;
  1927. if( m_pOwner != NULL ) m_pOwner->SelectItem(-1);
  1928. }
  1929. }
  1930. void CListContainerElementUI::SetEnabled(bool bEnable)
  1931. {
  1932. CControlUI::SetEnabled(bEnable);
  1933. if( !IsEnabled() ) {
  1934. m_uButtonState = 0;
  1935. }
  1936. }
  1937. int CListContainerElementUI::GetIndex() const
  1938. {
  1939. return m_iIndex;
  1940. }
  1941. void CListContainerElementUI::SetIndex(int iIndex)
  1942. {
  1943. m_iIndex = iIndex;
  1944. }
  1945. void CListContainerElementUI::Invalidate()
  1946. {
  1947. if( !IsVisible() ) return;
  1948. if( GetParent() ) {
  1949. CContainerUI* pParentContainer = static_cast<CContainerUI*>(GetParent()->GetInterface(_T("Container")));
  1950. if( pParentContainer ) {
  1951. RECT rc = pParentContainer->GetPos();
  1952. RECT rcInset = pParentContainer->GetInset();
  1953. rc.left += rcInset.left;
  1954. rc.top += rcInset.top;
  1955. rc.right -= rcInset.right;
  1956. rc.bottom -= rcInset.bottom;
  1957. CScrollBarUI* pVerticalScrollBar = pParentContainer->GetVerticalScrollBar();
  1958. if( pVerticalScrollBar && pVerticalScrollBar->IsVisible() ) rc.right -= pVerticalScrollBar->GetFixedWidth();
  1959. CScrollBarUI* pHorizontalScrollBar = pParentContainer->GetHorizontalScrollBar();
  1960. if( pHorizontalScrollBar && pHorizontalScrollBar->IsVisible() ) rc.bottom -= pHorizontalScrollBar->GetFixedHeight();
  1961. RECT invalidateRc = m_rcItem;
  1962. if( !::IntersectRect(&invalidateRc, &m_rcItem, &rc) )
  1963. {
  1964. return;
  1965. }
  1966. CControlUI* pParent = GetParent();
  1967. RECT rcTemp;
  1968. RECT rcParent;
  1969. while( pParent = pParent->GetParent() )
  1970. {
  1971. rcTemp = invalidateRc;
  1972. rcParent = pParent->GetPos();
  1973. if( !::IntersectRect(&invalidateRc, &rcTemp, &rcParent) )
  1974. {
  1975. return;
  1976. }
  1977. }
  1978. if( m_pManager != NULL ) m_pManager->Invalidate(invalidateRc);
  1979. }
  1980. else {
  1981. CContainerUI::Invalidate();
  1982. }
  1983. }
  1984. else {
  1985. CContainerUI::Invalidate();
  1986. }
  1987. }
  1988. bool CListContainerElementUI::Activate()
  1989. {
  1990. if( !CContainerUI::Activate() ) return false;
  1991. if( m_pManager != NULL ) m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMACTIVATE);
  1992. return true;
  1993. }
  1994. bool CListContainerElementUI::IsSelected() const
  1995. {
  1996. return m_bSelected;
  1997. }
  1998. bool CListContainerElementUI::Select(bool bSelect, bool bTriggerEvent)
  1999. {
  2000. if( !IsEnabled() ) return false;
  2001. if( bSelect == m_bSelected ) return true;
  2002. m_bSelected = bSelect;
  2003. if( bSelect && m_pOwner != NULL ) m_pOwner->SelectItem(m_iIndex, bTriggerEvent);
  2004. Invalidate();
  2005. return true;
  2006. }
  2007. bool CListContainerElementUI::IsExpanded() const
  2008. {
  2009. return false;
  2010. }
  2011. bool CListContainerElementUI::Expand(bool /*bExpand = true*/)
  2012. {
  2013. return false;
  2014. }
  2015. void CListContainerElementUI::DoEvent(TEventUI& event)
  2016. {
  2017. if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
  2018. if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
  2019. else CContainerUI::DoEvent(event);
  2020. return;
  2021. }
  2022. if( event.Type == UIEVENT_DBLCLICK )
  2023. {
  2024. if( IsEnabled() ) {
  2025. Activate();
  2026. Invalidate();
  2027. }
  2028. return;
  2029. }
  2030. if( event.Type == UIEVENT_KEYDOWN && IsEnabled() )
  2031. {
  2032. if( event.chKey == VK_RETURN ) {
  2033. Activate();
  2034. Invalidate();
  2035. return;
  2036. }
  2037. }
  2038. if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_RBUTTONDOWN )
  2039. {
  2040. if( IsEnabled() ){
  2041. m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCLICK);
  2042. Select();
  2043. Invalidate();
  2044. }
  2045. return;
  2046. }
  2047. if( event.Type == UIEVENT_BUTTONUP )
  2048. {
  2049. return;
  2050. }
  2051. if( event.Type == UIEVENT_MOUSEMOVE )
  2052. {
  2053. return;
  2054. }
  2055. if( event.Type == UIEVENT_MOUSEENTER )
  2056. {
  2057. if( IsEnabled() ) {
  2058. m_uButtonState |= UISTATE_HOT;
  2059. Invalidate();
  2060. }
  2061. return;
  2062. }
  2063. if( event.Type == UIEVENT_MOUSELEAVE )
  2064. {
  2065. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  2066. m_uButtonState &= ~UISTATE_HOT;
  2067. Invalidate();
  2068. }
  2069. return;
  2070. }
  2071. // An important twist: The list-item will send the event not to its immediate
  2072. // parent but to the "attached" list. A list may actually embed several components
  2073. // in its path to the item, but key-presses etc. needs to go to the actual list.
  2074. if( m_pOwner != NULL ) m_pOwner->DoEvent(event); else CControlUI::DoEvent(event);
  2075. }
  2076. void CListContainerElementUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  2077. {
  2078. if( _tcscmp(pstrName, _T("selected")) == 0 ) Select();
  2079. else CContainerUI::SetAttribute(pstrName, pstrValue);
  2080. }
  2081. void CListContainerElementUI::DoPaint(HDC hDC, const RECT& rcPaint)
  2082. {
  2083. if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return;
  2084. DrawItemBk(hDC, m_rcItem);
  2085. CContainerUI::DoPaint(hDC, rcPaint);
  2086. }
  2087. void CListContainerElementUI::DrawItemText(HDC hDC, const RECT& rcItem)
  2088. {
  2089. return;
  2090. }
  2091. void CListContainerElementUI::DrawItemBk(HDC hDC, const RECT& rcItem)
  2092. {
  2093. ASSERT(m_pOwner);
  2094. if( m_pOwner == NULL ) return;
  2095. TListInfoUI* pInfo = m_pOwner->GetListInfo();
  2096. if( pInfo == NULL ) return;
  2097. DWORD iBackColor = 0;
  2098. if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) iBackColor = pInfo->dwBkColor;
  2099. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  2100. iBackColor = pInfo->dwHotBkColor;
  2101. }
  2102. if( IsSelected() ) {
  2103. iBackColor = pInfo->dwSelectedBkColor;
  2104. }
  2105. if( !IsEnabled() ) {
  2106. iBackColor = pInfo->dwDisabledBkColor;
  2107. }
  2108. if ( iBackColor != 0 ) {
  2109. CRenderEngine::DrawColor(hDC, m_rcItem, GetAdjustColor(iBackColor));
  2110. }
  2111. if( !IsEnabled() ) {
  2112. if( DrawImage(hDC, pInfo->diDisabled) ) return;
  2113. }
  2114. if( IsSelected() ) {
  2115. if( DrawImage(hDC, pInfo->diSelected) ) return;
  2116. }
  2117. if( (m_uButtonState & UISTATE_HOT) != 0 ) {
  2118. if( DrawImage(hDC, pInfo->diHot) ) return;
  2119. }
  2120. if( !DrawImage(hDC, m_diBk) ) {
  2121. if( !pInfo->bAlternateBk || m_iIndex % 2 == 0 ) {
  2122. if( DrawImage(hDC, pInfo->diBk) ) return;
  2123. }
  2124. }
  2125. if ( pInfo->dwLineColor != 0 ) {
  2126. RECT rcLine = { m_rcItem.left, m_rcItem.bottom - 1, m_rcItem.right, m_rcItem.bottom - 1 };
  2127. CRenderEngine::DrawLine(hDC, rcLine, 1, GetAdjustColor(pInfo->dwLineColor));
  2128. }
  2129. }
  2130. } // namespace DuiLib