soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SMCListView.cpp
1#include "souistd.h"
2#include "control/SMCListView.h"
3#include "helper/SListViewItemLocator.h"
4
5#pragma warning(disable : 4267 4018)
6
7#define ITEM_MARGIN 4
8SNSBEGIN
9class SMCListViewDataSetObserver : public TObjRefImpl<ILvDataSetObserver> {
10 public:
11 SMCListViewDataSetObserver(SMCListView *pView)
12 : m_pOwner(pView)
13 {
14 }
15 STDMETHOD_(void, onChanged)(THIS) OVERRIDE;
16
17 STDMETHOD_(void, onInvalidated)(THIS) OVERRIDE;
18
19 STDMETHOD_(void, OnItemChanged)(THIS_ int iItem) OVERRIDE;
20
21 protected:
22 SMCListView *m_pOwner;
23};
24
25//////////////////////////////////////////////////////////////////////////
26void SMCListViewDataSetObserver::onChanged()
27{
28 m_pOwner->onDataSetChanged();
29}
30
31void SMCListViewDataSetObserver::onInvalidated()
32{
33 m_pOwner->onDataSetInvalidated();
34}
35
36void SMCListViewDataSetObserver::OnItemChanged(int iItem)
37{
38 m_pOwner->onItemDataChanged(iItem);
39}
40
41//////////////////////////////////////////////////////////////////////////
42// SMCListView
43
45 : m_pHeader(NULL)
46 , m_iSelItem(-1)
47 , m_iFirstVisible(-1)
48 , m_pHoverItem(NULL)
49 , m_itemCapture(NULL)
50 , m_pSkinDivider(NULL)
51 , m_bWantTab(FALSE)
53 , m_bPendingUpdate(false)
56 , m_crGrid(CR_INVALID)
57 , SHostProxy(this)
58{
59 m_bFocusable = TRUE;
60 m_bClipClient = TRUE;
61 m_dwUpdateInterval = 40;
62 m_nHeaderHeight.fromString(L"25dp");
63 m_observer.Attach(new SMCListViewDataSetObserver(this));
64
65 m_evtSet.addEvent(EVENTID(EventLVSelChanging));
66 m_evtSet.addEvent(EVENTID(EventLVSelChanged));
67}
68
74
75BOOL SMCListView::SetAdapter(IMcAdapter *adapter)
76{
77 if (!m_lvItemLocator)
78 {
79 SASSERT_MSGA(FALSE, "error: A item locator is in need before setting adapter!!!");
80 return FALSE;
81 }
82 if (m_adapter == adapter)
83 {
84 SSLOGW() << "the new adapter is same to previous set adapter, same as notifyDatasetChanged";
85 if (m_adapter)
86 {
88 }
89 return TRUE;
90 }
91 if (m_adapter)
92 {
93 m_adapter->unregisterDataSetObserver(m_observer);
94 }
95 {
96 // free all itemPanels in recycle
97 for (size_t i = 0; i < m_itemRecycle.GetCount(); i++)
98 {
99 SList<SItemPanel *> *lstItemPanels = m_itemRecycle.GetAt(i);
100 SPOSITION pos = lstItemPanels->GetHeadPosition();
101 while (pos)
102 {
103 SItemPanel *pItemPanel = lstItemPanels->GetNext(pos);
104 pItemPanel->Destroy();
105 }
106 delete lstItemPanels;
107 }
108 m_itemRecycle.RemoveAll();
109
110 // free all visible itemPanels
111 SPOSITION pos = m_lstItems.GetHeadPosition();
112 while (pos)
113 {
114 ItemInfo ii = m_lstItems.GetNext(pos);
115 ii.pItem->Destroy();
116 }
117 m_lstItems.RemoveAll();
118 m_pHoverItem = NULL;
119 m_itemCapture = NULL;
120 m_iSelItem = -1;
121 m_iFirstVisible = -1;
122 }
123
124 m_adapter = adapter;
125 if (m_lvItemLocator)
126 m_lvItemLocator->SetAdapter(adapter);
127 if (m_adapter)
128 {
129 SXmlNode xmlNode = m_xmlTemplate.root().first_child();
130 m_adapter->InitByTemplate(&xmlNode);
131 m_adapter->registerDataSetObserver(m_observer);
132 for (int i = 0; i < m_adapter->getViewTypeCount(); i++)
133 {
134 m_itemRecycle.Add(new SList<SItemPanel *>());
135 }
138 }
139 return TRUE;
140}
141
142int SMCListView::InsertColumn(int nIndex, LPCTSTR pszText, int nWidth, UINT fmt, LPARAM lParam, BOOL bDpiAware /*=TRUE*/, float fWeight /*=0.0f*/)
143{
144 SASSERT(m_pHeader);
145 int nRet = m_pHeader->InsertItem(nIndex, pszText, nWidth, fmt, lParam, bDpiAware, fWeight);
147 return nRet;
148}
149
151{
152 // listctrl的子控件只能是一个header控件
153 SXmlNode xmlTemplate = xmlNode.child(L"template");
154 xmlTemplate.set_userdata(1);
155 SXmlNode xmlHeader = xmlNode.child(L"headerStyle");
156 xmlHeader.set_userdata(1);
157 m_pHeader = sobj_cast<SHeaderCtrl>(CreateChildByName(xmlHeader.attribute(L"wndclass").as_string(SHeaderCtrl::GetClassName())));
158 if (!m_pHeader)
159 return FALSE;
161 m_pHeader->InitFromXml(&xmlHeader);
162
163 if (!__baseCls::CreateChildren(xmlNode))
164 return FALSE;
165 if (xmlTemplate)
166 {
167 m_xmlTemplate.root().append_copy(xmlTemplate);
168 SLayoutSize nItemHei = GETLAYOUTSIZE(xmlTemplate.attribute(L"itemHeight").value());
169 if (nItemHei.fSize > 0.0f)
170 { //指定了itemHeight属性时创建一个固定行高的定位器
171 IListViewItemLocator *pItemLocator = new SListViewItemLocatorFix(nItemHei, m_nDividerSize);
172 SetItemLocator(pItemLocator);
173 pItemLocator->Release();
174 }
175 else
176 { //创建一个行高可变的行定位器,从defHeight属性中获取默认行高
177 IListViewItemLocator *pItemLocator = new SListViewItemLocatorFlex(GETLAYOUTSIZE(xmlTemplate.attribute(L"defHeight").as_string(L"30dp")), m_nDividerSize);
178 SetItemLocator(pItemLocator);
179 pItemLocator->Release();
180 }
181 }
182
183 m_pHeader->GetEventSet()->subscribeEvent(EventHeaderItemChanging::EventID, Subscriber(&SMCListView::OnHeaderSizeChanging, this));
184 m_pHeader->GetEventSet()->subscribeEvent(EventHeaderItemSwap::EventID, Subscriber(&SMCListView::OnHeaderSwap, this));
185 m_pHeader->GetEventSet()->subscribeEvent(EventHeaderClick::EventID, Subscriber(&SMCListView::OnHeaderClick, this));
186
187 return TRUE;
188}
189
191{
192 CRect rcList;
193
194 GetClientRect(&rcList);
195 rcList.top += GetHeaderHeight();
196
197 return rcList;
198}
199
200// 更新滚动条
202{
203 CSize szView;
204 szView.cx = m_pHeader->GetTotalWidth(false);
205 int nMinWid = m_pHeader->GetTotalWidth(true);
206 szView.cy = m_lvItemLocator->GetTotalHeight();
207
208 CRect rcClient;
209 SWindow::GetClientRect(&rcClient); //不计算滚动条大小
210 rcClient.top += GetHeaderHeight();
211 if (rcClient.bottom < rcClient.top)
212 rcClient.bottom = rcClient.top;
213 CSize size = rcClient.Size();
214 // 关闭滚动条
215 m_wBarVisible = SSB_NULL;
216
217 if (size.cy < szView.cy || (size.cy < szView.cy + GetSbWidth() && size.cx < szView.cx))
218 {
219 // 需要纵向滚动条
220 m_wBarVisible |= SSB_VERT;
221 m_siVer.nMin = 0;
222 m_siVer.nMax = szView.cy - 1;
223 m_siVer.nPage = rcClient.Height();
224
225 int horzSize = size.cx - GetSbWidth();
226 if (horzSize < nMinWid)
227 {
228 // 小于表头的最小宽度, 需要横向滚动条
229 m_wBarVisible |= SSB_HORZ;
230 m_siVer.nPage = size.cy - GetSbWidth() > 0 ? size.cy - GetSbWidth() : 0; //注意同时调整纵向滚动条page信息
231
232 m_siHoz.nMin = 0;
233 m_siHoz.nMax = szView.cx - 1;
234 m_siHoz.nPage = (size.cx - GetSbWidth()) > 0 ? (size.cx - GetSbWidth()) : 0;
235 }
236 else
237 {
238 if (horzSize < szView.cx || m_pHeader->IsAutoResize())
239 { //大于最小宽度,小于现在宽度,则调整表头的宽度。
240 CRect rcHead = m_pHeader->GetWindowRect();
241 rcHead.right = rcHead.left + horzSize;
242 m_pHeader->Move(rcHead);
243 szView.cx = horzSize;
244 }
245 // 不需要横向滚动条
246 m_siHoz.nPage = szView.cx;
247 m_siHoz.nMin = 0;
248 m_siHoz.nMax = m_siHoz.nPage - 1;
249 m_siHoz.nPos = 0;
250 }
251 }
252 else
253 {
254 // 不需要纵向滚动条
255 m_siVer.nPage = size.cy;
256 m_siVer.nMin = 0;
257 m_siVer.nMax = size.cy - 1;
258 m_siVer.nPos = 0;
259
260 if (size.cx < nMinWid)
261 {
262 //小于表头的最小宽度, 需要横向滚动条
263 m_wBarVisible |= SSB_HORZ;
264 m_siHoz.nMin = 0;
265 m_siHoz.nMax = szView.cx - 1;
266 m_siHoz.nPage = size.cx;
267 }
268 else
269 {
270 if (size.cx < szView.cx || m_pHeader->IsAutoResize())
271 { //大于最小宽度,小于现在宽度,则调整表头的宽度。
272 CRect rcHead = m_pHeader->GetWindowRect();
273 rcHead.right = rcHead.left + size.cx;
274 m_pHeader->Move(rcHead);
275 szView.cx = size.cx;
276 }
277 // 不需要横向滚动条
278 m_siHoz.nPage = szView.cx;
279 m_siHoz.nMin = 0;
280 m_siHoz.nMax = m_siHoz.nPage - 1;
281 m_siHoz.nPos = 0;
282 }
283 }
284
285 // 根据需要调整原点位置
286 if (HasScrollBar(FALSE) && m_siHoz.nPos + m_siHoz.nPage > szView.cx)
287 {
288 m_siHoz.nPos = szView.cx - m_siHoz.nPage;
289 }
290
291 if (HasScrollBar(TRUE) && m_siVer.nPos + m_siVer.nPage > szView.cy)
292 {
293 m_siVer.nPos = szView.cy - m_siVer.nPage;
294 }
295
296 SetScrollPos(TRUE, m_siVer.nPos, TRUE);
297 SetScrollPos(FALSE, m_siHoz.nPos, TRUE);
298
299 // 重新计算客户区及非客户区
300 SSendMessage(WM_NCCALCSIZE);
301
302 Invalidate();
303}
304
305//更新表头位置
307{
308 CRect rcClient;
309 GetClientRect(&rcClient);
310 CRect rcHeader(rcClient);
311 rcHeader.bottom = rcHeader.top + GetHeaderHeight();
312 rcHeader.left -= m_siHoz.nPos;
313 if (m_pHeader)
314 m_pHeader->Move(rcHeader);
315}
316
318{
319 if (m_pHeader->DeleteItem(iCol))
320 {
322 }
323}
324
326{
327 if (!m_pHeader)
328 return 0;
329
330 return m_pHeader->GetItemCount();
331}
332
334{
335 __baseCls::UpdateChildrenPosition();
337}
338
340{
341 return m_nHeaderHeight.toPixelSize(GetScale());
342}
343
344BOOL SMCListView::OnHeaderClick(IEvtArgs *pEvt)
345{
346 EventHeaderClick *pEvt2 = sobj_cast<EventHeaderClick>(pEvt);
347 SASSERT(pEvt2);
348 SHDITEM hi = { SHDI_ORDER | SHDI_FORMAT, 0 };
349 UINT *pFmts = new UINT[m_pHeader->GetItemCount()];
350 int *pOrders = new int[m_pHeader->GetItemCount()];
351 int iCol = -1;
352 for (int i = 0; i < m_pHeader->GetItemCount(); i++)
353 {
354 m_pHeader->GetItem(i, &hi);
355 pFmts[hi.iOrder] = hi.fmt;
356 pOrders[hi.iOrder] = i;
357 if (i == pEvt2->iItem)
358 iCol = hi.iOrder;
359 }
360 if (m_adapter && m_adapter->OnSort(iCol, pFmts, m_pHeader->GetItemCount()))
361 {
362 //更新表头的排序状态
363 for (int i = 0; i < m_pHeader->GetItemCount(); i++)
364 {
365 m_pHeader->SetItemSort(pOrders[i], pFmts[i]);
366 }
368 }
369 delete[] pOrders;
370 delete[] pFmts;
371 return TRUE;
372}
373
375{
378 if (!m_lvItemLocator->IsFixHeight())
379 {
382 }
383 else
384 {
385 SPOSITION pos = m_lstItems.GetHeadPosition();
386 while (pos)
387 {
388 ItemInfo ii = m_lstItems.GetNext(pos);
389 CRect rcItem = ii.pItem->GetWindowRect();
390 rcItem.right = m_pHeader->GetTotalWidth();
391 ii.pItem->Move(rcItem);
392 CRect rcSubItem(rcItem);
393 rcSubItem.right = rcSubItem.left = 0;
394 for (int i = 0; i < m_pHeader->GetItemCount(); i++)
395 {
396 SHDITEM hi = { SHDI_ORDER, 0 };
397 m_pHeader->GetItem(i, &hi);
398 rcSubItem.left = rcSubItem.right;
399 rcSubItem.right += m_pHeader->GetItemWidth(i);
400 SStringW strColName;
401 m_adapter->GetColumnName(hi.iOrder, &strColName);
402 SWindow *pCol = ii.pItem->FindChildByName(strColName);
403 if (pCol)
404 {
405 pCol->Move(rcSubItem);
406 }
407 }
408 SASSERT(rcSubItem.right == m_pHeader->GetTotalWidth());
409 }
410
412 }
413 return TRUE;
414}
415
416BOOL SMCListView::OnHeaderSwap(IEvtArgs *pEvt)
417{
419 return TRUE;
420}
421
423{
424 if (!m_adapter)
425 return;
426 if (!IsVisible(TRUE))
427 {
428 m_bPendingUpdate = true;
430 return;
431 }
432
433 //更新列显示状态
434 m_pHeader->GetEventSet()->setMutedState(true);
435 for (size_t i = 0; i < m_pHeader->GetItemCount(); i++)
436 {
437 int iCol = m_pHeader->GetOriItemIndex(i);
438 m_pHeader->SetItemVisible(i, m_adapter->IsColumnVisible(iCol));
439 }
440 m_pHeader->GetEventSet()->setMutedState(false);
441
442 if (m_lvItemLocator)
443 m_lvItemLocator->OnDataSetChanged();
444 if (m_iSelItem >= m_adapter->getCount())
445 m_iSelItem = -1;
446
449}
450
456
458{
459 if (!m_adapter)
460 return;
461 if (!IsVisible(TRUE))
462 {
463 m_bPendingUpdate = true;
464 m_iPendingUpdateItem = m_iPendingUpdateItem == -2 ? iItem : -1;
465 return;
466 }
467
468 if (iItem < m_iFirstVisible)
469 return;
470 if (iItem >= m_iFirstVisible + (int)m_lstItems.GetCount())
471 return;
472 if (m_lvItemLocator->IsFixHeight())
473 UpdateVisibleItem(iItem);
474 else
476}
477
479{
481 {
483 m_bDatasetInvalidated = FALSE;
484 }
485 SPainter duiDC;
486 BeforePaint(pRT, duiDC);
487
488 float fMat[9];
489 pRT->GetTransform(fMat);
490 SMatrix mtx(fMat);
491
492 int iFirst = m_iFirstVisible;
493 if (iFirst != -1)
494 {
495 CRect rcClient;
496 GetClientRect(&rcClient);
497 rcClient.top += GetHeaderHeight();
498
499 pRT->PushClipRect(&rcClient, RGN_AND);
500
501 CRect rcClip, rcInter;
502 SAutoRefPtr<IRegionS> rgnClip;
503 pRT->GetClipBox(&rcClip);
504 pRT->GetClipRegion(&rgnClip);
505
506 SPOSITION pos = m_lstItems.GetHeadPosition();
507 int i = 0;
508 IRenderObj *oldPen = NULL;
509 if (m_crGrid != CR_INVALID)
510 {
512 pRT->CreatePen(PS_SOLID, m_crGrid, 1, &pen);
513 pRT->SelectObject(pen, &oldPen);
514 }
515
516 for (; pos; i++)
517 {
518 ItemInfo ii = m_lstItems.GetNext(pos);
519 CRect rcItem = _OnItemGetRect(iFirst + i);
520 if (SItemPanel::IsItemInClip(mtx, rcClip, rgnClip, rcItem))
521 ii.pItem->Draw(pRT, rcItem);
522 if (m_crGrid != CR_INVALID)
523 {
524 BOOL bAntiAlias = pRT->SetAntiAlias(FALSE);
525 if (i == 0)
526 {
527 POINT pts[2] = { { rcItem.left, rcItem.top }, { rcItem.right, rcItem.top } };
528 pRT->DrawLines(pts, 2);
529 }
530 POINT pts[2] = { { rcItem.left, rcItem.bottom - 1 }, { rcItem.right, rcItem.bottom - 1 } };
531 pRT->DrawLines(pts, 2);
532 pRT->SetAntiAlias(bAntiAlias);
533 }
534 rcItem.top = rcItem.bottom;
535 rcItem.bottom += m_lvItemLocator->GetDividerSize();
536 if (m_pSkinDivider && !rcItem.IsRectEmpty() && rgnClip->RectInRegion(&rcItem))
537 { //绘制分隔线
538 m_pSkinDivider->DrawByIndex(pRT, rcItem, 0);
539 }
540 }
541 if (m_crGrid != CR_INVALID)
542 {
543 // draw vertical grid.
544 BOOL bAntiAlias = pRT->SetAntiAlias(FALSE);
545
546 CRect rcTop = _OnItemGetRect(iFirst);
547 CRect rcBottom = _OnItemGetRect(iFirst + m_lstItems.GetCount() - 1);
548 POINT pts[2] = { { rcTop.left, rcTop.top }, { rcTop.left, rcBottom.bottom } };
549 pRT->DrawLines(pts, 2);
550 pts[0].x--, pts[1].x--;
551 for (int i = 0; i < m_pHeader->GetItemCount(); i++)
552 {
553 if (!m_pHeader->IsItemVisible(i))
554 continue;
555 int wid = m_pHeader->GetItemWidth(i);
556 pts[0].x += wid;
557 pts[1].x += wid;
558 pRT->DrawLines(pts, 2);
559 }
560 pRT->SetAntiAlias(bAntiAlias);
561
562 pRT->SelectObject(oldPen, NULL);
563 }
564 pRT->PopClip();
565 }
566 AfterPaint(pRT, duiDC);
567}
568
569BOOL SMCListView::OnScroll(BOOL bVertical, UINT uCode, int nPos)
570{
571 int nOldPos = bVertical ? m_siVer.nPos : m_siHoz.nPos;
572 __baseCls::OnScroll(bVertical, uCode, nPos);
573 int nNewPos = bVertical ? m_siVer.nPos : m_siHoz.nPos;
574 if (nOldPos != nNewPos)
575 {
576 if (bVertical)
578 else
580 //加速滚动时UI的刷新
581 if (uCode == SB_THUMBTRACK)
582 ScrollUpdate();
583
584 return TRUE;
585 }
586 return FALSE;
587}
588
590{
591 if (!m_adapter)
592 return;
593 SAutoEnableHostPrivUiDef enableUiDef(this);
594 int iOldFirstVisible = m_iFirstVisible;
595 int iOldLastVisible = m_iFirstVisible + m_lstItems.GetCount();
596 int nOldTotalHeight = m_lvItemLocator->GetTotalHeight();
597
598 int iNewFirstVisible = m_lvItemLocator->Position2Item(m_siVer.nPos);
599 int iNewLastVisible = iNewFirstVisible;
600 int pos = m_lvItemLocator->Item2Position(iNewFirstVisible);
601 int iHoverItem = m_pHoverItem ? (int)m_pHoverItem->GetItemIndex() : -1;
602 m_pHoverItem = NULL;
603
604 ItemInfo *pItemInfos = new ItemInfo[m_lstItems.GetCount()];
605 SPOSITION spos = m_lstItems.GetHeadPosition();
606 int i = 0;
607 while (spos)
608 {
609 pItemInfos[i++] = m_lstItems.GetNext(spos);
610 }
611
612 m_lstItems.RemoveAll();
613
614 if (iNewFirstVisible != -1)
615 {
616 while (pos < m_siVer.nPos + (int)m_siVer.nPage && iNewLastVisible < m_adapter->getCount())
617 {
618 DWORD dwState = WndState_Normal;
619 if (iHoverItem == iNewLastVisible)
620 dwState |= WndState_Hover;
621 if (m_iSelItem == iNewLastVisible)
622 dwState |= WndState_Check;
623
624 ItemInfo ii = { NULL, -1 };
625 ii.nType = m_adapter->getItemViewType(iNewLastVisible, dwState);
626
627 if (iNewLastVisible >= iOldFirstVisible && iNewLastVisible < iOldLastVisible)
628 { // use the old visible item
629 int iItem = iNewLastVisible - iOldFirstVisible; //(iNewLastVisible-iNewFirstVisible) +
630 //(iNewFirstVisible-iOldFirstVisible);
631 SASSERT(iItem >= 0 && iItem <= (iOldLastVisible - iOldFirstVisible));
632 if (pItemInfos[iItem].nType == ii.nType)
633 { //类型相同才能重用
634 ii = pItemInfos[iItem];
635 pItemInfos[iItem].pItem = NULL; //标记该行已经被重用
636 }
637 }
638 BOOL bNewItem = FALSE;
639 if (!ii.pItem)
640 { // create new visible item
641 SList<SItemPanel *> *lstRecycle = m_itemRecycle.GetAt(ii.nType);
642 if (lstRecycle->IsEmpty())
643 { //创建一个新的列表项
644 bNewItem = TRUE;
645 ii.pItem = SItemPanel::Create(this, SXmlNode(), this);
646 ii.pItem->GetEventSet()->subscribeEvent(EventItemPanelClick::EventID, Subscriber(&SMCListView::OnItemClick, this));
647 }
648 else
649 {
650 ii.pItem = lstRecycle->RemoveHead();
651 }
652 ii.pItem->SetItemIndex(iNewLastVisible);
653 }
654 ii.pItem->SetVisible(TRUE);
655 CRect rcItem(0, 0, m_pHeader->GetTotalWidth(), 100000);
656 if (m_lvItemLocator->IsFixHeight())
657 {
658 rcItem.bottom = m_lvItemLocator->GetItemHeight(iNewLastVisible);
659 ii.pItem->Move(rcItem);
660 }
661
662 //设置状态,同时暂时禁止应用响应statechanged事件。
663 ii.pItem->GetEventSet()->setMutedState(true);
664 ii.pItem->ModifyItemState(dwState, 0);
665 ii.pItem->GetEventSet()->setMutedState(false);
666 if (dwState & WndState_Hover)
667 m_pHoverItem = ii.pItem;
668
669 //应用可以根据ii.pItem的状态来决定如何初始化列表数据
670 SXmlNode xmlNode = m_xmlTemplate.root().first_child();
671 ii.pItem->LockUpdate();
672 m_adapter->getView(iNewLastVisible, ii.pItem, &xmlNode);
673 ii.pItem->UnlockUpdate();
674 if (bNewItem)
675 {
676 ii.pItem->SDispatchMessage(UM_SETSCALE, GetScale(), 0);
677 ii.pItem->SDispatchMessage(UM_SETLANGUAGE, 0, 0);
678 ii.pItem->DoColorize(GetColorizeColor());
679 }
680
681 if (!m_lvItemLocator->IsFixHeight())
682 { //计算出列表行高度
683 SIZE szView;
684 m_adapter->getViewDesiredSize(&szView, iNewLastVisible, ii.pItem, rcItem.Width(), rcItem.Height());
685 m_lvItemLocator->SetItemHeight(iNewLastVisible, szView.cy);
686 rcItem.bottom = szView.cy;
687 ii.pItem->Move(rcItem);
688 }
689 ii.pItem->UpdateLayout();
690
691 //调整网格大小
692 CRect rcSubItem(rcItem);
693 rcSubItem.right = rcSubItem.left;
694 for (int i = 0; i < m_pHeader->GetItemCount(); i++)
695 {
696 SHDITEM hditem = { SHDI_ORDER | SHDI_WIDTH, 0 };
697 m_pHeader->GetItem(i, &hditem);
698 SStringW strColName;
699 m_adapter->GetColumnName(hditem.iOrder, &strColName);
700 SWindow *pColWnd = ii.pItem->FindChildByName(strColName);
701 SASSERT(pColWnd);
702 if (m_pHeader->IsItemVisible(i))
703 {
704 pColWnd->SetVisible(true);
705 rcSubItem.left = rcSubItem.right;
706 rcSubItem.right += hditem.cx;
707 pColWnd->Move(rcSubItem);
708 }
709 else
710 {
711 pColWnd->SetVisible(false);
712 }
713 }
714
715 m_lstItems.AddTail(ii);
716 pos += rcItem.bottom + m_lvItemLocator->GetDividerSize();
717
718 iNewLastVisible++;
719 }
720 }
721
722 // move old visible items which were not reused to recycle
723 for (int i = 0; i < (iOldLastVisible - iOldFirstVisible); i++)
724 {
725 ItemInfo ii = pItemInfos[i];
726 if (!ii.pItem)
727 continue;
728
729 if (ii.pItem->GetState() & WndState_Hover)
730 {
731 ii.pItem->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
732 }
733 ii.pItem->GetEventSet()->setMutedState(true);
734 if (ii.pItem->GetState() & WndState_Check)
735 {
736 ii.pItem->ModifyItemState(0, WndState_Check);
737 ii.pItem->GetFocusManager()->ClearFocus();
738 }
739 ii.pItem->SetVisible(FALSE);
740 ii.pItem->GetEventSet()->setMutedState(false);
741 m_itemRecycle[ii.nType]->AddTail(ii.pItem);
742 }
743 delete[] pItemInfos;
744
745 m_iFirstVisible = iNewFirstVisible;
746
747 if (!m_lvItemLocator->IsFixHeight() && m_lvItemLocator->GetTotalHeight() != nOldTotalHeight)
748 { // update scroll range
751 UpdateVisibleItems(); //根据新的滚动条状态重新记录显示列表项
752 }
753 else
754 {
755 InvalidateRect(NULL);
756 }
757}
758
760{
761 SAutoEnableHostPrivUiDef enableUiDef(this);
762 SASSERT(m_lvItemLocator->IsFixHeight());
763 SItemPanel *pItem = GetItemPanel(iItem);
764 SASSERT(pItem);
765 SXmlNode xmlNode = m_xmlTemplate.root().first_child();
766 m_adapter->getView(iItem, pItem, &xmlNode);
767 pItem->Invalidate();
768}
769
770void SMCListView::OnSize(UINT nType, CSize size)
771{
772 __baseCls::OnSize(nType, size);
777}
778
780{
781 if (m_adapter)
782 {
783 m_adapter->unregisterDataSetObserver(m_observer);
784 }
785
786 // destroy all itempanel
787 SPOSITION pos = m_lstItems.GetHeadPosition();
788 while (pos)
789 {
790 ItemInfo ii = m_lstItems.GetNext(pos);
791 ii.pItem->Release();
792 }
793 m_lstItems.RemoveAll();
794
795 for (int i = 0; i < (int)m_itemRecycle.GetCount(); i++)
796 {
797 SList<SItemPanel *> *pLstTypeItems = m_itemRecycle[i];
798 SPOSITION pos = pLstTypeItems->GetHeadPosition();
799 while (pos)
800 {
801 SItemPanel *pItem = pLstTypeItems->GetNext(pos);
802 pItem->Release();
803 }
804 delete pLstTypeItems;
805 }
806 m_itemRecycle.RemoveAll();
807
808 __baseCls::OnDestroy();
809}
810
811//////////////////////////////////////////////////////////////////////////
812
814{
815 return TRUE;
816}
817
818BOOL SMCListView::OnItemGetRect(const SOsrPanel *pItem, CRect &rcItem) const
819{
820 int iPosition = (int)pItem->GetItemIndex();
821 if (iPosition < 0 || iPosition >= m_adapter->getCount())
822 return FALSE;
823 rcItem = _OnItemGetRect(iPosition);
824 return TRUE;
825}
826
827CRect SMCListView::_OnItemGetRect(int iPosition) const
828{
829 int nOffset = m_lvItemLocator->Item2Position(iPosition) - m_siVer.nPos;
830 CRect rcItem = GetClientRect();
831 rcItem.top += GetHeaderHeight() + nOffset;
832 rcItem.bottom = rcItem.top + m_lvItemLocator->GetItemHeight(iPosition);
833 rcItem.left -= m_siHoz.nPos;
834 rcItem.right = rcItem.left + m_pHeader->GetTotalWidth();
835 return rcItem;
836}
837
838void SMCListView::OnItemSetCapture(SOsrPanel *pItem, BOOL bCapture)
839{
840 if (bCapture)
841 {
843 m_itemCapture = pItem;
844 }
845 else
846 {
848 m_itemCapture = NULL;
849 }
850}
851
852void SMCListView::RedrawItem(SOsrPanel *pItem)
853{
854 pItem->InvalidateRect(NULL);
855}
856
857SItemPanel *SMCListView::HitTest(CPoint &pt) const
858{
859 SPOSITION pos = m_lstItems.GetHeadPosition();
860 while (pos)
861 {
862 ItemInfo ii = m_lstItems.GetNext(pos);
863 CRect rcItem = ii.pItem->GetItemRect();
864 if (rcItem.PtInRect(pt))
865 {
866 pt -= rcItem.TopLeft();
867 return ii.pItem;
868 }
869 }
870 return NULL;
871}
872
873IItemPanel *SMCListView::HitTest(const POINT *pt) const
874{
875 SASSERT(pt);
876 if (!pt)
877 return NULL;
878 CPoint pt2(*pt);
879 return HitTest(pt2);
880}
881
882LRESULT SMCListView::OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
883{
884 SetMsgHandled(FALSE);
885
886 if (!m_adapter)
887 {
888 return 0;
889 }
890
891 LRESULT lRet = 0;
892 CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
893
894 if (m_itemCapture)
895 {
896 CRect rcItem = m_itemCapture->GetItemRect();
897 pt.Offset(-rcItem.TopLeft());
898 lRet = m_itemCapture->DoFrameEvent(uMsg, wParam, MAKELPARAM(pt.x, pt.y));
899 }
900 else
901 {
902 if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN)
903 { //交给panel处理
904 __baseCls::ProcessSwndMessage(uMsg, wParam, lParam, lRet);
905 }
906
907 SItemPanel *pHover = HitTest(pt);
908 if (pHover != m_pHoverItem)
909 {
910 SOsrPanel *nOldHover = m_pHoverItem;
911 m_pHoverItem = pHover;
912 if (nOldHover)
913 {
914 nOldHover->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
915 RedrawItem(nOldHover);
916 }
917 if (m_pHoverItem)
918 {
919 m_pHoverItem->DoFrameEvent(WM_MOUSEHOVER, wParam, MAKELPARAM(pt.x, pt.y));
921 }
922 }
923 if (m_pHoverItem)
924 {
925 m_pHoverItem->DoFrameEvent(uMsg, wParam, MAKELPARAM(pt.x, pt.y));
926 }
927 else if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN)
928 {
929 // 点击空白区域取消选中
930 SetSel(-1, TRUE);
931 }
932 }
933
934 if (uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_MBUTTONUP)
935 { //交给panel处理
936 __baseCls::ProcessSwndMessage(uMsg, wParam, lParam, lRet);
937 }
938 SetMsgHandled(TRUE);
939 return 0;
940}
941
942LRESULT SMCListView::OnKeyEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
943{
944 LRESULT lRet = 0;
945 SItemPanel *pItem = GetItemPanel(m_iSelItem);
946 if (pItem)
947 {
948 lRet = pItem->DoFrameEvent(uMsg, wParam, lParam);
949 SetMsgHandled(pItem->IsMsgHandled());
950 }
951 else
952 {
953 SetMsgHandled(FALSE);
954 }
955 return lRet;
956}
957
959{
960 __baseCls::OnMouseLeave();
961 if (m_pHoverItem)
962 {
963 m_pHoverItem->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
964 m_pHoverItem = NULL;
965 }
966}
967
968void SMCListView::OnKeyDown(TCHAR nChar, UINT nRepCnt, UINT nFlags)
969{
970 if (!m_adapter)
971 {
972 SetMsgHandled(FALSE);
973 return;
974 }
975
976 if (m_iSelItem != -1 && m_bWantTab)
977 {
978 SItemPanel *pItem = GetItemPanel(m_iSelItem);
979 if (pItem)
980 {
981 pItem->DoFrameEvent(WM_KEYDOWN, nChar, MAKELONG(nFlags, nRepCnt));
982 if (pItem->IsMsgHandled())
983 return;
984 }
985 }
986
987 int nNewSelItem = -1;
988 SWindow *pOwner = GetOwner();
989 if (pOwner && (nChar == VK_ESCAPE || nChar == VK_RETURN))
990 {
991 pOwner->SSendMessage(WM_KEYDOWN, nChar, MAKELONG(nFlags, nRepCnt));
992 return;
993 }
994
995 if (nChar == VK_DOWN && m_iSelItem < m_adapter->getCount() - 1)
996 nNewSelItem = m_iSelItem + 1;
997 else if (nChar == VK_UP && m_iSelItem > 0)
998 nNewSelItem = m_iSelItem - 1;
999 else
1000 {
1001 switch (nChar)
1002 {
1003 case VK_PRIOR:
1004 OnScroll(TRUE, SB_PAGEUP, 0);
1005 break;
1006 case VK_NEXT:
1007 OnScroll(TRUE, SB_PAGEDOWN, 0);
1008 break;
1009 case VK_HOME:
1010 OnScroll(TRUE, SB_TOP, 0);
1011 break;
1012 case VK_END:
1013 OnScroll(TRUE, SB_BOTTOM, 0);
1014 break;
1015 }
1016
1017 if (nChar == VK_PRIOR || nChar == VK_HOME)
1018 {
1019 if (!m_lstItems.IsEmpty())
1020 {
1021 nNewSelItem = (int)m_lstItems.GetHead().pItem->GetItemIndex();
1022 }
1023 }
1024 else if (nChar == VK_NEXT || nChar == VK_END)
1025 {
1026 if (!m_lstItems.IsEmpty())
1027 {
1028 nNewSelItem = (int)m_lstItems.GetTail().pItem->GetItemIndex();
1029 }
1030 }
1031 }
1032
1033 if (nNewSelItem != -1)
1034 {
1035 EnsureVisible(nNewSelItem);
1036 // 取消选择通知
1037 SetSel(nNewSelItem, TRUE);
1038 }
1039 else
1040 {
1041 SetMsgHandled(FALSE);
1042 }
1043}
1044
1046{
1047 if (iItem < 0 || iItem >= m_adapter->getCount())
1048 return;
1049 if (!IsVisible(TRUE))
1050 {
1051 m_iPendingViewItem = iItem;
1052 return;
1053 }
1054
1055 int iFirstVisible = m_iFirstVisible;
1056 int iLastVisible = m_iFirstVisible + m_lstItems.GetCount();
1057
1058 if (iItem >= iFirstVisible && iItem < iLastVisible)
1059 {
1060 if (iItem == iFirstVisible)
1061 {
1062 int pos = m_lvItemLocator->Item2Position(iItem);
1063 OnScroll(TRUE, SB_THUMBPOSITION, pos);
1064 }
1065 else if (iItem == iLastVisible - 1)
1066 {
1067 if (iItem == m_adapter->getCount() - 1)
1068 OnScroll(TRUE, SB_BOTTOM, 0);
1069 else
1070 {
1071 int pos = m_lvItemLocator->Item2Position(iItem + 1) - m_siVer.nPage;
1072 OnScroll(TRUE, SB_THUMBPOSITION, pos);
1073 }
1074 }
1075
1076 return;
1077 }
1078
1079 if (iItem < iFirstVisible)
1080 { // scroll up
1081 int pos = m_lvItemLocator->Item2Position(iItem);
1082 OnScroll(TRUE, SB_THUMBPOSITION, pos);
1083 }
1084 else // if(iItem >= iLastVisible)
1085 { // scroll down
1086 if (iItem == m_adapter->getCount() - 1)
1087 {
1088 OnScroll(TRUE, SB_BOTTOM, 0);
1089 }
1090 else
1091 {
1092 int pos = m_lvItemLocator->Item2Position(iItem + 1) - m_siVer.nPage;
1093 OnScroll(TRUE, SB_THUMBPOSITION, pos);
1094 }
1095 }
1096 if (!m_lvItemLocator->IsFixHeight())
1097 {
1098 int pos = m_lvItemLocator->Item2Position(iItem);
1099 OnScroll(TRUE, SB_THUMBPOSITION, pos);
1100 }
1101}
1102
1103BOOL SMCListView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
1104{
1105 SItemPanel *pSelItem = GetItemPanel(m_iSelItem);
1106 if (pSelItem)
1107 {
1108 CRect rcItem = pSelItem->GetItemRect();
1109 CPoint pt2 = pt - rcItem.TopLeft();
1110 if (pSelItem->DoFrameEvent(WM_MOUSEWHEEL, MAKEWPARAM(nFlags, zDelta), MAKELPARAM(pt2.x, pt2.y)))
1111 return TRUE;
1112 }
1113 return __baseCls::OnMouseWheel(nFlags, zDelta, pt);
1114}
1115
1117{
1118 return m_lvItemLocator->GetScrollLineSize();
1119}
1120
1121SItemPanel *SMCListView::GetItemPanel(int iItem)
1122{
1123 if (!m_adapter || iItem < 0 || iItem >= m_adapter->getCount())
1124 return NULL;
1125 SPOSITION pos = m_lstItems.GetHeadPosition();
1126 while (pos)
1127 {
1128 ItemInfo ii = m_lstItems.GetNext(pos);
1129 if ((int)ii.pItem->GetItemIndex() == iItem)
1130 return ii.pItem;
1131 }
1132 return NULL;
1133}
1134
1135void SMCListView::SetItemLocator(IListViewItemLocator *pItemLocator)
1136{
1137 m_lvItemLocator = pItemLocator;
1138 if (m_lvItemLocator)
1139 {
1140 m_lvItemLocator->SetAdapter(GetAdapter());
1141 m_lvItemLocator->SetScale(GetScale());
1142 }
1144}
1145
1147{
1148 if (!m_pHoverItem)
1149 return __baseCls::UpdateToolTip(pt, tipInfo);
1150 return m_pHoverItem->UpdateToolTip(pt, tipInfo);
1151}
1152
1153void SMCListView::SetSel(int iItem, BOOL bNotify)
1154{
1155 if (!m_adapter)
1156 return;
1157
1158 if (iItem >= m_adapter->getCount())
1159 return;
1160
1161 if (iItem < 0)
1162 iItem = -1;
1163
1164 int nOldSel = m_iSelItem;
1165 int nNewSel = iItem;
1166
1167 m_iSelItem = nNewSel;
1168 if (bNotify)
1169 {
1170 EventLVSelChanging evt(this);
1171 evt.bCancel = FALSE;
1172 evt.iOldSel = nOldSel;
1173 evt.iNewSel = nNewSel;
1174 FireEvent(evt);
1175 if (evt.bCancel)
1176 { // Cancel SetSel and restore selection state
1177 m_iSelItem = nOldSel;
1178 return;
1179 }
1180 }
1181
1182 if (nOldSel == nNewSel)
1183 return;
1184
1185 m_iSelItem = nOldSel;
1186 SItemPanel *pItem = GetItemPanel(nOldSel);
1187 if (pItem)
1188 {
1189 pItem->GetFocusManager()->ClearFocus();
1190 pItem->ModifyItemState(0, WndState_Check);
1191 RedrawItem(pItem);
1192 }
1193 m_iSelItem = nNewSel;
1194 pItem = GetItemPanel(nNewSel);
1195 if (pItem)
1196 {
1197 pItem->ModifyItemState(WndState_Check, 0);
1198 RedrawItem(pItem);
1199 }
1200
1201 if (bNotify)
1202 {
1203 EventLVSelChanged evt(this);
1204 evt.iOldSel = nOldSel;
1205 evt.iNewSel = nNewSel;
1206 FireEvent(evt);
1207 }
1208}
1209
1211{
1212 if (m_bWantTab)
1213 return SC_WANTALLKEYS;
1214 else
1215 return SC_WANTARROWS | SC_WANTSYSKEY;
1216}
1217
1218void SMCListView::OnKillFocus(SWND wndFocus)
1219{
1220 __baseCls::OnKillFocus(wndFocus);
1221
1222 if (m_iSelItem == -1)
1223 return;
1224
1225 SItemPanel *pSelPanel = GetItemPanel(m_iSelItem);
1226 if (pSelPanel)
1227 pSelPanel->GetFocusManager()->StoreFocusedView();
1228}
1229
1231{
1232 __baseCls::OnSetFocus(wndOld);
1233 if (m_iSelItem == -1)
1234 return;
1235
1236 SItemPanel *pSelPanel = GetItemPanel(m_iSelItem);
1237 if (pSelPanel)
1238 pSelPanel->GetFocusManager()->RestoreFocusedView();
1239}
1240
1241BOOL SMCListView::OnSetCursor(const CPoint &pt)
1242{
1243 BOOL bRet = FALSE;
1244 if (m_itemCapture)
1245 {
1246 CRect rcItem = m_itemCapture->GetItemRect();
1247 bRet = m_itemCapture->DoFrameEvent(WM_SETCURSOR, 0, MAKELPARAM(pt.x - rcItem.left, pt.y - rcItem.top)) != 0;
1248 }
1249 else if (m_pHoverItem)
1250 {
1251 CRect rcItem = m_pHoverItem->GetItemRect();
1252 bRet = m_pHoverItem->DoFrameEvent(WM_SETCURSOR, 0, MAKELPARAM(pt.x - rcItem.left, pt.y - rcItem.top)) != 0;
1253 }
1254 if (!bRet)
1255 {
1256 bRet = __baseCls::OnSetCursor(pt);
1257 }
1258 return bRet;
1259}
1260
1261BOOL SMCListView::OnItemClick(IEvtArgs *pEvt)
1262{
1263 SItemPanel *pItemPanel = sobj_cast<SItemPanel>(pEvt->Sender());
1264 int iItem = (int)pItemPanel->GetItemIndex();
1265 if (iItem != m_iSelItem)
1266 {
1267 SetSel(iItem, TRUE);
1268 }
1269 return TRUE;
1270}
1271
1273{
1274 __baseCls::OnColorize(cr);
1275 DispatchMessage2Items(UM_SETCOLORIZE, cr, 0);
1276 SPOSITION pos = m_lstItems.GetHeadPosition();
1277 while (pos)
1278 {
1279 ItemInfo ii = m_lstItems.GetNext(pos);
1280 ii.pItem->DoColorize(cr);
1281 }
1282}
1283
1285{
1286 __baseCls::OnScaleChanged(nScale);
1287 if (m_lvItemLocator)
1288 m_lvItemLocator->SetScale(nScale);
1289 DispatchMessage2Items(UM_SETSCALE, nScale, 0);
1291}
1292
1294{
1295 HRESULT hret = __baseCls::OnLanguageChanged();
1296 DispatchMessage2Items(UM_SETLANGUAGE, 0, 0);
1297 return hret;
1298}
1299
1300void SMCListView::DispatchMessage2Items(UINT uMsg, WPARAM wParam, LPARAM lParam)
1301{
1302 SPOSITION pos = m_lstItems.GetHeadPosition();
1303 while (pos)
1304 {
1305 ItemInfo ii = m_lstItems.GetNext(pos);
1306 ii.pItem->SDispatchMessage(uMsg, wParam, lParam);
1307 }
1308 for (UINT i = 0; i < m_itemRecycle.GetCount(); i++)
1309 {
1310 SList<SItemPanel *> *pLstTypeItems = m_itemRecycle[i];
1311 SPOSITION pos = pLstTypeItems->GetHeadPosition();
1312 while (pos)
1313 {
1314 SItemPanel *pItem = pLstTypeItems->GetNext(pos);
1315 pItem->SDispatchMessage(uMsg, wParam, lParam);
1316 }
1317 }
1318}
1319
1320void SMCListView::OnShowWindow(BOOL bShow, UINT nStatus)
1321{
1322 __baseCls::OnShowWindow(bShow, nStatus);
1323 if (IsVisible(TRUE))
1324 {
1325 if (m_bPendingUpdate)
1326 {
1327 if (m_iPendingUpdateItem == -1)
1329 else
1331 m_bPendingUpdate = false;
1333 }
1334 if (m_iPendingViewItem != -1)
1335 {
1337 m_iPendingViewItem = -1;
1338 }
1339 }
1340}
1341
1343{
1344 return m_pHeader;
1345}
1346
1348{
1349 __baseCls::OnRebuildFont();
1350 DispatchMessage2Items(UM_UPDATEFONT, 0, 0);
1351}
1352
1354{
1355 return m_iSelItem;
1356}
1357
1358IListViewItemLocator *SMCListView::GetItemLocator() const
1359{
1360 return m_lvItemLocator;
1361}
1362
1363IMcAdapter *SMCListView::GetAdapter() const
1364{
1365 return m_adapter;
1366}
1367
1369{
1370 return GetHeaderCtrl();
1371}
1372
1373void SMCListView::GetDesiredSize(THIS_ SIZE *psz, int nParentWid, int nParentHei)
1374{
1375 __baseCls::GetDesiredSize(psz, nParentWid, nParentHei);
1376 ILayoutParam *pLayoutParam = GetLayoutParam();
1377 if (pLayoutParam->IsWrapContent(Vert) && m_lvItemLocator && m_lvItemLocator->IsFixHeight())
1378 {
1379 CRect rcPadding = GetStyle().GetPadding();
1380 psz->cy = m_lvItemLocator->GetTotalHeight() + rcPadding.top + rcPadding.bottom;
1381 if (nParentHei > 0 && psz->cy > nParentHei)
1382 psz->cy = nParentHei;
1383 }
1384}
1385
1387{
1388 if (!m_lvItemLocator->IsFixHeight() && m_adapter)
1389 {
1390 int *nWids = new int[m_pHeader->GetItemCount()];
1391 for (int i = 0; i < m_pHeader->GetItemCount(); i++)
1392 {
1393 SHDITEM hi = { SHDI_ORDER, 0 };
1394 m_pHeader->GetItem(i, &hi);
1395 nWids[hi.iOrder] = m_pHeader->GetItemWidth(i);
1396 }
1397 m_adapter->SetColumnsWidth(nWids, m_pHeader->GetItemCount());
1398 delete[] nWids;
1399 }
1400}
1401
1402SNSEND
@ WndState_Hover
Definition SWnd.h:76
@ WndState_Check
Definition SWnd.h:78
@ WndState_Normal
Definition SWnd.h:75
A helper class to enable or disable private UI definitions for the host container.
Definition SWnd.h:2663
Smart pointer class for managing COM-style reference-counted objects.
BOOL subscribeEvent(DWORD dwEventID, const IEvtSlot &subscriber)
订阅事件
Definition SEventSet.h:151
void setMutedState(BOOL setting)
设置事件集的静音状态
void RestoreFocusedView()
Restores the focused view.
void ClearFocus()
Clears the focused window.
void StoreFocusedView()
Stores the focused view.
Header Control.
Definition SHeaderCtrl.h:18
布局大小类
Definition SLayoutSize.h:10
固定高度的列表视图项定位器
可变高度的列表视图项定位器
int m_iPendingViewItem
void GetDesiredSize(SIZE *psz, int nParentWid, int nParentHei) OVERRIDE
Get the desired size of the control.
void UpdateVisibleItems()
Update visible items.
SHeaderCtrl * GetHeaderCtrl() const
Get the header control.
SList< ItemInfo > m_lstItems
BOOL OnItemClick(IEvtArgs *pEvt)
Handle item click event.
SArray< SList< SItemPanel * > * > m_itemRecycle
virtual void OnRebuildFont()
Handle rebuild font event.
virtual BOOL OnItemGetRect(const SOsrPanel *pItem, CRect &rcItem) const
Get the rectangle of an item.
IHeaderCtrl * GetIHeaderCtrl() SCONST OVERRIDE
Get the header control.
virtual BOOL CreateChildren(SXmlNode xmlNode)
Create child items from XML configuration.
SItemPanel * GetItemPanel(int iItem)
Get the item panel for a specific item.
void UpdateChildrenPosition() OVERRIDE
Update the position of child items.
virtual ~SMCListView()
Destructor.
void onDataSetChanged()
Handle data set changed event.
int GetSel() SCONST OVERRIDE
Get the selected item.
SXmlDoc m_xmlTemplate
SAutoRefPtr< IListViewItemLocator > m_lvItemLocator
void SetSel(int iItem, BOOL bNotify=FALSE) OVERRIDE
Set the selected item.
SOsrPanel * m_pHoverItem
CRect GetListRect()
Get the rectangle of the list.
int m_iFirstVisible
void OnShowWindow(BOOL bShow, UINT nStatus)
Handle show window event.
void OnKillFocus(SWND wndFocus)
Handle kill focus event.
LRESULT OnKeyEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handle key event.
int GetColumnCount() SCONST OVERRIDE
Get the total number of columns.
BOOL m_bDatasetInvalidated
void DispatchMessage2Items(UINT uMsg, WPARAM wParam, LPARAM lParam)
Dispatch messages to items.
void _UpdateAdapterColumnsWidth() const
Update the column widths in the adapter.
virtual HRESULT OnLanguageChanged()
Handle language change event.
virtual BOOL OnSetCursor(const CPoint &pt)
Handle set cursor event.
void UpdateHeaderCtrl()
Update the header control.
BOOL OnHeaderClick(IEvtArgs *pEvt)
Handle header click event.
SLayoutSize m_nHeaderHeight
virtual BOOL IsItemRedrawDelay() const
Check if item redraw is delayed.
int GetHeaderHeight() const
Get the height of the header.
BOOL SetAdapter(IMcAdapter *adapter) OVERRIDE
Set the adapter for the list view.
bool m_bPendingUpdate
void UpdateScrollBar()
Update the scroll bar.
SHeaderCtrl * m_pHeader
void UpdateVisibleItem(int iItem)
Update a specific visible item.
virtual int GetScrollLineSize(BOOL bVertical)
Get the scroll line size.
BOOL OnHeaderSizeChanging(IEvtArgs *pEvt)
Handle header size changing event.
virtual void OnItemSetCapture(SOsrPanel *pItem, BOOL bCapture)
Handle item capture.
void onDataSetInvalidated()
Handle data set invalidated event.
SAutoRefPtr< IMcAdapter > m_adapter
virtual UINT WINAPI OnGetDlgCode() const
Get the dialog code.
virtual void OnScaleChanged(int nScale)
Handle scale change event.
void OnSize(UINT nType, CSize size)
Handle size change event.
virtual void OnColorize(COLORREF cr)
Handle colorization event.
void RedrawItem(SOsrPanel *pItem)
Redraw a specific item.
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
Handle mouse wheel event.
void OnPaint(IRenderTarget *pRT)
Paint the control.
int InsertColumn(int nIndex, LPCTSTR pszText, int nWidth, UINT fmt, LPARAM lParam=0, BOOL bDpiAware=TRUE, float fWeight=0.0f) OVERRIDE
Insert a column.
COLORREF m_crGrid
SMCListView()
Constructor.
void DeleteColumn(int iCol) OVERRIDE
Delete a specific column.
CRect _OnItemGetRect(int iPosition) const
Get the rectangle of an item by position.
void OnSetFocus(SWND wndOld)
Handle set focus event.
void EnsureVisible(int iItem) OVERRIDE
Ensure an item is visible.
void SetItemLocator(IListViewItemLocator *pItemLocator) OVERRIDE
Set the item locator for the list view.
void OnMouseLeave()
Handle mouse leave event.
virtual BOOL OnScroll(BOOL bVertical, UINT uCode, int nPos)
Handle scroll event.
SAutoRefPtr< ISkinObj > m_pSkinDivider
void onItemDataChanged(int iItem)
Handle item data changed event.
int m_iPendingUpdateItem
virtual BOOL UpdateToolTip(CPoint pt, SwndToolTipInfo &tipInfo)
Update tooltip information.
IItemPanel * HitTest(const POINT *pt) SCONST OVERRIDE
Hit test to determine the item under the mouse.
BOOL OnHeaderSwap(IEvtArgs *pEvt)
Handle header swap event.
void OnDestroy()
Handle destroy event.
IMcAdapter * GetAdapter() SCONST OVERRIDE
Get the adapter for the list view.
IListViewItemLocator * GetItemLocator() SCONST OVERRIDE
Get the item locator for the list view.
SOsrPanel * m_itemCapture
SLayoutSize m_nDividerSize
LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handle mouse event.
SAutoRefPtr< ILvDataSetObserver > m_observer
void OnKeyDown(TCHAR nChar, UINT nRepCnt, UINT nFlags)
Handle key down event.
The SMatrix class holds a 3x3 matrix for transforming coordinates. SMatrix does not have a constructo...
Definition SMatrix.h:22
static LPCWSTR GetClassName()
Definition Sobject.hpp:41
Helper class for painting.
Definition SWnd.h:178
virtual CRect GetClientRect() const
Gets the client rectangle.
Definition SPanel.cpp:368
int GetSbWidth() const
Gets the width of the scrollbar.
Definition SPanel.cpp:650
void ScrollUpdate()
Updates the scrollbar.
Definition SPanel.cpp:579
A class representing an ASCII string.
Definition sstringw.h:96
Base class for SOUI DUI windows.
Definition SWnd.h:286
BOOL FireEvent(IEvtArgs *evt) OVERRIDE
Fires an event.
Definition Swnd.cpp:1540
void SetVisible(BOOL bVisible, BOOL bUpdate=FALSE) OVERRIDE
Sets the visibility of the window.
Definition Swnd.cpp:655
void UnlockUpdate() OVERRIDE
Unlocks updates to the window.
Definition Swnd.cpp:1497
SWindow * GetOwner() const
Retrieves the current owner of the window.
Definition Swnd.cpp:706
BOOL Destroy() OVERRIDE
Destroys the window.
Definition Swnd.cpp:504
DWORD GetState() SCONST OVERRIDE
Retrieves the current state of the window.
Definition Swnd.cpp:437
void SDispatchMessage(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0) OVERRIDE
Dispatches a message to the window.
Definition Swnd.cpp:388
int GetScale() SCONST OVERRIDE
Retrieves the scale factor of the window.
Definition Swnd.cpp:3266
BOOL IsMsgHandled() const
Checks if the message is handled.
Definition Swnd.cpp:207
COLORREF GetColorizeColor() SCONST OVERRIDE
Retrieves the colorization color of the window.
Definition Swnd.cpp:3166
BOOL IsVisible(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is visible.
Definition Swnd.cpp:646
ISwndContainer * GetContainer() OVERRIDE
Retrieves the container associated with this window.
Definition Swnd.cpp:679
void DoColorize(COLORREF cr) OVERRIDE
Applies colorization to the window.
Definition Swnd.cpp:3143
SWindow * FindChildByName(LPCWSTR strName, int nDeep=-1)
Finds a child window by its name.
Definition Swnd.cpp:795
virtual CRect GetClientRect() const
Retrieves the client rectangle of the window.
Definition Swnd.cpp:243
void InsertChild(SWindow *pNewChild, SWindow *pInsertAfter=NULL)
Inserts a child window into the window tree.
Definition Swnd.cpp:538
LRESULT SSendMessage(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0, BOOL *pbMsgHandled=NULL) OVERRIDE
Sends a message to the window.
Definition Swnd.cpp:364
virtual void BeforePaint(IRenderTarget *pRT, SPainter &painter)
Prepare rendering environment.
Definition Swnd.cpp:1755
void InvalidateRect(LPCRECT lprect) OVERRIDE
Invalidates a specific rectangle area of the window.
Definition Swnd.cpp:1444
void UpdateLayout() OVERRIDE
Updates the layout of the window.
Definition Swnd.cpp:2251
BOOL m_bFocusable
Definition SWnd.h:2609
virtual SWindow * CreateChildByName(LPCWSTR pszName)
Create child window by name.
Definition Swnd.cpp:935
virtual void AfterPaint(IRenderTarget *pRT, SPainter &painter)
Restore rendering environment.
Definition Swnd.cpp:1776
ILayoutParam * GetLayoutParam() SCONST OVERRIDE
Retrieves the layout parameter object associated with the window.
Definition SWnd.h:405
SEventSet * GetEventSet()
Retrieves the event set associated with the window.
Definition SWnd.h:1290
void Invalidate() OVERRIDE
Invalidates the entire window.
Definition Swnd.cpp:1437
void GetWindowRect(LPRECT prect) SCONST OVERRIDE
Retrieves the bounding rectangle of the window.
void SetMsgHandled(BOOL bHandled)
Sets the message handled flag.
Definition Swnd.cpp:212
SEventSet m_evtSet
Definition SWnd.h:2581
const SwndStyle & GetStyle() const
Retrieves the style of the window.
Definition Swnd.cpp:716
void LockUpdate() OVERRIDE
Locks updates to the window.
Definition Swnd.cpp:1492
SWND m_swnd
Member variables representing various properties of the window.
Definition SWnd.h:2577
void Move(LPCRECT prect) OVERRIDE
Moves the window to a new position and size.
Definition Swnd.cpp:399
BOOL m_bClipClient
Definition SWnd.h:2607
const wchar_t * as_string(const wchar_t *def=L"") const
Gets the attribute value as a string.
Definition SXml.cpp:95
const wchar_t * value() const
Gets the attribute value.
Definition SXml.cpp:90
Class representing an XML node.
Definition SXml.h:352
SXmlAttr attribute(const wchar_t *name, bool bCaseSensitive=false) const
Gets the attribute with the specified name.
Definition SXml.cpp:428
SXmlNode child(const wchar_t *name, bool bCaseSensitive=false) const
Gets the child node, attribute, or next/previous sibling with the specified name.
Definition SXml.cpp:423
BOOL set_userdata(int data) OVERRIDE
Sets user data for the node.
Definition SXml.cpp:270
SFocusManager * GetFocusManager()
Retrieves the focus manager.
CRect GetPadding() const
Retrieves the padding rectangle.
Template class implementing the IObjRef interface.
Base class for all renderable objects.
Definition SRender-i.h:145
Interface for rendering target objects.
Definition SRender-i.h:1440
HRESULT GetTransform(float matrix[9]) SCONST PURE
Retrieves the current coordinate transformation matrix.
HRESULT SelectObject(IRenderObj *pObj, IRenderObj **pOldObj=NULL) PURE
Selects a new rendering object and optionally retrieves the previous one.
HRESULT PushClipRect(LPCRECT pRect, UINT mode=RGN_AND) PURE
Push a rectangular clip region.
HRESULT CreatePen(int iStyle, COLORREF cr, int cWidth, IPenS **ppPen) PURE
Create a pen object.
HRESULT PopClip() PURE
Pop the last clip region from the stack.
HRESULT GetClipBox(LPRECT prc) PURE
Get the bounding box of the current clip region.
HRESULT GetClipRegion(IRegionS **ppRegion) PURE
Get the current clip region.
BOOL SetAntiAlias(BOOL bAntiAlias) PURE
Enables or disables anti-aliasing for drawing operations.
HRESULT DrawLines(LPPOINT pPt, size_t nCount) PURE
Draw a series of connected lines.
BOOL OnReleaseSwndCapture() PURE
Releases the mouse capture from the Swnd object.
SWND OnSetSwndCapture(SWND swnd) PURE
Sets the Swnd object to capture the mouse.
Information for window tooltips.
Definition SWnd.h:208