soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SPanel.cpp
1//////////////////////////////////////////////////////////////////////////
2// File Name: SPanel.h
3//////////////////////////////////////////////////////////////////////////
4#include "souistd.h"
5#include "core/SPanel.h"
6
7#define DEF_UPDATEINTERVAL 0
8
9SNSBEGIN
10
11CRect SPanel::GetScrollBarRect(BOOL bVert) const
12{
13 CRect rcSb;
14 if (!HasScrollBar(bVert))
15 return rcSb;
16
18
19 if (bVert)
20 {
21 rcSb.left = rcSb.right - GetSbWidth();
22 }
23 else
24 {
25 rcSb.top = rcSb.bottom - GetSbWidth();
26 }
27 if (HasScrollBar(!bVert))
28 {
29 if (bVert)
30 {
31 rcSb.bottom -= GetSbWidth();
32 }
33 else
34 {
35 rcSb.right -= GetSbWidth();
36 }
37 }
38
39 if (bVert)
40 {
41 rcSb.top += m_nSbTop.toPixelSize(GetScale());
42 rcSb.bottom -= m_nSbBottom.toPixelSize(GetScale());
43 }
44 else
45 {
46 rcSb.left += m_nSbLeft.toPixelSize(GetScale());
47 rcSb.right -= m_nSbRight.toPixelSize(GetScale());
48 }
49 return rcSb;
50}
51
53{
54 return m_pSkinSb;
55}
56
57const SCROLLINFO *SPanel::GetScrollBarInfo(BOOL bVert) const
58{
59 return bVert ? (&m_siVer) : (&m_siHoz);
60}
61
62int SPanel::GetScrollBarArrowSize(BOOL bVert) const
63{
64 if (m_nSbArrowSize.isValid())
65 return m_nSbArrowSize.toPixelSize(GetScale());
66 SASSERT(m_pSkinSb);
67 if (!m_pSkinSb->HasArrow())
68 return 0;
69 return m_pSkinSb->GetIdealSize();
70}
71
72void SPanel::OnScrollUpdatePart(BOOL bVert, int iPart)
73{
74 SScrollBarHandler &sbHandler = bVert ? m_sbVert : m_sbHorz;
75 if (iPart == -1)
76 {
77 CRect rc = GetScrollBarRect(bVert);
79 sbHandler.OnDraw(pRT, SB_LINEUP);
80 sbHandler.OnDraw(pRT, SScrollBarHandler::kSbRail);
81 sbHandler.OnDraw(pRT, SB_THUMBTRACK);
82 sbHandler.OnDraw(pRT, SB_LINEDOWN);
84 }
85 else if (iPart == SB_THUMBTRACK)
86 {
87 CRect rcRail = sbHandler.GetPartRect(SScrollBarHandler::kSbRail);
89 sbHandler.OnDraw(pRT, SScrollBarHandler::kSbRail);
90 sbHandler.OnDraw(pRT, SB_THUMBTRACK);
92 }
93 else if (iPart == SB_PAGEDOWN || iPart == SB_PAGEUP)
94 {
95 CRect rc = sbHandler.GetPartRect(iPart);
97 sbHandler.OnDraw(pRT, SScrollBarHandler::kSbRail);
99 }
100 else
101 {
102 CRect rc = sbHandler.GetPartRect(iPart);
103 IRenderTarget *pRT = GetRenderTarget(&rc, GRT_PAINTBKGND, FALSE);
104 sbHandler.OnDraw(pRT, iPart);
106 }
107}
108
113
114void SPanel::OnScrollUpdateThumbTrack(BOOL bVert, int nPos)
115{
116 SScrollBarHandler &sbHandler = bVert ? m_sbVert : m_sbHorz;
117 SCROLLINFO &si = bVert ? m_siVer : m_siHoz;
118 CRect rcOldThumb = sbHandler.GetPartRect(SB_THUMBTRACK);
119 si.nTrackPos = nPos;
120 CRect rcThumb = sbHandler.GetPartRect(SB_THUMBTRACK);
121 CRect rcUnion;
122 rcUnion.UnionRect(rcOldThumb, rcThumb);
123 IRenderTarget *pRT = GetRenderTarget(&rcUnion, GRT_PAINTBKGND, FALSE);
124 sbHandler.OnDraw(pRT, SScrollBarHandler::kSbRail);
125 sbHandler.OnDraw(pRT, SB_THUMBTRACK);
127 OnScroll(bVert, SB_THUMBTRACK, nPos);
128}
129
130void SPanel::OnScrollCommand(BOOL bVert, int iCmd, int nPos)
131{
132 SASSERT(iCmd != SB_THUMBTRACK);
133 OnScroll(bVert, iCmd, nPos);
134}
135
136void SPanel::OnScrollSetTimer(BOOL bVert, char id, UINT uElapse)
137{
138 SetTimer(id, uElapse);
139}
140
141void SPanel::OnScrollKillTimer(BOOL bVert, char id)
142{
143 KillTimer(id);
144}
145
146const IInterpolator *SPanel::GetScrollInterpolator() const
147{
148 if (m_fadeFrames > 0 && !m_fadeInterpolator)
149 {
150 m_fadeInterpolator.Attach(CREATEINTERPOLATOR(L"Accelerate"));
151 }
152 return m_fadeInterpolator;
153}
154
156{
157 return m_fadeFrames;
158}
159
161{
162 return m_bySbThumbTrackMinAlpha;
163}
164
166 : m_dragSb(SSB_NULL)
167 , m_hitSb(SSB_NULL)
168 , m_wBarVisible(0)
169 , m_wBarEnable(SSB_BOTH)
170 , m_dwUpdateInterval(DEF_UPDATEINTERVAL)
171 , m_nScrollSpeed(10)
172 , m_zDelta(0)
173 , m_sbVert(this, true)
174 , m_sbHorz(this, false)
175 , m_fadeFrames(0)
176 , m_bySbThumbTrackMinAlpha(128)
177{
178 m_nSbWid.setInvalid();
179 m_nSbArrowSize.setInvalid();
180
181 ISkinObj *pSkin = GETBUILTINSKIN(SKIN_SYS_SCROLLBAR);
182 if (pSkin && pSkin->IsClass(SSkinScrollbar::GetClassName()))
183 m_pSkinSb = (SSkinScrollbar *)pSkin;
184
185 memset(&m_siHoz, 0, sizeof(SCROLLINFO));
186 memset(&m_siVer, 0, sizeof(SCROLLINFO));
187 m_siHoz.nTrackPos = (DWORD)-1;
188 m_siVer.nTrackPos = (DWORD)-1;
189}
190
191BOOL SPanel::ShowScrollBar(int wBar, BOOL bShow)
192{
193 if (bShow)
194 m_wBarVisible |= wBar;
195 else
196 m_wBarVisible &= ~wBar;
197 SSendMessage(WM_NCCALCSIZE);
198 Invalidate();
199 return TRUE;
200}
201
202BOOL SPanel::EnableScrollBar(int wBar, BOOL bEnable)
203{
204 if (bEnable)
205 m_wBarEnable |= wBar;
206 else
207 m_wBarEnable &= ~wBar;
208 if (wBar & SSB_VERT)
209 {
210 CRect rcSb = GetScrollBarRect(TRUE);
211 InvalidateRect(rcSb);
212 }
213 if (wBar & SSB_HORZ)
214 {
215 CRect rcSb = GetScrollBarRect(FALSE);
216 InvalidateRect(rcSb);
217 }
218 return TRUE;
219}
220
221BOOL SPanel::IsScrollBarEnable(BOOL bVertical) const
222{
223 return m_wBarEnable & (bVertical ? SSB_VERT : SSB_HORZ);
224}
225
226void SPanel::SetScrollInfo(SCROLLINFO si, BOOL bVertical)
227{
228 SCROLLINFO *psi = bVertical ? (&m_siVer) : (&m_siHoz);
229 if (si.fMask & SIF_RANGE)
230 {
231 psi->nMin = si.nMin;
232 psi->nMax = si.nMax;
233 }
234 if (si.fMask & SIF_PAGE)
235 psi->nPage = si.nPage;
236 if (si.fMask & SIF_POS)
237 psi->nPos = si.nPos;
238 if (si.fMask & SIF_TRACKPOS)
239 psi->nTrackPos = si.nTrackPos;
240 if (si.nPage == 0)
241 psi->nPos = 0;
242 else
243 {
244 if (psi->nPos > (psi->nMax - (int)psi->nPage + 1))
245 psi->nPos = (psi->nMax - psi->nPage + 1);
246 if (psi->nPos < psi->nMin)
247 psi->nPos = psi->nMin;
248 }
249}
250
251BOOL SPanel::SetScrollPos(BOOL bVertical, int nNewPos, BOOL bRedraw)
252{
253 SCROLLINFO *psi = bVertical ? (&m_siVer) : (&m_siHoz);
254
255 // make sure nNewPos is valid.
256 if (nNewPos < psi->nMin)
257 nNewPos = psi->nMin;
258 if (nNewPos > psi->nMax - (int)psi->nPage + 1)
259 nNewPos = psi->nMax - psi->nPage + 1;
260
261 LockUpdate();
262 BOOL bRet = OnScroll(bVertical, SB_THUMBPOSITION, nNewPos);
263 UnlockUpdate();
264 if (bRet)
265 {
266 if (bRedraw)
267 {
268 CRect rcSb = GetScrollBarRect(!!bVertical);
269 InvalidateRect(rcSb);
270 }
271 Invalidate();
272 }
273 return bRet;
274}
275
276int SPanel::GetScrollPos(BOOL bVertical) const
277{
278 const SCROLLINFO &si = bVertical ? m_siVer : m_siHoz;
279 return si.nTrackPos != -1 ? si.nTrackPos : si.nPos;
280}
281
282BOOL SPanel::SetScrollRange(BOOL bVertical, int nMinPos, int nMaxPos, BOOL bRedraw)
283{
284 SCROLLINFO *psi = bVertical ? (&m_siVer) : (&m_siHoz);
285
286 bRedraw = bRedraw || psi->nMin != nMinPos || psi->nMax != nMaxPos;
287 psi->nMin = nMinPos;
288 psi->nMax = nMaxPos;
289
290 if (psi->nPos < psi->nMin)
291 psi->nPos = psi->nMin;
292 if (psi->nPos > psi->nMax - (int)psi->nPage + 1)
293 psi->nPos = psi->nMax - psi->nPage + 1;
294
295 if (bRedraw)
296 {
297 CRect rcSb = GetScrollBarRect(!!bVertical);
298 InvalidateRect(rcSb);
299 }
300 return TRUE;
301}
302
303BOOL SPanel::GetScrollRange(BOOL bVertical, LPINT lpMinPos, LPINT lpMaxPos) const
304{
305 const SCROLLINFO *psi = bVertical ? (&m_siVer) : (&m_siHoz);
306 if (lpMaxPos)
307 *lpMaxPos = psi->nMax;
308 if (lpMinPos)
309 *lpMinPos = psi->nMin;
310 return TRUE;
311}
312
313BOOL SPanel::HasScrollBar(BOOL bVertical) const
314{
315 return m_wBarVisible & (bVertical ? SSB_VERT : SSB_HORZ);
316}
317
319{
320 int nRet = __baseCls::OnCreate(NULL);
321 if (nRet != 0)
322 return nRet;
323 return m_pSkinSb ? 0 : -1;
324}
325
327{
328 m_sbHorz.OnDestroy();
329 m_sbVert.OnDestroy();
331}
332
334{
335 __baseCls::OnNcPaint(pRT);
336 CRect rcDest;
337 //绘制滚动条
338 if (HasScrollBar(TRUE))
339 {
340 m_sbVert.OnDraw(pRT, SB_LINEUP);
341 m_sbVert.OnDraw(pRT, SScrollBarHandler::kSbRail);
342 m_sbVert.OnDraw(pRT, SB_THUMBTRACK);
343 m_sbVert.OnDraw(pRT, SB_LINEDOWN);
344 }
345 if (HasScrollBar(FALSE))
346 {
347 m_sbHorz.OnDraw(pRT, SB_LINEUP);
348 m_sbHorz.OnDraw(pRT, SScrollBarHandler::kSbRail);
349 m_sbHorz.OnDraw(pRT, SB_THUMBTRACK);
350 m_sbHorz.OnDraw(pRT, SB_LINEDOWN);
351 }
352
353 if (HasScrollBar(TRUE) && HasScrollBar(FALSE))
354 {
355 CRect rcDest;
356 __baseCls::GetClientRect(&rcDest);
357 rcDest.left = rcDest.right - GetSbWidth();
358 rcDest.top = rcDest.bottom - GetSbWidth();
359 m_pSkinSb->DrawByState(pRT, rcDest, SB_CORNOR);
360 }
361}
362
363void SPanel::GetClientRect(LPRECT pRect) const
364{
365 *pRect = m_rcClient;
366}
367
369{
370 return m_rcClient;
371}
372
373BOOL SPanel::OnNcHitTest(CPoint pt)
374{
375 if (m_dragSb != SSB_NULL)
376 return TRUE;
377 return !m_rcClient.PtInRect(pt);
378}
379
380void SPanel::OnNcLButtonDown(UINT nFlags, CPoint point)
381{
382 SetCapture();
383 if (m_sbVert.OnMouseDown(point))
384 m_dragSb = SSB_VERT;
385 else if (m_sbHorz.OnMouseDown(point))
386 m_dragSb = SSB_HORZ;
387 else
388 m_dragSb = SSB_NULL;
389}
390
391void SPanel::OnNcLButtonUp(UINT nFlags, CPoint pt)
392{
393 if (m_dragSb != SSB_NULL)
394 {
395 SScrollBarHandler &sbHandler = m_dragSb == SSB_VERT ? m_sbVert : m_sbHorz;
396 sbHandler.OnMouseUp(pt);
397 m_dragSb = SSB_NULL;
398 OnNcMouseMove(nFlags, pt);
399 }
401}
402
403void SPanel::OnNcMouseMove(UINT nFlags, CPoint point)
404{
405 if (m_dragSb != SSB_NULL)
406 {
407 SScrollBarHandler &sbHandler = m_dragSb == SSB_VERT ? m_sbVert : m_sbHorz;
408 CRect rcSb = GetScrollBarRect(m_dragSb == SSB_VERT);
409 BOOL bInSbNew = rcSb.PtInRect(point);
410 BOOL bInSbOld = sbHandler.GetHitPart() != -1;
411 if (bInSbNew != bInSbOld)
412 {
413 if (bInSbOld)
414 sbHandler.OnMouseLeave();
415 else
416 sbHandler.OnMouseHover(point);
417 }
418 sbHandler.OnMouseMove(point);
419
420 m_hitSb = bInSbNew ? m_dragSb : SSB_NULL;
421 }
422 else
423 {
424 if (m_sbVert.HitTest(point) != -1)
425 {
426 if (m_hitSb == SSB_NULL)
427 m_sbVert.OnMouseHover(point);
428 else
429 m_sbVert.OnMouseMove(point);
430 m_hitSb = SSB_VERT;
431 }
432 else if (m_sbHorz.HitTest(point) != -1)
433 {
434 if (m_hitSb == SSB_NULL)
435 m_sbHorz.OnMouseHover(point);
436 else
437 m_sbHorz.OnMouseMove(point);
438 m_hitSb = SSB_HORZ;
439 }
440 else
441 {
442 if (m_hitSb != SSB_NULL)
443 {
444 SScrollBarHandler &sbHandler = m_hitSb == SSB_VERT ? m_sbVert : m_sbHorz;
445 sbHandler.OnMouseLeave();
446 }
447 m_hitSb = SSB_NULL;
448 }
449 }
450}
451
453{
454 if (m_dragSb != SSB_NULL)
455 {
456 if (m_hitSb == m_dragSb)
457 {
458 SScrollBarHandler &sbHandler = m_dragSb == SSB_VERT ? m_sbVert : m_sbHorz;
459 sbHandler.OnMouseLeave();
460 m_hitSb = SSB_NULL;
461 }
462 }
463 else if (m_hitSb != SSB_NULL)
464 {
465 SScrollBarHandler &sbHandler = m_hitSb == SSB_VERT ? m_sbVert : m_sbHorz;
466 sbHandler.OnMouseLeave();
467 m_hitSb = SSB_NULL;
468 }
469}
470
471//滚动条显示或者隐藏时发送该消息
472LRESULT SPanel::OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
473{
474 SWindow::GetClientRect(&m_rcClient);
475
476 if (HasScrollBar(TRUE))
477 m_rcClient.right -= GetSbWidth();
478 if (HasScrollBar(FALSE))
479 m_rcClient.bottom -= GetSbWidth();
480 InvalidateRect(NULL);
481 return 0;
482}
483
484BOOL SPanel::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
485{
486 BOOL bVertScroll = HasScrollBar(TRUE);
487
488 m_zDelta += zDelta;
489 short delta = m_zDelta / WHEEL_DELTA;
490 m_zDelta %= WHEEL_DELTA;
491
492 short nLines = delta > 0 ? delta : (-delta);
493 short i = 0;
494 for (; i < nLines; i++)
495 {
496 // 返回FALSE代表无法再再进行滚动,可以透传给父窗口
497 if (!OnScroll(bVertScroll, delta > 0 ? SB_LINEUP : SB_LINEDOWN, 0))
498 {
499 break;
500 }
501 ScrollUpdate();
502 }
503 if (i < nLines)
504 { // 返回FALSE代表无法再再进行滚动,可以透传给父窗口
505 delta = (nLines - i) * WHEEL_DELTA * (delta > 0 ? 1 : -1);
506 SWindow::OnMouseWheel(nFlags, delta, pt);
507 }
508 if (nLines != 0)
509 {
510 HWND hHost = GetContainer()->GetHostHwnd();
511 ::SendMessage(hHost, WM_MOUSEMOVE, nFlags, MAKELPARAM(pt.x, pt.y));
512 ::SendMessage(hHost, WM_SETCURSOR, WPARAM(hHost), MAKELPARAM(HTCLIENT, WM_MOUSEMOVE));
513 }
514 return FALSE;
515}
516
517BOOL SPanel::OnScroll(BOOL bVertical, UINT uCode, int nPos)
518{
519 SCROLLINFO *psi = bVertical ? (&m_siVer) : (&m_siHoz);
520 int nNewPos = psi->nPos;
521 switch (uCode)
522 {
523 case SB_LINEUP:
524 nNewPos -= GetScrollLineSize(bVertical);
525 break;
526 case SB_LINEDOWN:
527 nNewPos += GetScrollLineSize(bVertical);
528 break;
529 case SB_PAGEUP:
530 nNewPos -= psi->nPage;
531 break;
532 case SB_PAGEDOWN:
533 nNewPos += psi->nPage;
534 break;
535 case SB_THUMBTRACK:
536 nNewPos = nPos;
537 break;
538 case SB_THUMBPOSITION:
539 nNewPos = nPos;
540 psi->nTrackPos = -1;
541 break;
542 case SB_TOP:
543 nNewPos = psi->nMin;
544 break;
545 case SB_BOTTOM:
546 nNewPos = psi->nMax - psi->nPage + 1;
547 break;
548 }
549
550 if (nNewPos < psi->nMin)
551 nNewPos = psi->nMin;
552 if (nNewPos > psi->nMax - (int)psi->nPage + 1)
553 nNewPos = psi->nMax - psi->nPage + 1;
554 if (psi->nPage == 0)
555 nNewPos = 0;
556
557 if (nNewPos == psi->nPos)
558 return FALSE;
559
560 psi->nPos = nNewPos;
561 if (IsVisible(TRUE) && HasScrollBar(bVertical) && uCode != SB_THUMBTRACK)
562 {
563 OnScrollUpdatePart(!!bVertical, SB_THUMBTRACK);
564 }
565 Invalidate();
566 return TRUE;
567}
568
569void SPanel::OnTimer(char cTimerID)
570{
571 if (cTimerID == IScrollBarHost::Timer_Go || cTimerID == IScrollBarHost::Timer_Wait)
572 {
573 SASSERT(m_dragSb != SSB_NULL);
574 SScrollBarHandler &sbHandler = m_dragSb == SSB_VERT ? m_sbVert : m_sbHorz;
575 sbHandler.OnTimer(cTimerID);
576 }
577}
578
580{
581 DWORD dwTime = GetTickCount();
582 if (dwTime - m_dwUpdateTime >= m_dwUpdateInterval)
583 {
584 Update();
585 m_dwUpdateTime = dwTime;
586 }
587}
588
589void SPanel::OnShowWindow(BOOL bShow, UINT nStatus)
590{
591 SWindow::OnShowWindow(bShow, nStatus);
592 if (!IsVisible(TRUE) && m_dragSb != SSB_NULL)
593 { //隐藏窗口时正有可能正在拖动滚动条,需要处理一下。
594 OnNcLButtonUp(0, CPoint(-1, -1));
595 }
596}
597
598void SPanel::OnEnable(BOOL bEnable, UINT uStatus)
599{
600 SWindow::OnEnable(bEnable, uStatus);
601 if (IsDisabled(TRUE) && m_dragSb != SSB_NULL)
602 {
603 OnNcLButtonUp(0, CPoint(-1, -1));
604 }
605}
606
607HRESULT SPanel::OnAttrScrollbarSkin(SStringW strValue, BOOL bLoading)
608{
609 ISkinObj *pSbSkin = GETSKIN(strValue, GetScale());
610 if (!pSbSkin || !pSbSkin->IsClass(SSkinScrollbar::GetClassName()))
611 return E_FAIL;
612 m_pSkinSb = (SSkinScrollbar *)pSbSkin;
613 return bLoading ? S_FALSE : S_OK;
614}
615
616int SPanel::GetScrollLineSize(BOOL bVertical)
617{
618 return m_nScrollSpeed;
619}
620
621void SPanel::OnVScroll(UINT nSBCode, UINT nPos, HWND)
622{
623 OnScroll(TRUE, nSBCode, nPos);
624}
625
626void SPanel::OnHScroll(UINT nSBCode, UINT nPos, HWND)
627{
628 OnScroll(FALSE, nSBCode, nPos);
629}
630
631void SPanel::OnColorize(COLORREF cr)
632{
633 __baseCls::OnColorize(cr);
634 if (m_pSkinSb)
635 m_pSkinSb->OnColorize(cr);
636}
637
639{
640 __baseCls::OnScaleChanged(nScale);
641 if (m_pSkinSb)
642 {
643 SAutoRefPtr<ISkinObj> pSkin = (ISkinObj *)m_pSkinSb;
644 GetScaleSkin(pSkin, nScale);
645 m_pSkinSb = (SSkinScrollbar *)(ISkinObj *)pSkin;
646 SSendMessage(WM_NCCALCSIZE);
647 }
648}
649
651{
652 if (m_nSbWid.isValid())
653 return m_nSbWid.toPixelSize(GetScale());
654 SASSERT(m_pSkinSb);
655 return m_pSkinSb->GetIdealSize();
656}
657
658void SPanel::OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
659{
660 m_sbHorz.OnContainerChanged(pOldContainer, pNewContainer);
661 m_sbVert.OnContainerChanged(pOldContainer, pNewContainer);
662 SWindow::OnContainerChanged(pOldContainer, pNewContainer);
663}
664
665//////////////////////////////////////////////////////////////////////////
667{
668 m_ptOrigin = CPoint();
669 m_szView = CSize();
670 m_bClipClient = TRUE;
671 m_viewSize[0].setInvalid();
672 m_viewSize[1].setInvalid();
673
674 GetEventSet()->addEvent(EVENTID(EventScrollViewOriginChanged));
675 GetEventSet()->addEvent(EVENTID(EventScrollViewSizeChanged));
676 GetEventSet()->addEvent(EVENTID(EventScroll));
677}
678
679void SScrollView::OnSize(UINT nType, CSize size)
680{
681 __baseCls::OnSize(nType, size);
683}
684
685void SScrollView::OnViewOriginChanged(CPoint ptOld, CPoint ptNew)
686{
688 EventScrollViewOriginChanged evt(this);
689 evt.ptOldOrigin = ptOld;
690 evt.ptNewOrigin = ptNew;
691 FireEvent(evt);
692}
693
694void SScrollView::OnViewSizeChanged(CSize szOld, CSize szNew)
695{
696 EventScrollViewSizeChanged evt(this);
697 evt.szOldViewSize = szOld;
698 evt.szNewViewSize = szNew;
699 FireEvent(evt);
700}
701
703{
704 if (pt.x < 0)
705 pt.x = 0;
706 if (pt.y < 0)
707 pt.y = 0;
708 if (pt.x > (int)(m_siHoz.nMax - m_siHoz.nPage + 1))
709 pt.x = (int)(m_siHoz.nMax - m_siHoz.nPage + 1);
710 if (pt.y > (int)(m_siVer.nMax - m_siVer.nPage + 1))
711 pt.y = (int)(m_siVer.nMax - m_siVer.nPage + 1);
712 if (m_ptOrigin.x == pt.x && m_ptOrigin.y == pt.y)
713 return;
714 POINT ptOld = m_ptOrigin;
715 m_ptOrigin = pt;
716 if (GetScrollPos(FALSE) != pt.x)
717 SetScrollPos(FALSE, m_ptOrigin.x, TRUE);
718 if (GetScrollPos(TRUE) != pt.y)
719 SetScrollPos(TRUE, m_ptOrigin.y, TRUE);
720
721 m_layoutDirty = dirty_self;
722
723 OnViewOriginChanged(ptOld, pt);
724
725 Invalidate();
726}
727
728void SScrollView::GetViewOrigin(POINT *ptOri) const
729{
730 SASSERT(ptOri);
731 *ptOri = m_ptOrigin;
732}
733
735{
736 if (szView.cx == m_szView.cx && szView.cy == m_szView.cy)
737 return;
738
739 CSize oldViewSize = m_szView;
740 m_szView = szView;
742 OnViewSizeChanged(oldViewSize, szView);
743}
744
745void SScrollView::GetViewSize(SIZE *szView) const
746{
747 SASSERT(szView);
748 *szView = m_szView;
749}
750
752{
753 CRect rcClient;
754 SWindow::GetClientRect(&rcClient);
755
756 CSize size = rcClient.Size();
757 m_wBarVisible = SSB_NULL; //关闭滚动条
758 CPoint ptOrigin = m_ptOrigin; // backup
759
760 if (size.cy < m_szView.cy || (size.cy < m_szView.cy + GetSbWidth() && size.cx < m_szView.cx))
761 {
762 //需要纵向滚动条
763 m_wBarVisible |= SSB_VERT;
764 m_siVer.nMin = 0;
765 m_siVer.nMax = m_szView.cy - 1;
766 m_siVer.nPage = size.cy;
767 if (m_siVer.nPos + (int)m_siVer.nPage > m_siVer.nMax)
768 {
769 m_siVer.nPos = m_siVer.nMax - m_siVer.nPage;
770 m_ptOrigin.y = m_siVer.nPos;
771 }
772 if (size.cx < m_szView.cx + GetSbWidth())
773 {
774 //需要横向滚动条
775 m_wBarVisible |= SSB_HORZ;
776 m_siVer.nPage = size.cy - GetSbWidth() > 0 ? size.cy - GetSbWidth() : 0;
777
778 m_siHoz.nMin = 0;
779 m_siHoz.nMax = m_szView.cx - 1;
780 m_siHoz.nPage = size.cx - GetSbWidth() > 0 ? size.cx - GetSbWidth() : 0;
781 if (m_siHoz.nPos + (int)m_siHoz.nPage > m_siHoz.nMax)
782 {
783 m_siHoz.nPos = m_siHoz.nMax - m_siHoz.nPage;
784 m_ptOrigin.x = m_siHoz.nPos;
785 }
786 }
787 else
788 {
789 //不需要横向滚动条
790 m_siHoz.nPage = size.cx;
791 m_siHoz.nMin = 0;
792 m_siHoz.nMax = m_siHoz.nPage - 1;
793 m_siHoz.nPos = 0;
794 m_ptOrigin.x = 0;
795 }
796 }
797 else
798 {
799 //不需要纵向滚动条
800 m_siVer.nPage = size.cy;
801 m_siVer.nMin = 0;
802 m_siVer.nMax = size.cy - 1;
803 m_siVer.nPos = 0;
804 m_ptOrigin.y = 0;
805
806 if (size.cx < m_szView.cx)
807 {
808 //需要横向滚动条
809 m_wBarVisible |= SSB_HORZ;
810 m_siHoz.nMin = 0;
811 m_siHoz.nMax = m_szView.cx - 1;
812 m_siHoz.nPage = size.cx;
813 if (m_siHoz.nPos + (int)m_siHoz.nPage > m_siHoz.nMax)
814 {
815 m_siHoz.nPos = m_siHoz.nMax - m_siHoz.nPage;
816 m_ptOrigin.x = m_siHoz.nPos;
817 }
818 }
819 //不需要横向滚动条
820 else
821 {
822 m_siHoz.nPage = size.cx;
823 m_siHoz.nMin = 0;
824 m_siHoz.nMax = m_siHoz.nPage - 1;
825 m_siHoz.nPos = 0;
826 m_ptOrigin.x = 0;
827 }
828 }
829
830 SetScrollPos(TRUE, m_siVer.nPos, TRUE);
831 SetScrollPos(FALSE, m_siHoz.nPos, TRUE);
832
833 SSendMessage(WM_NCCALCSIZE);
834
835 if (m_ptOrigin.x != ptOrigin.x || m_ptOrigin.y != ptOrigin.y)
836 {
837 m_layoutDirty = dirty_self;
838 OnViewOriginChanged(ptOrigin, m_ptOrigin);
839 }
840 Invalidate();
841}
842
843BOOL SScrollView::OnScroll(BOOL bVertical, UINT uCode, int nPos)
844{
845 BOOL bRet = __baseCls::OnScroll(bVertical, uCode, nPos);
846 if (bRet)
847 {
848 int nPos = GetScrollPos(bVertical);
849 CPoint ptOrigin = m_ptOrigin;
850
851 if (bVertical)
852 ptOrigin.y = nPos;
853 else
854 ptOrigin.x = nPos;
855
856 if (ptOrigin != m_ptOrigin)
857 SetViewOrigin(ptOrigin);
858
859 if (uCode == SB_THUMBTRACK)
860 ScrollUpdate();
861
862 EventScroll evt(this);
863 evt.bVertical = bVertical;
864 evt.nSbCode = uCode;
865 evt.nPos = nPos;
866 FireEvent(evt);
867 }
868 return bRet;
869}
870
872{
873 if (!(m_viewSize[0].isValid() && m_viewSize[1].isValid()))
874 return;
875 CRect rcWnd = SWindow::GetClientRect();
876 CRect rcPadding = GetStyle().GetPadding();
877 rcWnd.DeflateRect(rcPadding);
878
879 CSize szView;
880 if (m_viewSize[0].isMatchParent())
881 szView.cx = rcWnd.Width();
882 else if (m_viewSize[0].isWrapContent())
883 szView.cx = -1;
884 else
885 szView.cx = m_viewSize[0].toPixelSize(GetScale());
886
887 if (m_viewSize[1].isMatchParent())
888 szView.cy = rcWnd.Height();
889 else if (m_viewSize[1].isWrapContent())
890 szView.cy = -1;
891 else
892 szView.cy = m_viewSize[1].toPixelSize(GetScale());
893
894 if (m_viewSize[0].isWrapContent() || m_viewSize[1].isWrapContent())
895 {
896 CSize szCalc = GetLayout()->MeasureChildren(this, szView.cx, szView.cy);
897 if (m_viewSize[0].isWrapContent())
898 szView.cx = szCalc.cx;
899 if (m_viewSize[1].isWrapContent())
900 szView.cy = szCalc.cy;
901 }
902
903 if (szView.cy > rcWnd.Height() && m_viewSize[0].isMatchParent())
904 {
905 szView.cx -= GetSbWidth();
906 if (m_viewSize[1].isWrapContent())
907 {
908 // recalc height
909 CSize szCalc = GetLayout()->MeasureChildren(this, szView.cx, -1);
910 szView.cy = szCalc.cy;
911 }
912 }
913 else if (szView.cx > rcWnd.Width() && m_viewSize[1].isMatchParent())
914 {
915 szView.cy -= GetSbWidth();
916 if (m_viewSize[0].isWrapContent())
917 {
918 // recalc width
919 CSize szCalc = GetLayout()->MeasureChildren(this, -1, szView.cy);
920 szView.cx = szCalc.cx;
921 }
922 }
923 if (!m_viewSize[0].isSpecifiedSize())
924 szView.cx += rcPadding.left + rcPadding.right;
925 if (!m_viewSize[1].isSpecifiedSize())
926 szView.cy += rcPadding.top + rcPadding.bottom;
927
928 SetViewSize(szView);
929}
930
931HRESULT SScrollView::OnAttrViewSize(const SStringW &strValue, BOOL bLoading)
932{
933 SStringWList values;
934 if (SplitString(strValue, L',', values) != 2)
935 return E_INVALIDARG;
936 m_viewSize[0] = GETLAYOUTSIZE(values[0]);
937 m_viewSize[1] = GETLAYOUTSIZE(values[1]);
938
939 if (!bLoading)
940 {
942 }
943 return S_FALSE;
944}
945
947{
948 CRect rcRet;
949 __baseCls::GetChildrenLayoutRect(&rcRet);
950 CRect rcPadding = GetStyle().GetPadding();
951 rcRet.OffsetRect(-m_ptOrigin.x, -m_ptOrigin.y);
952 rcRet.right = rcRet.left + m_szView.cx - rcPadding.left - rcPadding.right;
953 rcRet.bottom = rcRet.top + m_szView.cy - rcPadding.top - rcPadding.bottom;
954 *prc = rcRet;
955}
956
958{
960 __baseCls::UpdateChildrenPosition();
961}
962
963SNSEND
SOUI Panel with Scrollbar Support.
#define SB_CORNOR
Constant for scrollbar corner.
Definition SSkin.h:617
@ GRT_PAINTBKGND
Smart pointer class for managing COM-style reference-counted objects.
BOOL addEvent(DWORD dwEventID, LPCWSTR pszEventHandlerName)
添加一个新事件到事件集
static LPCWSTR GetClassName()
Definition Sobject.hpp:41
void OnNcPaint(IRenderTarget *pRT)
Handles the WM_NCPAINT message.
Definition SPanel.cpp:333
int GetScrollPos(BOOL bVertical) SCONST OVERRIDE
Gets the scroll position for a scrollbar.
Definition SPanel.cpp:276
void OnNcLButtonDown(UINT nFlags, CPoint point)
Handles the WM_NCLBUTTONDOWN message.
Definition SPanel.cpp:380
virtual int GetScrollLineSize(BOOL bVertical)
Gets the line size for scrolling.
Definition SPanel.cpp:616
virtual CRect GetClientRect() const
Gets the client rectangle.
Definition SPanel.cpp:368
void SetScrollInfo(SCROLLINFO si, BOOL bVertical) OVERRIDE
Sets the scroll information for a scrollbar.
Definition SPanel.cpp:226
virtual void OnColorize(COLORREF cr)
Handles colorization events.
Definition SPanel.cpp:631
void OnScrollUpdateThumbTrack(BOOL bVert, int nPos) OVERRIDE
Updates the thumb track of the scrollbar.
Definition SPanel.cpp:114
int GetScrollBarArrowSize(BOOL bVert) SCONST OVERRIDE
Gets the arrow size for a scrollbar.
Definition SPanel.cpp:62
void OnNcMouseMove(UINT nFlags, CPoint point)
Handles the WM_NCMOUSEMOVE message.
Definition SPanel.cpp:403
ISwndContainer * GetScrollBarContainer() OVERRIDE
Gets the container for the scrollbar.
Definition SPanel.cpp:109
void OnEnable(BOOL bEnable, UINT uStatus)
Handles the WM_ENABLE message.
Definition SPanel.cpp:598
LRESULT OnNcCalcSize(BOOL bCalcValidRects, LPARAM lParam)
Handles the WM_NCCALCSIZE message.
Definition SPanel.cpp:472
void OnScrollKillTimer(BOOL bVert, char id) OVERRIDE
Kills a timer for the scrollbar.
Definition SPanel.cpp:141
BYTE GetScrollThumbTrackMinAlpha() SCONST OVERRIDE
Gets the minimum alpha value for the scrollbar thumb track.
Definition SPanel.cpp:160
virtual void OnScaleChanged(int nScale)
Handles scale change events.
Definition SPanel.cpp:638
SPanel()
Constructor for SPanel.
Definition SPanel.cpp:165
void OnShowWindow(BOOL bShow, UINT nStatus)
Handles the WM_SHOWWINDOW message.
Definition SPanel.cpp:589
ISkinObj * GetScrollBarSkin(BOOL bVert) SCONST OVERRIDE
Gets the skin for a scrollbar.
Definition SPanel.cpp:52
BOOL GetScrollRange(BOOL bVertical, LPINT lpMinPos, LPINT lpMaxPos) SCONST OVERRIDE
Gets the scroll range for a scrollbar.
Definition SPanel.cpp:303
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
Handles the WM_MOUSEWHEEL message.
Definition SPanel.cpp:484
void OnTimer(char cTimerID)
Handles the WM_TIMER message.
Definition SPanel.cpp:569
void OnNcLButtonUp(UINT nFlags, CPoint pt)
Handles the WM_NCLBUTTONUP message.
Definition SPanel.cpp:391
void OnNcMouseLeave()
Handles the WM_NCMOUSELEAVE message.
Definition SPanel.cpp:452
int GetSbWidth() const
Gets the width of the scrollbar.
Definition SPanel.cpp:650
void OnHScroll(UINT nSBCode, UINT nPos, HWND hwnd)
Handles the WM_HSCROLL message.
Definition SPanel.cpp:626
BOOL HasScrollBar(BOOL bVertical) SCONST OVERRIDE
Checks if a scrollbar is present.
Definition SPanel.cpp:313
int GetScrollFadeFrames() SCONST OVERRIDE
Gets the number of fade frames for the scrollbar.
Definition SPanel.cpp:155
virtual BOOL OnNcHitTest(CPoint pt)
Handles the WM_NCHITTEST message.
Definition SPanel.cpp:373
const SCROLLINFO * GetScrollBarInfo(BOOL bVert) SCONST OVERRIDE
Gets the scroll information for a scrollbar.
Definition SPanel.cpp:57
void OnVScroll(UINT nSBCode, UINT nPos, HWND hwnd)
Handles the WM_VSCROLL message.
Definition SPanel.cpp:621
virtual BOOL OnScroll(BOOL bVertical, UINT uCode, int nPos)
Handles scroll events.
Definition SPanel.cpp:517
BOOL EnableScrollBar(int wBar, BOOL bEnable) OVERRIDE
Enables or disables a scrollbar.
Definition SPanel.cpp:202
int OnCreate(LPVOID)
Handles the WM_CREATE message.
Definition SPanel.cpp:318
CRect GetScrollBarRect(BOOL bVert) SCONST OVERRIDE
Gets the rectangle of a scrollbar.
Definition SPanel.cpp:11
void OnDestroy()
Handles the WM_DESTROY message.
Definition SPanel.cpp:326
BOOL SetScrollPos(BOOL bVertical, int nNewPos, BOOL bRedraw) OVERRIDE
Sets the scroll position for a scrollbar.
Definition SPanel.cpp:251
BOOL IsScrollBarEnable(BOOL bVertical) SCONST OVERRIDE
Checks if a scrollbar is enabled.
Definition SPanel.cpp:221
void ScrollUpdate()
Updates the scrollbar.
Definition SPanel.cpp:579
HRESULT OnAttrScrollbarSkin(SStringW strValue, BOOL bLoading)
Handles the scrollbar skin attribute.
Definition SPanel.cpp:607
virtual void OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
Handles container change events.
Definition SPanel.cpp:658
void OnScrollCommand(BOOL bVert, int iCmd, int nPos) OVERRIDE
Handles scroll commands.
Definition SPanel.cpp:130
const IInterpolator * GetScrollInterpolator() SCONST OVERRIDE
Gets the interpolator for the scrollbar.
Definition SPanel.cpp:146
BOOL ShowScrollBar(int wBar, BOOL bShow) OVERRIDE
Shows or hides a scrollbar.
Definition SPanel.cpp:191
void OnScrollSetTimer(BOOL bVert, char id, UINT uElapse) OVERRIDE
Sets a timer for the scrollbar.
Definition SPanel.cpp:136
BOOL SetScrollRange(BOOL bVertical, int nMinPos, int nMaxPos, BOOL bRedraw) OVERRIDE
Sets the scroll range for a scrollbar.
Definition SPanel.cpp:282
void OnScrollUpdatePart(BOOL bVert, int iPart) OVERRIDE
Updates a part of the scrollbar.
Definition SPanel.cpp:72
Scrollbar Handler.
void OnMouseLeave()
Handles mouse leave events.
CRect GetPartRect(int iPart) const
Gets the rectangle of a scrollbar part.
void OnMouseHover(CPoint pt)
Handles mouse hover events.
int GetHitPart() const
Gets the hit part of the scrollbar.
void OnDraw(IRenderTarget *pRT, int iPart) const
Draws a part of the scrollbar.
void OnTimer(char id)
Handles timer events.
void OnMouseUp(CPoint pt)
Handles mouse up events.
void OnMouseMove(CPoint pt)
Handles mouse move events.
virtual void OnViewSizeChanged(CSize szOld, CSize szNew)
Called when the view size changes.
Definition SPanel.cpp:694
SScrollView()
Constructor for SScrollView.
Definition SPanel.cpp:666
void SetViewOrigin(POINT pt) OVERRIDE
Sets the origin of the view.
Definition SPanel.cpp:702
virtual void UpdateScrollBar()
Updates the scrollbar.
Definition SPanel.cpp:751
void GetChildrenLayoutRect(RECT *prc) SCONST OVERRIDE
Gets the layout rectangle of the children.
Definition SPanel.cpp:946
void UpdateViewSize()
Updates the view size.
Definition SPanel.cpp:871
HRESULT OnAttrViewSize(const SStringW &strValue, BOOL bLoading)
Handles the view size attribute.
Definition SPanel.cpp:931
void GetViewOrigin(POINT *ptOri) SCONST OVERRIDE
Gets the origin of the view.
Definition SPanel.cpp:728
void GetViewSize(SIZE *szView) SCONST OVERRIDE
Gets the size of the view.
Definition SPanel.cpp:745
void UpdateChildrenPosition() OVERRIDE
Updates the position of the children.
Definition SPanel.cpp:957
virtual void OnViewOriginChanged(CPoint ptOld, CPoint ptNew)
Called when the view origin changes.
Definition SPanel.cpp:685
void OnSize(UINT nType, CSize size)
Handles the WM_SIZE message.
Definition SPanel.cpp:679
virtual BOOL OnScroll(BOOL bVertical, UINT uCode, int nPos)
Handles scroll events.
Definition SPanel.cpp:843
void SetViewSize(SIZE szView) OVERRIDE
Sets the size of the view.
Definition SPanel.cpp:734
Scrollbar Skin.
Definition SSkin.h:637
A class representing an ASCII string.
Definition sstringw.h:96
BOOL SetTimer(char id, UINT uElapse) OVERRIDE
Sets a timer for the window.
Definition Swnd.cpp:477
BOOL FireEvent(IEvtArgs *evt) OVERRIDE
Fires an event.
Definition Swnd.cpp:1540
virtual void OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
Called when the container of the window changes.
Definition Swnd.cpp:3407
void OnDestroy()
Handles the destruction of the window.
Definition Swnd.cpp:1701
void UnlockUpdate() OVERRIDE
Unlocks updates to the window.
Definition Swnd.cpp:1497
void ReleaseRenderTarget(IRenderTarget *pRT)
Releases the RenderTarget obtained via GetRenderTarget.
Definition Swnd.cpp:2372
int GetScale() SCONST OVERRIDE
Retrieves the scale factor of the window.
Definition Swnd.cpp:3266
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
virtual CRect GetClientRect() const
Retrieves the client rectangle of the window.
Definition Swnd.cpp:243
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
Handles the mouse wheel event.
Definition Swnd.cpp:2159
LRESULT SSendMessage(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0, BOOL *pbMsgHandled=NULL) OVERRIDE
Sends a message to the window.
Definition Swnd.cpp:364
void InvalidateRect(LPCRECT lprect) OVERRIDE
Invalidates a specific rectangle area of the window.
Definition Swnd.cpp:1444
LayoutDirtyType m_layoutDirty
Definition SWnd.h:2618
SWND SetCapture() OVERRIDE
Sets the window to capture the mouse.
Definition Swnd.cpp:2484
BOOL IsDisabled(BOOL bCheckParent=FALSE) SCONST OVERRIDE
Checks if the window is disabled.
Definition Swnd.cpp:638
SEventSet * GetEventSet()
Retrieves the event set associated with the window.
Definition SWnd.h:1290
BOOL KillTimer(char id) OVERRIDE
Kills a timer for the window.
Definition Swnd.cpp:483
void OnShowWindow(BOOL bShow, UINT nStatus)
Handles showing or hiding the window.
Definition Swnd.cpp:2001
void Invalidate() OVERRIDE
Invalidates the entire window.
Definition Swnd.cpp:1437
ILayout * GetLayout() OVERRIDE
Retrieves the layout object associated with the window.
Definition SWnd.h:396
void GetScaleSkin(SAutoRefPtr< ISkinObj > &pSkin, int nScale)
Retrieves a scaled skin object based on the current scale factor.
Definition Swnd.cpp:3290
void OnEnable(BOOL bEnable, UINT nStatus)
Handles enabling or disabling the window.
Definition Swnd.cpp:2059
void Update(BOOL bForce=FALSE) OVERRIDE
Updates the window.
Definition Swnd.cpp:1430
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
BOOL m_bClipClient
Definition SWnd.h:2607
BOOL ReleaseCapture() OVERRIDE
Releases the mouse capture from the window.
Definition Swnd.cpp:2491
IRenderTarget * GetRenderTarget(LPCRECT pRc=NULL, GrtFlag gdcFlags=GRT_NODRAW, BOOL bClientRT=TRUE)
Retrieves a memory DC compatible with the SWND window.
Definition Swnd.cpp:2320
CRect GetPadding() const
Retrieves the padding rectangle.
Interface for rendering target objects.
Definition SRender-i.h:1440
Interface for Skin Objects.
Definition SSkinobj-i.h:29
BOOL IsClass(LPCWSTR lpszName) SCONST PURE
Checks if the object is of a specified class type.
SOUI Window Container Interface.
HWND GetHostHwnd() PURE
Retrieves the handle to the host window.