soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
STileView.cpp
1#include "souistd.h"
2#include "control/STileView.h"
3
4SNSBEGIN
5
6class STileViewDataSetObserver : public TObjRefImpl<ILvDataSetObserver> {
7 public:
8 STileViewDataSetObserver(STileView *pView)
9 : m_pOwner(pView)
10 {
11 }
12 STDMETHOD_(void, onChanged)(THIS) OVERRIDE;
13
14 STDMETHOD_(void, onInvalidated)(THIS) OVERRIDE;
15
16 STDMETHOD_(void, OnItemChanged)(THIS_ int iItem) OVERRIDE;
17
18 protected:
19 STileView *m_pOwner;
20};
21
22//////////////////////////////////////////////////////////////////////////
23void STileViewDataSetObserver::onChanged()
24{
25 m_pOwner->onDataSetChanged();
26}
27
28void STileViewDataSetObserver::onInvalidated()
29{
30 m_pOwner->onDataSetInvalidated();
31}
32
33void STileViewDataSetObserver::OnItemChanged(int iItem)
34{
35 m_pOwner->onItemDataChanged(iItem);
36}
37
38//////////////////////////////////////////////////////////////////////////
40 : m_iSelItem(-1)
41 , m_iFirstVisible(-1)
42 , m_pHoverItem(NULL)
43 , m_itemCapture(NULL)
44 , m_nMarginSize(0.0f, SLayoutSize::px)
45 , m_bWantTab(FALSE)
47 , m_bPendingUpdate(false)
50 , SHostProxy(this)
51
52{
53 m_bFocusable = TRUE;
54 m_observer.Attach(new STileViewDataSetObserver(this));
55 m_dwUpdateInterval = 40;
56 m_evtSet.addEvent(EVENTID(EventLVSelChanging));
57 m_evtSet.addEvent(EVENTID(EventLVSelChanged));
58}
59
61{
62 m_observer = NULL;
63 m_tvItemLocator = NULL;
64}
65
66BOOL STileView::SetAdapter(ILvAdapter *adapter)
67{
68 if (!m_tvItemLocator)
69 {
70 SASSERT_MSGA(FALSE, "error: A item locator is in need before setting adapter!!!");
71 return FALSE;
72 }
73 if (m_adapter == adapter)
74 {
75 SSLOGW() << "the new adapter is same to previous set adapter, same as notifyDatasetChanged";
76 if (m_adapter)
77 {
79 }
80 return TRUE;
81 }
82 if (m_adapter)
83 {
84 m_adapter->unregisterDataSetObserver(m_observer);
85 }
86 {
87 // free all itemPanels in recycle
88 for (size_t i = 0; i < m_itemRecycle.GetCount(); i++)
89 {
90 SList<SItemPanel *> *lstItemPanels = m_itemRecycle.GetAt(i);
91 SPOSITION pos = lstItemPanels->GetHeadPosition();
92 while (pos)
93 {
94 SItemPanel *pItemPanel = lstItemPanels->GetNext(pos);
95 pItemPanel->Destroy();
96 }
97 delete lstItemPanels;
98 }
99 m_itemRecycle.RemoveAll();
100
101 // free all visible itemPanels
102 SPOSITION pos = m_lstItems.GetHeadPosition();
103 while (pos)
104 {
105 ItemInfo ii = m_lstItems.GetNext(pos);
106 ii.pItem->Destroy();
107 }
108 m_lstItems.RemoveAll();
109 m_pHoverItem = NULL;
110 m_itemCapture = NULL;
111 m_iSelItem = -1;
112 m_iFirstVisible = -1;
113 }
114
115 m_adapter = adapter;
116 if (m_tvItemLocator)
117 {
118 m_tvItemLocator->SetTileViewWidth(GetClientRect().Width(), FALSE);
119 m_tvItemLocator->SetAdapter(adapter);
120 }
121 if (m_adapter)
122 {
123 SXmlNode xmlNode = m_xmlTemplate.root().first_child();
124 m_adapter->InitByTemplate(&xmlNode);
125 m_adapter->registerDataSetObserver(m_observer);
126 for (int i = 0; i < m_adapter->getViewTypeCount(); i++)
127 {
128 m_itemRecycle.Add(new SList<SItemPanel *>());
129 }
131 }
132 return TRUE;
133}
134
136{
137 CRect rcClient = SWindow::GetClientRect();
138 CSize size = rcClient.Size();
139 CSize szView;
140 szView.cx = rcClient.Width();
141 szView.cy = m_tvItemLocator ? m_tvItemLocator->GetTotalHeight() : 0;
142
143 // 关闭滚动条
144 m_wBarVisible = SSB_NULL;
145
146 if (size.cy < szView.cy)
147 {
148 // 需要纵向滚动条
149 m_wBarVisible |= SSB_VERT;
150 m_siVer.nMin = 0;
151 m_siVer.nMax = szView.cy - 1;
152 m_siVer.nPage = size.cy;
153 m_siVer.nPos = smin(m_siVer.nPos, m_siVer.nMax - (int)m_siVer.nPage);
154 }
155 else
156 {
157 // 不需要纵向滚动条
158 m_siVer.nPage = size.cy;
159 m_siVer.nMin = 0;
160 m_siVer.nMax = size.cy - 1;
161 m_siVer.nPos = 0;
162 }
163
164 SetScrollPos(TRUE, m_siVer.nPos, FALSE);
165
166 // 重新计算客户区及非客户区
167 SSendMessage(WM_NCCALCSIZE);
168
169 InvalidateRect(NULL);
170}
171
173{
174 if (!m_adapter)
175 {
176 return;
177 }
178 if (m_tvItemLocator)
179 {
180 m_tvItemLocator->OnDataSetChanged();
181 }
182 if (m_iSelItem != -1 && m_iSelItem >= m_adapter->getCount())
183 m_iSelItem = -1;
184
187}
188
194
196{
197 SAutoEnableHostPrivUiDef enableUiDef(this);
198 SItemPanel *pItem = GetItemPanel(iItem);
199 SASSERT(pItem);
200 SXmlNode xmlNode = m_xmlTemplate.root().first_child();
201 m_adapter->getView(iItem, pItem, &xmlNode);
202 pItem->Invalidate();
203}
204
206{
207 if (!m_adapter)
208 return;
209 if (!IsVisible(TRUE))
210 {
211 m_bPendingUpdate = true;
212 m_iPendingUpdateItem = m_iPendingUpdateItem == -2 ? iItem : -1;
213 return;
214 }
215 if (iItem < m_iFirstVisible)
216 return;
217 if (iItem >= m_iFirstVisible + (int)m_lstItems.GetCount())
218 return;
219 UpdateVisibleItem(iItem);
220}
221
223{
225 {
227 m_bDatasetInvalidated = FALSE;
228 }
229 SPainter duiDC;
230 BeforePaint(pRT, duiDC);
231
232 int iFirst = m_iFirstVisible;
233 if (iFirst != -1)
234 {
235 CRect rcClient;
236 GetClientRect(&rcClient);
237 pRT->PushClipRect(&rcClient, RGN_AND);
238
239 float fMat[9];
240 pRT->GetTransform(fMat);
241 SMatrix mtx(fMat);
242
243 CRect rcClip;
244 pRT->GetClipBox(&rcClip);
245 SAutoRefPtr<IRegionS> rgnClip;
246 pRT->GetClipRegion(&rgnClip);
247
248 int nOffset = m_tvItemLocator->Item2Position(iFirst) - m_siVer.nPos;
249 int nLastBottom = rcClient.top + m_tvItemLocator->GetMarginSize() + nOffset;
250
251 SPOSITION pos = m_lstItems.GetHeadPosition();
252 int i = 0;
253 for (; pos; i++)
254 {
255 ItemInfo ii = m_lstItems.GetNext(pos);
256 CRect rcItem = m_tvItemLocator->GetItemRect(iFirst + i);
257 rcItem.OffsetRect(rcClient.left, 0);
258 rcItem.MoveToY(nLastBottom);
259 if (m_tvItemLocator->IsLastInRow(iFirst + i))
260 {
261 nLastBottom = rcItem.bottom + m_tvItemLocator->GetMarginSize();
262 }
263 if (SItemPanel::IsItemInClip(mtx, rcClip, rgnClip, rcItem))
264 {
265 ii.pItem->Draw(pRT, rcItem);
266 }
267 }
268
269 pRT->PopClip();
270 }
271 AfterPaint(pRT, duiDC);
272}
273
274BOOL STileView::OnScroll(BOOL bVertical, UINT uCode, int nPos)
275{
276 int nOldPos = m_siVer.nPos;
277 __baseCls::OnScroll(bVertical, uCode, nPos);
278 int nNewPos = m_siVer.nPos;
279 if (nOldPos != nNewPos)
280 {
282
283 //加速滚动时UI的刷新
284 if (uCode == SB_THUMBTRACK)
285 {
286 ScrollUpdate();
287 }
288 return TRUE;
289 }
290 return FALSE;
291}
292
294{
295 if (!m_adapter)
296 {
297 return;
298 }
299 SAutoEnableHostPrivUiDef enableUiDef(this);
300 int iOldFirstVisible = m_iFirstVisible;
301 int iOldLastVisible = m_iFirstVisible + (int)m_lstItems.GetCount();
302
303 int iNewFirstVisible = m_tvItemLocator->Position2Item(m_siVer.nPos);
304 int iNewLastVisible = iNewFirstVisible;
305
306 int pos = m_tvItemLocator->Item2Position(iNewFirstVisible);
307 int iHoverItem = m_pHoverItem ? (int)m_pHoverItem->GetItemIndex() : -1;
308
309 ItemInfo *pItemInfos = new ItemInfo[m_lstItems.GetCount()];
310 SPOSITION spos = m_lstItems.GetHeadPosition();
311 int i = 0;
312 while (spos)
313 {
314 pItemInfos[i++] = m_lstItems.GetNext(spos);
315 }
316
317 m_lstItems.RemoveAll();
318
319 if (iNewFirstVisible != -1)
320 {
321 while (pos < m_siVer.nPos + (int)m_siVer.nPage && iNewLastVisible < m_adapter->getCount())
322 {
323 DWORD dwState = WndState_Normal;
324 if (iHoverItem == iNewLastVisible)
325 dwState |= WndState_Hover;
326 if (m_iSelItem == iNewLastVisible)
327 dwState |= WndState_Check;
328
329 ItemInfo ii = { NULL, -1 };
330 ii.nType = m_adapter->getItemViewType(iNewLastVisible, dwState);
331 if (iNewLastVisible >= iOldFirstVisible && iNewLastVisible < iOldLastVisible)
332 {
333 // use the old visible item
334 int iItem = iNewLastVisible - iOldFirstVisible;
335 SASSERT(iItem >= 0 && iItem <= (iOldLastVisible - iOldFirstVisible));
336 if (ii.nType == pItemInfos[iItem].nType)
337 {
338 ii = pItemInfos[iItem];
339 pItemInfos[iItem].pItem = NULL; //标记该行已经被重用
340 }
341 }
342 BOOL bNewItem = FALSE;
343 if (!ii.pItem)
344 {
345 // create new visible item
346 SList<SItemPanel *> *lstRecycle = m_itemRecycle.GetAt(ii.nType);
347 if (lstRecycle->IsEmpty())
348 {
349 //创建一个新的列表项
350 bNewItem = TRUE;
351 ii.pItem = SItemPanel::Create(this, SXmlNode(), this);
352 ii.pItem->GetEventSet()->subscribeEvent(EventItemPanelClick::EventID, Subscriber(&STileView::OnItemClick, this));
353 }
354 else
355 {
356 ii.pItem = lstRecycle->RemoveHead();
357 }
358 ii.pItem->SetItemIndex(iNewLastVisible);
359 }
360 ii.pItem->SetVisible(TRUE);
361 CRect rcItem = m_tvItemLocator->GetItemRect(iNewLastVisible);
362 rcItem.MoveToXY(0, 0);
363 ii.pItem->Move(rcItem);
364
365 //设置状态,同时暂时禁止应用响应statechanged事件。
366 ii.pItem->GetEventSet()->setMutedState(true);
367 ii.pItem->ModifyItemState(dwState, 0);
368 ii.pItem->GetEventSet()->setMutedState(false);
369 if (dwState & WndState_Hover)
370 m_pHoverItem = ii.pItem;
371
372 SXmlNode xmlNode = m_xmlTemplate.root().first_child();
373 ii.pItem->LockUpdate();
374 m_adapter->getView(iNewLastVisible, ii.pItem, &xmlNode);
375 ii.pItem->UnlockUpdate();
376 if (bNewItem)
377 {
378 ii.pItem->SDispatchMessage(UM_SETSCALE, GetScale(), 0);
379 ii.pItem->SDispatchMessage(UM_SETLANGUAGE, 0, 0);
381 }
382
383 ii.pItem->UpdateLayout();
384 if (iNewLastVisible == m_iSelItem)
385 {
386 ii.pItem->ModifyItemState(WndState_Check, 0);
387 }
388
389 m_lstItems.AddTail(ii);
390
391 if (m_tvItemLocator->IsLastInRow(iNewLastVisible))
392 {
393 pos += rcItem.Height() + m_tvItemLocator->GetMarginSize();
394 }
395
396 iNewLastVisible++;
397 }
398 }
399
400 // move old visible items which were not reused to recycle
401 for (int i = 0; i < (iOldLastVisible - iOldFirstVisible); i++)
402 {
403 ItemInfo ii = pItemInfos[i];
404 if (!ii.pItem)
405 {
406 continue;
407 }
408 if (ii.pItem->GetState() & WndState_Hover)
409 {
410 ii.pItem->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
411 m_pHoverItem = NULL;
412 }
413 ii.pItem->GetEventSet()->setMutedState(true);
414 if (ii.pItem->GetState() & WndState_Check)
415 {
416 ii.pItem->ModifyItemState(0, WndState_Check);
418 }
419 ii.pItem->SetVisible(FALSE);
420 ii.pItem->GetEventSet()->setMutedState(false);
421 m_itemRecycle[ii.nType]->AddTail(ii.pItem);
422 }
423 delete[] pItemInfos;
424
425 m_iFirstVisible = iNewFirstVisible;
426 InvalidateRect(NULL);
427}
428
429void STileView::OnSize(UINT nType, CSize size)
430{
431 __baseCls::OnSize(nType, size);
432
433 CRect rcClient = SWindow::GetClientRect();
434 m_tvItemLocator->SetTileViewWidth(rcClient.Width(), FALSE); //重设TileView宽度
435 UpdateScrollBar(); //重设滚动条
436
438}
439
441{
442 if (m_adapter)
443 {
444 m_adapter->unregisterDataSetObserver(m_observer);
445 }
446
447 // destroy all itempanel
448 SPOSITION pos = m_lstItems.GetHeadPosition();
449 while (pos)
450 {
451 ItemInfo ii = m_lstItems.GetNext(pos);
452 ii.pItem->Release();
453 }
454 m_lstItems.RemoveAll();
455
456 for (int i = 0; i < (int)m_itemRecycle.GetCount(); i++)
457 {
458 SList<SItemPanel *> *pLstTypeItems = m_itemRecycle[i];
459 SPOSITION pos = pLstTypeItems->GetHeadPosition();
460 while (pos)
461 {
462 SItemPanel *pItem = pLstTypeItems->GetNext(pos);
463 pItem->Release();
464 }
465 delete pLstTypeItems;
466 }
467 m_itemRecycle.RemoveAll();
468 __baseCls::OnDestroy();
469}
470
471//////////////////////////////////////////////////////////////////////////
472
474{
475 return TRUE;
476}
477
478CRect STileView::CalcItemDrawRect(int iItem) const
479{
480 //相对整个窗体的实际绘制位置
481 int nOffset = m_tvItemLocator->Item2Position(iItem) - m_siVer.nPos;
482
483 CRect rcClient = GetClientRect();
484 //获取left/right
485 CRect rcItem = m_tvItemLocator->GetItemRect(iItem);
486 rcItem.OffsetRect(rcClient.TopLeft());
487 //修正top/bottom
488 rcItem.MoveToY(rcClient.top + m_tvItemLocator->GetMarginSize() + nOffset);
489 return rcItem;
490}
491
492BOOL STileView::OnItemGetRect(const SOsrPanel *pItem, CRect &rcItem) const
493{
494 int iPosition = (int)pItem->GetItemIndex();
495 if (iPosition < 0 || iPosition >= m_adapter->getCount())
496 return FALSE;
497 rcItem = CalcItemDrawRect(iPosition);
498 return TRUE;
499}
500
501void STileView::OnItemSetCapture(SOsrPanel *pItem, BOOL bCapture)
502{
503 if (bCapture)
504 {
506 m_itemCapture = pItem;
507 }
508 else
509 {
511 m_itemCapture = NULL;
512 }
513}
514
515void STileView::RedrawItem(SOsrPanel *pItem)
516{
517 pItem->InvalidateRect(NULL);
518}
519
520SItemPanel *STileView::HitTest(CPoint &pt) const
521{
522 SPOSITION pos = m_lstItems.GetHeadPosition();
523 while (pos)
524 {
525 ItemInfo ii = m_lstItems.GetNext(pos);
526 CRect rcItem = ii.pItem->GetItemRect();
527 if (rcItem.PtInRect(pt))
528 {
529 pt -= rcItem.TopLeft();
530 return ii.pItem;
531 }
532 }
533 return NULL;
534}
535
536IItemPanel *STileView::HitTest(const POINT *pt) const
537{
538 SASSERT(pt);
539 if (!pt)
540 return NULL;
541 CPoint pt2(*pt);
542 return HitTest(pt2);
543}
544
545LRESULT STileView::OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
546{
547 SetMsgHandled(FALSE);
548 if (!m_adapter)
549 {
550 return 0;
551 }
552
553 LRESULT lRet = 0;
554 CPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
555
556 if (m_itemCapture)
557 {
558 CRect rcItem = m_itemCapture->GetItemRect();
559 pt.Offset(-rcItem.TopLeft());
560 lRet = m_itemCapture->DoFrameEvent(uMsg, wParam, MAKELPARAM(pt.x, pt.y));
561 }
562 else
563 {
564 if (uMsg == WM_LBUTTONDOWN || uMsg == WM_RBUTTONDOWN || uMsg == WM_MBUTTONDOWN)
565 { //交给panel处理
566 __baseCls::ProcessSwndMessage(uMsg, wParam, lParam, lRet);
567 }
568
569 SItemPanel *pHover = HitTest(pt);
570 if (pHover != m_pHoverItem)
571 {
572 SOsrPanel *nOldHover = m_pHoverItem;
573 m_pHoverItem = pHover;
574 if (nOldHover)
575 {
576 nOldHover->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
577 RedrawItem(nOldHover);
578 }
579 if (m_pHoverItem)
580 {
581 m_pHoverItem->DoFrameEvent(WM_MOUSEHOVER, wParam, MAKELPARAM(pt.x, pt.y));
583 }
584 }
585 if (m_pHoverItem)
586 {
587 m_pHoverItem->DoFrameEvent(uMsg, wParam, MAKELPARAM(pt.x, pt.y));
588 }
589 }
590
591 if (uMsg == WM_LBUTTONUP || uMsg == WM_RBUTTONUP || uMsg == WM_MBUTTONUP)
592 { //交给panel处理
593 __baseCls::ProcessSwndMessage(uMsg, wParam, lParam, lRet);
594 }
595 SetMsgHandled(TRUE);
596
597 return 0;
598}
599
600LRESULT STileView::OnKeyEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
601{
602 LRESULT lRet = 0;
603 SItemPanel *pItem = GetItemPanel(m_iSelItem);
604 if (pItem)
605 {
606 lRet = pItem->DoFrameEvent(uMsg, wParam, lParam);
607 SetMsgHandled(pItem->IsMsgHandled());
608 }
609 else
610 {
611 SetMsgHandled(FALSE);
612 }
613 return lRet;
614}
615
617{
618 __baseCls::OnMouseLeave();
619
620 if (m_pHoverItem)
621 {
622 m_pHoverItem->DoFrameEvent(WM_MOUSELEAVE, 0, 0);
623 m_pHoverItem = NULL;
624 }
625}
626
627void STileView::OnKeyDown(TCHAR nChar, UINT nRepCnt, UINT nFlags)
628{
629 if (!m_adapter)
630 {
631 SetMsgHandled(FALSE);
632 return;
633 }
634
635 if (m_iSelItem != -1 && m_bWantTab)
636 {
637 SItemPanel *pItem = GetItemPanel(m_iSelItem);
638 if (pItem)
639 {
640 pItem->DoFrameEvent(WM_KEYDOWN, nChar, MAKELONG(nFlags, nRepCnt));
641 if (pItem->IsMsgHandled())
642 {
643 return;
644 }
645 }
646 }
647
648 int nNewSelItem = -1;
649 SWindow *pOwner = GetOwner();
650 if (pOwner && (nChar == VK_ESCAPE || nChar == VK_RETURN))
651 {
652 pOwner->SSendMessage(WM_KEYDOWN, nChar, MAKELONG(nFlags, nRepCnt));
653 return;
654 }
655
656 if (nChar == VK_RIGHT && m_iSelItem < m_adapter->getCount() - 1)
657 {
658 nNewSelItem = m_iSelItem + 1;
659 }
660 else if (nChar == VK_LEFT && m_iSelItem > 0)
661 {
662 nNewSelItem = m_iSelItem - 1;
663 }
664 else if (nChar == VK_UP && m_iSelItem > 0)
665 {
666 nNewSelItem = m_tvItemLocator->GetUpItem(m_iSelItem);
667 }
668 else if (nChar == VK_DOWN && m_iSelItem < m_adapter->getCount() - 1)
669 {
670 nNewSelItem = m_tvItemLocator->GetDownItem(m_iSelItem);
671 }
672 else
673 {
674 switch (nChar)
675 {
676 case VK_PRIOR:
677 OnScroll(TRUE, SB_PAGEUP, 0);
678 break;
679 case VK_NEXT:
680 OnScroll(TRUE, SB_PAGEDOWN, 0);
681 break;
682 case VK_HOME:
683 OnScroll(TRUE, SB_TOP, 0);
684 break;
685 case VK_END:
686 OnScroll(TRUE, SB_BOTTOM, 0);
687 break;
688 }
689 if (nChar == VK_PRIOR || nChar == VK_HOME)
690 {
691 if (!m_lstItems.IsEmpty())
692 {
693 nNewSelItem = (int)(m_lstItems.GetHead().pItem->GetItemIndex());
694 }
695 }
696 else if (nChar == VK_NEXT || nChar == VK_END)
697 {
698 if (!m_lstItems.IsEmpty())
699 {
700 nNewSelItem = (int)(m_lstItems.GetTail().pItem->GetItemIndex());
701 }
702 }
703 }
704
705 if (nNewSelItem != -1)
706 {
707 EnsureVisible(nNewSelItem);
708 SetSel(nNewSelItem, TRUE);
709 }
710 else
711 {
712 SetMsgHandled(FALSE);
713 }
714}
715
717{
718 if (iItem < 0 || iItem >= m_adapter->getCount())
719 {
720 return;
721 }
722 if (!IsVisible(TRUE))
723 {
724 m_iPendingViewItem = iItem;
725 return;
726 }
727
728 CRect rcItem = m_tvItemLocator->GetItemRect(iItem);
729 if (rcItem.top < m_siVer.nPos)
730 {
731 // scroll up
732 OnScroll(TRUE, SB_THUMBPOSITION, rcItem.top);
733 }
734 if (rcItem.bottom > m_siVer.nPos + (int)m_siVer.nPage)
735 {
736 // scroll down
737 OnScroll(TRUE, SB_THUMBPOSITION, rcItem.bottom - m_siVer.nPage);
738 }
739}
740
741BOOL STileView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
742{
743 SItemPanel *pSelItem = GetItemPanel(m_iSelItem);
744 if (pSelItem)
745 {
746 CRect rcItem = pSelItem->GetItemRect();
747 CPoint pt2 = pt - rcItem.TopLeft();
748 if (pSelItem->DoFrameEvent(WM_MOUSEWHEEL, MAKEWPARAM(nFlags, zDelta), MAKELPARAM(pt2.x, pt2.y)))
749 {
750 return TRUE;
751 }
752 }
753 return __baseCls::OnMouseWheel(nFlags, zDelta, pt);
754}
755
757{
758 return m_tvItemLocator->GetScrollLineSize();
759}
760
761SItemPanel *STileView::GetItemPanel(int iItem)
762{
763 if (!m_adapter || iItem < 0 || iItem >= m_adapter->getCount())
764 {
765 return NULL;
766 }
767 SPOSITION pos = m_lstItems.GetHeadPosition();
768 while (pos)
769 {
770 ItemInfo ii = m_lstItems.GetNext(pos);
771 if ((int)ii.pItem->GetItemIndex() == iItem)
772 {
773 return ii.pItem;
774 }
775 }
776 return NULL;
777}
778
780{
781 SXmlNode xmlTemplate = xmlNode.child(L"template");
782 if (xmlTemplate)
783 {
784 m_xmlTemplate.root().append_copy(xmlTemplate);
785 {
786 //创建一个定位器
787 STileViewItemLocator *pItemLocator = new STileViewItemLocator(this, xmlTemplate.attribute(L"itemHeight").as_string(L"10dp"), xmlTemplate.attribute(L"itemWidth").as_string(L"10dp"), m_nMarginSize);
788 SetItemLocator(pItemLocator);
789 pItemLocator->Release();
790 }
791 }
792 return TRUE;
793}
794
795void STileView::SetItemLocator(ITileViewItemLocator *pItemLocator)
796{
797 m_tvItemLocator = pItemLocator;
798 if (m_tvItemLocator)
799 {
800 m_tvItemLocator->SetAdapter(GetAdapter());
801 m_tvItemLocator->SetScale(GetScale());
802 }
804}
805
807{
808 if (!m_pHoverItem)
809 {
810 return __baseCls::UpdateToolTip(pt, tipInfo);
811 }
812 return m_pHoverItem->UpdateToolTip(pt, tipInfo);
813}
814
815void STileView::SetSel(int iItem, BOOL bNotify)
816{
817 if (!m_adapter)
818 {
819 return;
820 }
821
822 if (iItem >= m_adapter->getCount())
823 {
824 return;
825 }
826
827 if (iItem < 0)
828 {
829 iItem = -1;
830 }
831
832 int nOldSel = m_iSelItem;
833 int nNewSel = iItem;
834
835 m_iSelItem = nNewSel;
836 if (bNotify)
837 {
838 EventLVSelChanging evt(this);
839 evt.bCancel = FALSE;
840 evt.iOldSel = nOldSel;
841 evt.iNewSel = nNewSel;
842 FireEvent(evt);
843 if (evt.bCancel)
844 {
845 // Cancel SetSel and restore selection state
846 m_iSelItem = nOldSel;
847 return;
848 }
849 }
850
851 if (nOldSel == nNewSel)
852 {
853 return;
854 }
855
856 m_iSelItem = nOldSel;
857 SItemPanel *pItem = GetItemPanel(nOldSel);
858 if (pItem)
859 {
860 pItem->GetFocusManager()->ClearFocus();
861 pItem->ModifyItemState(0, WndState_Check);
862 RedrawItem(pItem);
863 }
864 m_iSelItem = nNewSel;
865 pItem = GetItemPanel(nNewSel);
866 if (pItem)
867 {
868 pItem->ModifyItemState(WndState_Check, 0);
869 RedrawItem(pItem);
870 }
871
872 if (bNotify)
873 {
874 EventLVSelChanged evt(this);
875 evt.iOldSel = nOldSel;
876 evt.iNewSel = nNewSel;
877 FireEvent(evt);
878 }
879}
880
882{
883 if (m_bWantTab)
884 {
885 return SC_WANTALLKEYS;
886 }
887 else
888 {
889 return SC_WANTARROWS | SC_WANTSYSKEY;
890 }
891}
892
893void STileView::OnKillFocus(SWND wndFocus)
894{
895 __baseCls::OnKillFocus(wndFocus);
896
897 if (m_iSelItem == -1)
898 {
899 return;
900 }
901
902 SItemPanel *pSelPanel = GetItemPanel(m_iSelItem);
903 if (pSelPanel)
904 {
905 pSelPanel->GetFocusManager()->StoreFocusedView();
906 }
907}
908
909void STileView::OnSetFocus(SWND wndOld)
910{
911 __baseCls::OnSetFocus(wndOld);
912 if (m_iSelItem == -1)
913 {
914 return;
915 }
916
917 SItemPanel *pSelPanel = GetItemPanel(m_iSelItem);
918 if (pSelPanel)
919 {
920 pSelPanel->GetFocusManager()->RestoreFocusedView();
921 }
922}
923
924LRESULT STileView::OnSetScale(UINT uMsg, WPARAM wParam, LPARAM lParam)
925{
926 int nScale = (int)wParam;
927 m_tvItemLocator->SetScale(nScale);
928 __baseCls::OnSetScale(uMsg, wParam, lParam);
929 return LRESULT();
930}
931
932BOOL STileView::OnSetCursor(const CPoint &pt)
933{
934 BOOL bRet = FALSE;
935 if (m_itemCapture)
936 {
937 CRect rcItem = m_itemCapture->GetItemRect();
938 bRet = m_itemCapture->DoFrameEvent(WM_SETCURSOR, 0, MAKELPARAM(pt.x - rcItem.left, pt.y - rcItem.top)) != 0;
939 }
940 else if (m_pHoverItem)
941 {
942 CRect rcItem = m_pHoverItem->GetItemRect();
943 bRet = m_pHoverItem->DoFrameEvent(WM_SETCURSOR, 0, MAKELPARAM(pt.x - rcItem.left, pt.y - rcItem.top)) != 0;
944 }
945 if (!bRet)
946 {
947 bRet = __baseCls::OnSetCursor(pt);
948 }
949 return bRet;
950}
951
952BOOL STileView::OnItemClick(IEvtArgs *pEvt)
953{
954 SItemPanel *pItemPanel = sobj_cast<SItemPanel>(pEvt->Sender());
955 int iItem = (int)pItemPanel->GetItemIndex();
956 if (iItem != m_iSelItem)
957 {
958 SetSel(iItem, TRUE);
959 }
960 return true;
961}
962
963void STileView::OnColorize(COLORREF cr)
964{
965 __baseCls::OnColorize(cr);
966 DispatchMessage2Items(UM_SETCOLORIZE, cr, 0);
967}
968
970{
971 __baseCls::OnScaleChanged(nScale);
972 if (m_tvItemLocator)
973 m_tvItemLocator->SetScale(nScale);
974 DispatchMessage2Items(UM_SETSCALE, nScale, 0);
976}
977
979{
980 HRESULT hret = __baseCls::OnLanguageChanged();
981 DispatchMessage2Items(UM_SETLANGUAGE, 0, 0);
982 return hret;
983}
984
985void STileView::DispatchMessage2Items(UINT uMsg, WPARAM wParam, LPARAM lParam)
986{
987 SPOSITION pos = m_lstItems.GetHeadPosition();
988 while (pos)
989 {
990 ItemInfo ii = m_lstItems.GetNext(pos);
991 ii.pItem->SDispatchMessage(uMsg, wParam, lParam);
992 }
993 for (UINT i = 0; i < m_itemRecycle.GetCount(); i++)
994 {
995 SList<SItemPanel *> *pLstTypeItems = m_itemRecycle[i];
996 SPOSITION pos = pLstTypeItems->GetHeadPosition();
997 while (pos)
998 {
999 SItemPanel *pItem = pLstTypeItems->GetNext(pos);
1000 pItem->SDispatchMessage(uMsg, wParam, lParam);
1001 }
1002 }
1003}
1004
1005void STileView::OnShowWindow(BOOL bShow, UINT nStatus)
1006{
1007 __baseCls::OnShowWindow(bShow, nStatus);
1008 if (IsVisible(TRUE))
1009 {
1010 if (m_bPendingUpdate)
1011 {
1012 if (m_iPendingUpdateItem == -1)
1014 else
1016 m_bPendingUpdate = false;
1018 }
1019 if (m_iPendingViewItem != -1)
1020 {
1022 m_iPendingViewItem = -1;
1023 }
1024 }
1025}
1026
1028{
1029 __baseCls::OnRebuildFont();
1030 DispatchMessage2Items(UM_UPDATEFONT, 0, 0);
1031}
1032
1033ILvAdapter *STileView::GetAdapter() const
1034{
1035 return m_adapter;
1036}
1037
1038ITileViewItemLocator *STileView::GetItemLocator() const
1039{
1040 return m_tvItemLocator;
1041}
1042
1044{
1045 return m_iSelItem;
1046}
1047
1048SNSEND
Definition of the STileView class.
@ 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.
布局大小类
Definition SLayoutSize.h:10
The SMatrix class holds a 3x3 matrix for transforming coordinates. SMatrix does not have a constructo...
Definition SMatrix.h:22
Helper class for painting.
Definition SWnd.h:178
virtual CRect GetClientRect() const
Gets the client rectangle.
Definition SPanel.cpp:368
void ScrollUpdate()
Updates the scrollbar.
Definition SPanel.cpp:579
SAutoRefPtr< ILvDataSetObserver > m_observer
Definition STileView.h:380
virtual void OnColorize(COLORREF cr)
Handles colorization.
void OnKeyDown(TCHAR nChar, UINT nRepCnt, UINT nFlags)
Handles the key down event.
SXmlDoc m_xmlTemplate
Definition STileView.h:407
virtual void OnRebuildFont()
Rebuilds the font.
BOOL m_bDatasetInvalidated
Definition STileView.h:410
void UpdateScrollBar()
Updates the scroll bars.
virtual HRESULT OnLanguageChanged()
Handles language changes.
void onDataSetInvalidated()
Handles data set invalidation.
void OnPaint(IRenderTarget *pRT)
Handles the paint event.
virtual BOOL IsItemRedrawDelay() const
Checks if item redraw is delayed.
BOOL m_bWantTab
Definition STileView.h:409
SAutoRefPtr< ILvAdapter > m_adapter
Definition STileView.h:379
int m_iSelItem
Definition STileView.h:402
ILvAdapter * GetAdapter() SCONST OVERRIDE
Gets the adapter for the tile view.
SItemPanel * GetItemPanel(int iItem)
Gets the item panel by index.
void UpdateVisibleItems()
Updates the visible items.
SOsrPanel * m_pHoverItem
Definition STileView.h:403
void EnsureVisible(int iItem) OVERRIDE
Ensures the specified item is visible.
LRESULT OnSetScale(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handles the set scale event.
IItemPanel * HitTest(const POINT *pt) SCONST OVERRIDE
Performs a hit test on the tile view.
void OnSize(UINT nType, CSize size)
Handles the size event.
void SetSel(int iItem, BOOL bNotify=FALSE) OVERRIDE
Sets the selected item.
void SetItemLocator(ITileViewItemLocator *pItemLocator) OVERRIDE
Sets the item locator for the tile view.
virtual int GetScrollLineSize(BOOL bVertical)
Gets the scroll line size.
int m_iPendingUpdateItem
Definition STileView.h:394
void OnMouseLeave()
Handles the mouse leave event.
virtual BOOL CreateChildren(SXmlNode xmlNode)
Creates child windows from an XML node.
~STileView()
Destructor for STileView.
Definition STileView.cpp:60
virtual UINT WINAPI OnGetDlgCode() const
Gets the dialog code for the window.
void UpdateVisibleItem(int iItem)
Updates a specific visible item.
void OnDestroy()
Handles the destroy event.
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
Handles the mouse wheel event.
void onDataSetChanged()
Handles data set changes.
SOsrPanel * m_itemCapture
Definition STileView.h:400
virtual BOOL OnSetCursor(const CPoint &pt)
Sets the cursor.
int GetSel() SCONST OVERRIDE
Gets the selected item.
void onItemDataChanged(int iItem)
Handles data changes for a specific item.
ITileViewItemLocator * GetItemLocator() SCONST OVERRIDE
Gets the item locator for the tile view.
void OnShowWindow(BOOL bShow, UINT nStatus)
Handles the show window event.
CRect CalcItemDrawRect(int iItem) const
Calculates the drawing rectangle for an item.
void OnSetFocus(SWND wndOld)
Handles the set focus event.
LRESULT OnKeyEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handles key events.
SAutoRefPtr< ITileViewItemLocator > m_tvItemLocator
Definition STileView.h:381
STileView()
Constructor for STileView.
Definition STileView.cpp:39
BOOL OnItemClick(IEvtArgs *pEvt)
Handles item click events.
void OnKillFocus(SWND wndFocus)
Handles the kill focus event.
BOOL SetAdapter(ILvAdapter *adapter) OVERRIDE
Sets the adapter for the tile view.
Definition STileView.cpp:66
bool m_bPendingUpdate
Definition STileView.h:393
virtual void OnScaleChanged(int nScale)
Handles scale changes.
virtual BOOL OnScroll(BOOL bVertical, UINT uCode, int nPos)
Handles scroll events.
int m_iFirstVisible
Definition STileView.h:397
SLayoutSize m_nMarginSize
Definition STileView.h:408
virtual BOOL UpdateToolTip(CPoint pt, SwndToolTipInfo &tipInfo)
Updates the tooltip.
LRESULT OnMouseEvent(UINT uMsg, WPARAM wParam, LPARAM lParam)
Handles mouse events.
void DispatchMessage2Items(UINT uMsg, WPARAM wParam, LPARAM lParam)
Dispatches messages to items.
virtual BOOL OnItemGetRect(const SOsrPanel *pItem, CRect &rcItem) const
Gets the rectangle of an item.
int m_iPendingViewItem
Definition STileView.h:395
void RedrawItem(SOsrPanel *pItem)
Redraws a specific item.
virtual void OnItemSetCapture(SOsrPanel *pItem, BOOL bCapture)
Handles the capture of an item.
瓷砖视图项定位器类
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
virtual CRect GetClientRect() const
Retrieves the client rectangle of the window.
Definition Swnd.cpp:243
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 void AfterPaint(IRenderTarget *pRT, SPainter &painter)
Restore rendering environment.
Definition Swnd.cpp:1776
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 SetMsgHandled(BOOL bHandled)
Sets the message handled flag.
Definition Swnd.cpp:212
SEventSet m_evtSet
Definition SWnd.h:2581
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
const wchar_t * as_string(const wchar_t *def=L"") const
Gets the attribute value as a string.
Definition SXml.cpp:95
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
SFocusManager * GetFocusManager()
Retrieves the focus manager.
Template class implementing the IObjRef interface.
long Release() override
Decrements the reference count and deletes the object if the count reaches zero.
Interface for rendering target objects.
Definition SRender-i.h:1440
HRESULT GetTransform(float matrix[9]) SCONST PURE
Retrieves the current coordinate transformation matrix.
HRESULT PushClipRect(LPCRECT pRect, UINT mode=RGN_AND) PURE
Push a rectangular clip region.
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 OnReleaseSwndCapture() PURE
Releases the mouse capture from the Swnd object.
SWND OnSetSwndCapture(SWND swnd) PURE
Sets the Swnd object to capture the mouse.
Information about an item in the tile view.
Definition STileView.h:388
SItemPanel * pItem
Definition STileView.h:389
Information for window tooltips.
Definition SWnd.h:208