soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SScrollBarHandler.cpp
1#include <souistd.h>
2#include <core/SScrollBarHandler.h>
3#include <core/SSkin.h>
4
5SNSBEGIN
6SScrollBarHandler::SScrollBarHandler(IScrollBarHost *pCB, bool bVert)
7 : m_bVert(bVert)
8 , m_pSbHost(pCB)
9 , m_iFrame(0)
10 , m_fadeMode(FADE_STOP)
11 , m_iHitPart(-1)
12 , m_iClickPart(-1)
13 , m_nClickPos(-1)
14{
15 SASSERT(m_pSbHost);
16}
17
19{
20 m_bVert = bVert;
21}
22
24{
25 SASSERT(m_fadeMode != FADE_STOP);
26 if (m_iFrame > 0 && m_iFrame < m_pSbHost->GetScrollFadeFrames())
27 {
28 m_iFrame += GetFadeStep();
29 m_pSbHost->OnScrollUpdatePart(m_bVert, -1);
30 }
31 else
32 {
33 m_fadeMode = FADE_STOP;
35 }
36}
37
38CRect SScrollBarHandler::GetPartRect(int iPart) const
39{
40 SASSERT(m_pSbHost->GetScrollBarSkin(m_bVert));
41 const SCROLLINFO *pSi = m_pSbHost->GetScrollBarInfo(m_bVert);
42 __int64 nTrackPos = pSi->nTrackPos;
43 if (pSi->nPage == 0)
44 return CRect();
45 int nMax = pSi->nMax;
46 if (nMax < pSi->nMin + (int)pSi->nPage - 1)
47 nMax = pSi->nMin + pSi->nPage - 1;
48
49 if (nTrackPos == -1)
50 nTrackPos = pSi->nPos;
51 CRect rcAll = m_pSbHost->GetScrollBarRect(m_bVert);
52 int nLength = (IsVertical() ? rcAll.Height() : rcAll.Width());
53 if (nLength <= 0)
54 return CRect();
55
56 int nArrowHei = m_pSbHost->GetScrollBarArrowSize(m_bVert);
57 int nInterHei = nLength - 2 * nArrowHei;
58 if (nInterHei < 0)
59 nInterHei = 0;
60 int nSlideHei = pSi->nPage * nInterHei / (nMax - pSi->nMin + 1);
61 if (nMax == (int)(pSi->nMin + pSi->nPage - 1))
62 nSlideHei = nInterHei;
63 if (nSlideHei < THUMB_MINSIZE)
64 nSlideHei = THUMB_MINSIZE;
65 if (nInterHei < THUMB_MINSIZE)
66 nSlideHei = 0;
67 int nEmptyHei = nInterHei - nSlideHei;
68 if (nInterHei == 0)
69 nArrowHei = nLength / 2;
70 CRect rcRet(0, 0, rcAll.Width(), nArrowHei);
71 if (iPart == kSbRail)
72 {
73 rcRet = CRect(0, 0, rcAll.Width(), nLength);
74 rcRet.DeflateRect(0, nArrowHei);
75 goto end;
76 }
77 if (iPart == SB_LINEUP)
78 goto end;
79 rcRet.top = rcRet.bottom;
80 if ((pSi->nMax - pSi->nMin - pSi->nPage + 1) == 0)
81 rcRet.bottom += nEmptyHei / 2;
82 else
83 rcRet.bottom += (int)(nEmptyHei * nTrackPos / (pSi->nMax - pSi->nMin - pSi->nPage + 1));
84 if (iPart == SB_PAGEUP)
85 goto end;
86 rcRet.top = rcRet.bottom;
87 rcRet.bottom += nSlideHei;
88 if (iPart == SB_THUMBTRACK)
89 goto end;
90 rcRet.top = rcRet.bottom;
91 rcRet.bottom = nLength - nArrowHei;
92 if (iPart == SB_PAGEDOWN)
93 goto end;
94 rcRet.top = rcRet.bottom;
95 rcRet.bottom = nLength;
96 if (iPart == SB_LINEDOWN)
97 goto end;
98end:
99 if (!IsVertical())
100 {
101 rcRet.left = rcRet.top;
102 rcRet.right = rcRet.bottom;
103 rcRet.top = 0;
104 rcRet.bottom = rcAll.Height();
105 }
106 rcRet.OffsetRect(rcAll.TopLeft());
107 return rcRet;
108}
109
111{
112 return m_bVert;
113}
114
116{
117 return m_pSbHost->GetScrollBarContainer();
118}
119
120const IInterpolator *SScrollBarHandler::GetInterpolator() const
121{
122 return m_pSbHost->GetScrollInterpolator();
123 ;
124}
125
126int SScrollBarHandler::HitTest(CPoint pt) const
127{
128 static const int parts[] = {
129 SB_LINEUP, SB_PAGEUP, SB_THUMBTRACK, SB_PAGEDOWN, SB_LINEDOWN,
130 };
131 for (int i = 0; i < ARRAYSIZE(parts); i++)
132 {
133 CRect rc = GetPartRect(parts[i]);
134 if (rc.PtInRect(pt))
135 return parts[i];
136 }
137 return -1;
138}
139
140void SScrollBarHandler::OnDraw(IRenderTarget *pRT, int iPart) const
141{
142 CRect rcPart = GetPartRect(iPart);
143 DWORD dwState = GetPartState(iPart);
144 if (iPart == kSbRail)
145 iPart = SB_PAGEUP;
146 BYTE byAlpha = GetAlpha(iPart);
147 m_pSbHost->GetScrollBarSkin(IsVertical())->DrawByState2(pRT, rcPart, MAKESBSTATE(iPart, dwState, IsVertical()), byAlpha);
148}
149
151{
152 if (id == IScrollBarHost::Timer_Wait)
153 {
154 m_pSbHost->OnScrollKillTimer(m_bVert, IScrollBarHost::Timer_Wait);
155 m_pSbHost->OnScrollSetTimer(m_bVert, IScrollBarHost::Timer_Go, IScrollBarHost::kTime_Go);
156 }
157 else if (id == IScrollBarHost::Timer_Go)
158 {
159 SASSERT(m_iClickPart != -1);
160 SASSERT(m_iClickPart != SB_THUMBTRACK);
161 if (m_iClickPart == m_iHitPart)
162 {
163 if (m_iClickPart == SB_PAGEUP || m_iClickPart == SB_PAGEDOWN)
164 {
165 int iHitPart = HitTest(m_ptCursor);
166 if (iHitPart == SB_THUMBTRACK)
167 return;
168 }
169 m_pSbHost->OnScrollCommand(m_bVert, m_iClickPart, 0);
170 }
171 }
172}
173
175{
176 if (m_fadeMode != FADE_STOP)
177 {
178 m_fadeMode = FADE_STOP;
180 }
181}
182
184{
185 if (!m_pSbHost->IsScrollBarEnable(m_bVert))
186 return;
187
188 if (m_iClickPart == SB_THUMBTRACK)
189 return;
190
191 if (m_iClickPart == -1)
192 {
193 if (m_pSbHost->GetScrollFadeFrames() > 0)
194 {
195 m_iFrame = 1;
196 m_fadeMode = FADEIN; // to show
198 }
199 }
200 else
201 {
202 m_iHitPart = HitTest(pt); // update hit part.
203 m_pSbHost->OnScrollUpdatePart(m_bVert, m_iClickPart);
204 }
205}
206
208{
209 if (!m_pSbHost->IsScrollBarEnable(m_bVert))
210 return;
211
212 if (m_iClickPart == SB_THUMBTRACK)
213 return;
214
215 int iOldHit = m_iHitPart;
216 m_iHitPart = -1;
217
218 if (m_iClickPart == -1)
219 {
220 if (m_pSbHost->GetScrollFadeFrames() == 0)
221 {
222 if (iOldHit != -1)
223 m_pSbHost->OnScrollUpdatePart(m_bVert, iOldHit);
224 }
225 else
226 {
227 m_iFrame = m_pSbHost->GetScrollFadeFrames() - 1;
228 m_fadeMode = FADEOUT; // to hide
230 }
231 }
232 else
233 {
234 m_pSbHost->OnScrollUpdatePart(m_bVert, m_iClickPart);
235 }
236}
237
239{
240 if (!m_pSbHost->IsScrollBarEnable(m_bVert))
241 return;
242
243 m_ptCursor = pt;
244 int iNewHit = HitTest(pt);
245 if (m_iClickPart == -1)
246 {
247 if (iNewHit != m_iHitPart)
248 {
249 int iOldHit = m_iHitPart;
250 m_iHitPart = iNewHit;
251 if (iOldHit != -1)
252 m_pSbHost->OnScrollUpdatePart(m_bVert, iOldHit);
253 if (m_iHitPart != -1)
254 m_pSbHost->OnScrollUpdatePart(m_bVert, m_iHitPart);
255 }
256 }
257 else if (m_iClickPart == SB_THUMBTRACK)
258 { // draging.
259 CRect rcWnd = m_pSbHost->GetScrollBarRect(m_bVert);
260 int nInterHei = (IsVertical() ? rcWnd.Height() : rcWnd.Width()) - 2 * m_pSbHost->GetScrollBarArrowSize(m_bVert);
261 const SCROLLINFO *psi = m_pSbHost->GetScrollBarInfo(m_bVert);
262 int nSlideHei = psi->nPage * nInterHei / (psi->nMax - psi->nMin + 1);
263 if (nSlideHei < THUMB_MINSIZE)
264 nSlideHei = THUMB_MINSIZE;
265 if (nInterHei < THUMB_MINSIZE)
266 nSlideHei = 0;
267 int nEmptyHei = nInterHei - nSlideHei;
268 int nDragLen = IsVertical() ? (pt.y - m_ptClick.y) : (pt.x - m_ptClick.x);
269 int nSlide = (int)((nEmptyHei == 0) ? 0 : (nDragLen * (__int64)(psi->nMax - psi->nMin - psi->nPage + 1) / nEmptyHei));
270 int nNewTrackPos = m_nClickPos + nSlide;
271 if (nNewTrackPos < psi->nMin)
272 {
273 nNewTrackPos = psi->nMin;
274 }
275 else if (nNewTrackPos > (int)(psi->nMax - psi->nMin - psi->nPage + 1))
276 {
277 nNewTrackPos = psi->nMax - psi->nMin - psi->nPage + 1;
278 }
279 if (nNewTrackPos != psi->nTrackPos)
280 {
281 m_pSbHost->OnScrollUpdateThumbTrack(m_bVert, nNewTrackPos);
282 }
283 m_iHitPart = iNewHit;
284 }
285 else if (m_iHitPart != iNewHit)
286 {
287 m_iHitPart = iNewHit;
288 if (m_iHitPart == m_iClickPart)
289 {
290 m_pSbHost->OnScrollSetTimer(m_bVert, IScrollBarHost::Timer_Go, IScrollBarHost::kTime_Go);
291 }
292 else
293 {
294 m_pSbHost->OnScrollKillTimer(m_bVert, IScrollBarHost::Timer_Go);
295 }
296 m_pSbHost->OnScrollUpdatePart(m_bVert, m_iClickPart);
297 }
298}
299
301{
302 if (!m_pSbHost->IsScrollBarEnable(m_bVert))
303 return;
304
305 int iClickPart = m_iClickPart;
306 SASSERT(iClickPart != -1);
307 m_iClickPart = -1;
308 m_nClickPos = -1;
309 m_pSbHost->OnScrollUpdatePart(m_bVert, iClickPart);
310 if (m_iHitPart != -1 && m_iHitPart != iClickPart)
311 {
312 m_pSbHost->OnScrollUpdatePart(m_bVert, m_iHitPart);
313 }
314 m_pSbHost->OnScrollKillTimer(m_bVert, IScrollBarHost::Timer_Wait);
315 m_pSbHost->OnScrollKillTimer(m_bVert, IScrollBarHost::Timer_Go);
316
317 if (iClickPart == SB_THUMBTRACK)
318 {
319 const SCROLLINFO *psi = m_pSbHost->GetScrollBarInfo(m_bVert);
320 if (psi->nTrackPos != -1)
321 m_pSbHost->OnScrollCommand(m_bVert, SB_THUMBPOSITION, psi->nTrackPos);
322 }
323
324 if (iClickPart != -1 && m_iHitPart == -1)
325 {
326 OnMouseLeave();
327 }
328}
329
331{
332 if (!m_pSbHost->IsScrollBarEnable(m_bVert))
333 return false;
334 int iClickPart = HitTest(pt);
335 if (iClickPart == -1)
336 return false;
337 m_iClickPart = iClickPart;
338 m_ptClick = pt;
339 if (m_fadeMode != FADE_STOP)
340 {
341 m_iFrame = m_pSbHost->GetScrollFadeFrames(); // stop animate
342 m_pSbHost->OnScrollUpdatePart(m_bVert, -1);
343 }
344 else
345 {
346 m_pSbHost->OnScrollUpdatePart(m_bVert, m_iHitPart);
347 }
348
349 const SCROLLINFO *psi = m_pSbHost->GetScrollBarInfo(m_bVert);
350 if (iClickPart != SB_THUMBTRACK)
351 m_pSbHost->OnScrollCommand(m_bVert, iClickPart, 0);
352
353 m_nClickPos = psi->nPos;
354
355 switch (m_iClickPart)
356 {
357 case SB_LINEUP:
358 case SB_LINEDOWN:
359 case SB_PAGEUP:
360 case SB_PAGEDOWN:
361 m_pSbHost->OnScrollSetTimer(m_bVert, IScrollBarHost::Timer_Wait, IScrollBarHost::kTime_Wait);
362 break;
363 }
364 return true;
365}
366
367BYTE SScrollBarHandler::GetAlpha(int iPart) const
368{
369 if (m_pSbHost->GetScrollFadeFrames() <= 0)
370 return 0xFF;
371 float fProg = GetInterpolator()->getInterpolation(m_iFrame * 1.0f / m_pSbHost->GetScrollFadeFrames());
372 if (iPart == SB_THUMBTRACK)
373 {
374 return (BYTE)(fProg * (0xFF - m_pSbHost->GetScrollThumbTrackMinAlpha()) + m_pSbHost->GetScrollThumbTrackMinAlpha());
375 }
376 else
377 {
378 return (BYTE)(fProg * 0xFF);
379 }
380}
381
383{
384 switch (m_fadeMode)
385 {
386 case FADEIN:
387 return 1;
388 case FADEOUT:
389 return -1;
390 case FADE_STOP:
391 default:
392 return 0;
393 }
394}
395
397{
398 return m_iHitPart;
399}
400
402{
403 return m_iClickPart;
404}
405
407{
408 if (iPart == kSbRail)
409 return SBST_NORMAL;
410 if (!m_pSbHost->IsScrollBarEnable(m_bVert))
411 return SBST_INACTIVE;
412
413 DWORD dwState = SBST_NORMAL;
414 if (iPart == m_iClickPart && (m_iClickPart == m_iHitPart || m_iClickPart == SB_THUMBTRACK))
415 dwState = SBST_PUSHDOWN;
416 else if (iPart == m_iHitPart)
417 dwState = SBST_HOVER;
418 return dwState;
419}
420
422{
423 if (pOldContainer)
424 pOldContainer->UnregisterTimelineHandler(this);
425}
426
427SNSEND
Skin Classes for SOUI.
#define MAKESBSTATE(sbCode, nState1, bVertical)
Macro to create a scrollbar state code.
Definition SSkin.h:611
#define THUMB_MINSIZE
Minimum size for the scrollbar thumb.
Definition SSkin.h:629
void OnMouseLeave()
Handles mouse leave events.
CRect GetPartRect(int iPart) const
Gets the rectangle of a scrollbar part.
const IInterpolator * GetInterpolator() const
Gets the interpolator for the scrollbar.
void OnContainerChanged(ISwndContainer *pOldContainer, ISwndContainer *pNewContainer)
Handles container change events.
void OnDestroy()
Handles destruction events.
int GetClickPart() const
Gets the clicked part of the scrollbar.
int HitTest(CPoint pt) const
Performs hit testing on the scrollbar.
void OnNextFrame() OVERRIDE
Handles the next frame in the timeline.
void OnMouseHover(CPoint pt)
Handles mouse hover events.
void SetVertical(bool bVert)
Sets the orientation of the scrollbar.
DWORD GetPartState(int iPart) const
Gets the state of a part of the scrollbar.
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.
bool OnMouseDown(CPoint pt)
Handles mouse down events.
ISwndContainer * GetContainer()
Gets the container for the scrollbar.
bool IsVertical() const
Checks if the scrollbar is vertical.
BYTE GetAlpha(int iPart) const
Gets the alpha value for a part of the scrollbar.
void OnMouseMove(CPoint pt)
Handles mouse move events.
int GetFadeStep() const
Gets the fade step for the scrollbar.
Interface for rendering target objects.
Definition SRender-i.h:1440
Interface for scrollbar host.
SOUI Window Container Interface.
BOOL RegisterTimelineHandler(ITimelineHandler *pHandler) PURE
Registers an animation frame handler.
BOOL UnregisterTimelineHandler(ITimelineHandler *pHandler) PURE
Unregisters an animation frame handler.