OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "xfa/fwl/core/ifwl_scrollbar.h" | |
8 | |
9 #include <algorithm> | |
10 #include <memory> | |
11 #include <utility> | |
12 | |
13 #include "third_party/base/ptr_util.h" | |
14 #include "xfa/fwl/core/cfwl_msgmouse.h" | |
15 #include "xfa/fwl/core/cfwl_msgmousewheel.h" | |
16 #include "xfa/fwl/core/cfwl_notedriver.h" | |
17 #include "xfa/fwl/core/cfwl_themebackground.h" | |
18 #include "xfa/fwl/core/cfwl_themepart.h" | |
19 #include "xfa/fwl/core/cfwl_timerinfo.h" | |
20 #include "xfa/fwl/core/ifwl_themeprovider.h" | |
21 | |
22 #define FWL_SCROLLBAR_Elapse 500 | |
23 #define FWL_SCROLLBAR_MinThumb 5 | |
24 | |
25 IFWL_ScrollBar::IFWL_ScrollBar( | |
26 const CFWL_App* app, | |
27 std::unique_ptr<CFWL_WidgetProperties> properties, | |
28 IFWL_Widget* pOuter) | |
29 : IFWL_Widget(app, std::move(properties), pOuter), | |
30 m_pTimerInfo(nullptr), | |
31 m_fRangeMin(0), | |
32 m_fRangeMax(-1), | |
33 m_fPageSize(0), | |
34 m_fStepSize(0), | |
35 m_fPos(0), | |
36 m_fTrackPos(0), | |
37 m_iMinButtonState(CFWL_PartState_Normal), | |
38 m_iMaxButtonState(CFWL_PartState_Normal), | |
39 m_iThumbButtonState(CFWL_PartState_Normal), | |
40 m_iMinTrackState(CFWL_PartState_Normal), | |
41 m_iMaxTrackState(CFWL_PartState_Normal), | |
42 m_fLastTrackPos(0), | |
43 m_cpTrackPointX(0), | |
44 m_cpTrackPointY(0), | |
45 m_iMouseWheel(0), | |
46 m_bMouseDown(false), | |
47 m_fButtonLen(0), | |
48 m_bMinSize(false), | |
49 m_fMinThumb(FWL_SCROLLBAR_MinThumb), | |
50 m_Timer(this) { | |
51 m_rtClient.Reset(); | |
52 m_rtThumb.Reset(); | |
53 m_rtMinBtn.Reset(); | |
54 m_rtMaxBtn.Reset(); | |
55 m_rtMinTrack.Reset(); | |
56 m_rtMaxTrack.Reset(); | |
57 } | |
58 | |
59 IFWL_ScrollBar::~IFWL_ScrollBar() {} | |
60 | |
61 FWL_Type IFWL_ScrollBar::GetClassID() const { | |
62 return FWL_Type::ScrollBar; | |
63 } | |
64 | |
65 void IFWL_ScrollBar::GetWidgetRect(CFX_RectF& rect, bool bAutoSize) { | |
66 if (!bAutoSize) { | |
67 rect = m_pProperties->m_rtWidget; | |
68 return; | |
69 } | |
70 | |
71 rect.Set(0, 0, 0, 0); | |
72 FX_FLOAT* pfMinWidth = static_cast<FX_FLOAT*>( | |
73 GetThemeCapacity(CFWL_WidgetCapacity::ScrollBarWidth)); | |
74 if (!pfMinWidth) | |
75 return; | |
76 if (IsVertical()) | |
77 rect.Set(0, 0, (*pfMinWidth), (*pfMinWidth) * 3); | |
78 else | |
79 rect.Set(0, 0, (*pfMinWidth) * 3, (*pfMinWidth)); | |
80 IFWL_Widget::GetWidgetRect(rect, true); | |
81 } | |
82 | |
83 void IFWL_ScrollBar::Update() { | |
84 if (IsLocked()) | |
85 return; | |
86 if (!m_pProperties->m_pThemeProvider) | |
87 m_pProperties->m_pThemeProvider = GetAvailableTheme(); | |
88 | |
89 Layout(); | |
90 } | |
91 | |
92 void IFWL_ScrollBar::DrawWidget(CFX_Graphics* pGraphics, | |
93 const CFX_Matrix* pMatrix) { | |
94 if (!pGraphics) | |
95 return; | |
96 if (!m_pProperties->m_pThemeProvider) | |
97 return; | |
98 | |
99 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; | |
100 if (HasBorder()) | |
101 DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix); | |
102 if (HasEdge()) | |
103 DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix); | |
104 DrawTrack(pGraphics, pTheme, true, pMatrix); | |
105 DrawTrack(pGraphics, pTheme, false, pMatrix); | |
106 DrawArrowBtn(pGraphics, pTheme, true, pMatrix); | |
107 DrawArrowBtn(pGraphics, pTheme, false, pMatrix); | |
108 DrawThumb(pGraphics, pTheme, pMatrix); | |
109 } | |
110 | |
111 void IFWL_ScrollBar::SetTrackPos(FX_FLOAT fTrackPos) { | |
112 m_fTrackPos = fTrackPos; | |
113 CalcThumbButtonRect(m_rtThumb); | |
114 CalcMinTrackRect(m_rtMinTrack); | |
115 CalcMaxTrackRect(m_rtMaxTrack); | |
116 } | |
117 | |
118 bool IFWL_ScrollBar::DoScroll(FWL_SCBCODE dwCode, FX_FLOAT fPos) { | |
119 if (dwCode == FWL_SCBCODE::None) | |
120 return false; | |
121 return OnScroll(dwCode, fPos); | |
122 } | |
123 | |
124 void IFWL_ScrollBar::DrawTrack(CFX_Graphics* pGraphics, | |
125 IFWL_ThemeProvider* pTheme, | |
126 bool bLower, | |
127 const CFX_Matrix* pMatrix) { | |
128 CFWL_ThemeBackground param; | |
129 param.m_pWidget = this; | |
130 param.m_iPart = bLower ? CFWL_Part::LowerTrack : CFWL_Part::UpperTrack; | |
131 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) | |
132 ? CFWL_PartState_Disabled | |
133 : (bLower ? m_iMinTrackState : m_iMaxTrackState); | |
134 param.m_pGraphics = pGraphics; | |
135 param.m_matrix.Concat(*pMatrix); | |
136 param.m_rtPart = bLower ? m_rtMinTrack : m_rtMaxTrack; | |
137 pTheme->DrawBackground(¶m); | |
138 } | |
139 | |
140 void IFWL_ScrollBar::DrawArrowBtn(CFX_Graphics* pGraphics, | |
141 IFWL_ThemeProvider* pTheme, | |
142 bool bMinBtn, | |
143 const CFX_Matrix* pMatrix) { | |
144 CFWL_ThemeBackground param; | |
145 param.m_pWidget = this; | |
146 param.m_iPart = bMinBtn ? CFWL_Part::ForeArrow : CFWL_Part::BackArrow; | |
147 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) | |
148 ? CFWL_PartState_Disabled | |
149 : (bMinBtn ? m_iMinButtonState : m_iMaxButtonState); | |
150 param.m_pGraphics = pGraphics; | |
151 param.m_matrix.Concat(*pMatrix); | |
152 param.m_rtPart = bMinBtn ? m_rtMinBtn : m_rtMaxBtn; | |
153 if (param.m_rtPart.height > 0 && param.m_rtPart.width > 0) | |
154 pTheme->DrawBackground(¶m); | |
155 } | |
156 | |
157 void IFWL_ScrollBar::DrawThumb(CFX_Graphics* pGraphics, | |
158 IFWL_ThemeProvider* pTheme, | |
159 const CFX_Matrix* pMatrix) { | |
160 CFWL_ThemeBackground param; | |
161 param.m_pWidget = this; | |
162 param.m_iPart = CFWL_Part::Thumb; | |
163 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) | |
164 ? CFWL_PartState_Disabled | |
165 : m_iThumbButtonState; | |
166 param.m_pGraphics = pGraphics; | |
167 param.m_matrix.Concat(*pMatrix); | |
168 param.m_rtPart = m_rtThumb; | |
169 pTheme->DrawBackground(¶m); | |
170 } | |
171 | |
172 void IFWL_ScrollBar::Layout() { | |
173 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; | |
174 CFWL_ThemePart part; | |
175 part.m_pWidget = this; | |
176 m_fMinThumb = *static_cast<FX_FLOAT*>( | |
177 pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Size)); | |
178 GetClientRect(m_rtClient); | |
179 CalcButtonLen(); | |
180 CalcMinButtonRect(m_rtMinBtn); | |
181 CalcMaxButtonRect(m_rtMaxBtn); | |
182 CalcThumbButtonRect(m_rtThumb); | |
183 CalcMinTrackRect(m_rtMinTrack); | |
184 CalcMaxTrackRect(m_rtMaxTrack); | |
185 } | |
186 | |
187 void IFWL_ScrollBar::CalcButtonLen() { | |
188 m_fButtonLen = IsVertical() ? m_rtClient.width : m_rtClient.height; | |
189 FX_FLOAT fLength = IsVertical() ? m_rtClient.height : m_rtClient.width; | |
190 if (fLength < m_fButtonLen * 2) { | |
191 m_fButtonLen = fLength / 2; | |
192 m_bMinSize = true; | |
193 } else { | |
194 m_bMinSize = false; | |
195 } | |
196 } | |
197 | |
198 void IFWL_ScrollBar::CalcMinButtonRect(CFX_RectF& rect) { | |
199 rect.left = m_rtClient.left; | |
200 rect.top = m_rtClient.top; | |
201 rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen; | |
202 rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height; | |
203 } | |
204 | |
205 void IFWL_ScrollBar::CalcMaxButtonRect(CFX_RectF& rect) { | |
206 rect.left = | |
207 IsVertical() ? m_rtClient.left : m_rtClient.right() - m_fButtonLen; | |
208 rect.top = IsVertical() ? m_rtClient.bottom() - m_fButtonLen : m_rtClient.top; | |
209 rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen; | |
210 rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height; | |
211 } | |
212 | |
213 void IFWL_ScrollBar::CalcThumbButtonRect(CFX_RectF& rect) { | |
214 if (!IsEnabled()) { | |
215 m_rtThumb.Reset(); | |
216 return; | |
217 } | |
218 if (m_bMinSize) { | |
219 m_rtThumb.Empty(); | |
220 return; | |
221 } | |
222 | |
223 FX_FLOAT fRange = m_fRangeMax - m_fRangeMin; | |
224 memset(&rect, 0, sizeof(CFX_Rect)); | |
225 if (fRange < 0) { | |
226 if (IsVertical()) | |
227 rect.Set(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width, 0); | |
228 else | |
229 rect.Set(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height); | |
230 return; | |
231 } | |
232 | |
233 CFX_RectF rtClient = m_rtClient; | |
234 FX_FLOAT fLength = IsVertical() ? rtClient.height : rtClient.width; | |
235 FX_FLOAT fSize = m_fButtonLen; | |
236 fLength -= fSize * 2.0f; | |
237 if (fLength < fSize) | |
238 fLength = 0.0f; | |
239 | |
240 FX_FLOAT fThumbSize = fLength * fLength / (fRange + fLength); | |
241 fThumbSize = std::max(fThumbSize, m_fMinThumb); | |
242 | |
243 FX_FLOAT fDiff = std::max(fLength - fThumbSize, 0.0f); | |
244 FX_FLOAT fTrackPos = | |
245 std::max(std::min(m_fTrackPos, m_fRangeMax), m_fRangeMin); | |
246 if (!fRange) | |
247 return; | |
248 | |
249 FX_FLOAT iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange; | |
250 rect.left = rtClient.left; | |
251 if (!IsVertical()) | |
252 rect.left += iPos; | |
253 | |
254 rect.top = rtClient.top; | |
255 if (IsVertical()) | |
256 rect.top += iPos; | |
257 | |
258 rect.width = IsVertical() ? rtClient.width : fThumbSize; | |
259 rect.height = IsVertical() ? fThumbSize : rtClient.height; | |
260 } | |
261 | |
262 void IFWL_ScrollBar::CalcMinTrackRect(CFX_RectF& rect) { | |
263 if (m_bMinSize) { | |
264 rect.Empty(); | |
265 return; | |
266 } | |
267 | |
268 FX_FLOAT fBottom = m_rtThumb.bottom(); | |
269 FX_FLOAT fRight = m_rtThumb.right(); | |
270 FX_FLOAT ix = (m_rtThumb.left + fRight) / 2; | |
271 FX_FLOAT iy = (m_rtThumb.top + fBottom) / 2; | |
272 rect.left = m_rtClient.left; | |
273 rect.top = m_rtClient.top; | |
274 bool bVertical = IsVertical(); | |
275 rect.width = bVertical ? m_rtClient.width : ix; | |
276 rect.height = bVertical ? iy : m_rtClient.height; | |
277 } | |
278 | |
279 void IFWL_ScrollBar::CalcMaxTrackRect(CFX_RectF& rect) { | |
280 if (m_bMinSize) { | |
281 rect.Empty(); | |
282 return; | |
283 } | |
284 | |
285 FX_FLOAT ix = (m_rtThumb.left + m_rtThumb.right()) / 2; | |
286 FX_FLOAT iy = (m_rtThumb.top + m_rtThumb.bottom()) / 2; | |
287 bool bVertical = IsVertical(); | |
288 rect.left = bVertical ? m_rtClient.left : ix; | |
289 rect.top = bVertical ? iy : m_rtClient.top; | |
290 rect.width = bVertical ? m_rtClient.width : m_rtClient.right() - ix; | |
291 rect.height = bVertical ? m_rtClient.bottom() - iy : m_rtClient.height; | |
292 } | |
293 | |
294 FX_FLOAT IFWL_ScrollBar::GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy) { | |
295 FX_FLOAT fDiffX = fx - m_cpTrackPointX; | |
296 FX_FLOAT fDiffY = fy - m_cpTrackPointY; | |
297 FX_FLOAT fRange = m_fRangeMax - m_fRangeMin; | |
298 FX_FLOAT fPos; | |
299 | |
300 if (IsVertical()) { | |
301 fPos = fRange * fDiffY / | |
302 (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height); | |
303 } else { | |
304 fPos = fRange * fDiffX / | |
305 (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width); | |
306 } | |
307 | |
308 fPos += m_fLastTrackPos; | |
309 return std::min(std::max(fPos, m_fRangeMin), m_fRangeMax); | |
310 } | |
311 | |
312 void IFWL_ScrollBar::GetTrackRect(CFX_RectF& rect, bool bLower) { | |
313 bool bDisabled = !!(m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled); | |
314 if (bDisabled) { | |
315 rect = bLower ? m_rtMinTrack : m_rtMaxTrack; | |
316 return; | |
317 } | |
318 | |
319 FX_FLOAT fW = m_rtThumb.width / 2; | |
320 FX_FLOAT fH = m_rtThumb.height / 2; | |
321 bool bVert = IsVertical(); | |
322 if (bLower) { | |
323 if (bVert) { | |
324 FX_FLOAT fMinTrackHeight = m_rtMinTrack.height - fH - m_rtMinBtn.height; | |
325 fMinTrackHeight = (fMinTrackHeight >= 0.0f) ? fMinTrackHeight : 0.0f; | |
326 rect.Set(m_rtMinTrack.left, m_rtMinTrack.top + m_rtMinBtn.height, | |
327 m_rtMinTrack.width, fMinTrackHeight); | |
328 return; | |
329 } | |
330 | |
331 FX_FLOAT fMinTrackWidth = m_rtMinTrack.width - fW - m_rtMinBtn.width + 2; | |
332 fMinTrackWidth = (fMinTrackWidth >= 0.0f) ? fMinTrackWidth : 0.0f; | |
333 rect.Set(m_rtMinTrack.left + m_rtMinBtn.width - 1, m_rtMinTrack.top, | |
334 fMinTrackWidth, m_rtMinTrack.height); | |
335 return; | |
336 } | |
337 | |
338 if (bVert) { | |
339 FX_FLOAT fMaxTrackHeight = m_rtMaxTrack.height - fH - m_rtMaxBtn.height; | |
340 fMaxTrackHeight = (fMaxTrackHeight >= 0.0f) ? fMaxTrackHeight : 0.0f; | |
341 rect.Set(m_rtMaxTrack.left, m_rtMaxTrack.top + fH, m_rtMaxTrack.width, | |
342 fMaxTrackHeight); | |
343 return; | |
344 } | |
345 | |
346 FX_FLOAT fMaxTrackWidth = m_rtMaxTrack.width - fW - m_rtMaxBtn.width + 2; | |
347 fMaxTrackWidth = (fMaxTrackWidth >= 0.0f) ? fMaxTrackWidth : 0.0f; | |
348 rect.Set(m_rtMaxTrack.left + fW, m_rtMaxTrack.top, fMaxTrackWidth, | |
349 m_rtMaxTrack.height); | |
350 } | |
351 | |
352 bool IFWL_ScrollBar::SendEvent() { | |
353 if (m_iMinButtonState == CFWL_PartState_Pressed) { | |
354 DoScroll(FWL_SCBCODE::StepBackward, m_fTrackPos); | |
355 return false; | |
356 } | |
357 if (m_iMaxButtonState == CFWL_PartState_Pressed) { | |
358 DoScroll(FWL_SCBCODE::StepForward, m_fTrackPos); | |
359 return false; | |
360 } | |
361 if (m_iMinTrackState == CFWL_PartState_Pressed) { | |
362 DoScroll(FWL_SCBCODE::PageBackward, m_fTrackPos); | |
363 return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY); | |
364 } | |
365 if (m_iMaxTrackState == CFWL_PartState_Pressed) { | |
366 DoScroll(FWL_SCBCODE::PageForward, m_fTrackPos); | |
367 return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY); | |
368 } | |
369 if (m_iMouseWheel) { | |
370 FWL_SCBCODE dwCode = m_iMouseWheel < 0 ? FWL_SCBCODE::StepForward | |
371 : FWL_SCBCODE::StepBackward; | |
372 DoScroll(dwCode, m_fTrackPos); | |
373 } | |
374 return true; | |
375 } | |
376 | |
377 bool IFWL_ScrollBar::OnScroll(FWL_SCBCODE dwCode, FX_FLOAT fPos) { | |
378 bool bRet = true; | |
379 CFWL_EvtScroll ev; | |
380 ev.m_iScrollCode = dwCode; | |
381 ev.m_pSrcTarget = this; | |
382 ev.m_fPos = fPos; | |
383 ev.m_pRet = &bRet; | |
384 DispatchEvent(&ev); | |
385 return bRet; | |
386 } | |
387 | |
388 void IFWL_ScrollBar::OnProcessMessage(CFWL_Message* pMessage) { | |
389 if (!pMessage) | |
390 return; | |
391 | |
392 CFWL_MessageType dwMsgCode = pMessage->GetClassID(); | |
393 if (dwMsgCode == CFWL_MessageType::Mouse) { | |
394 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); | |
395 switch (pMsg->m_dwCmd) { | |
396 case FWL_MouseCommand::LeftButtonDown: | |
397 OnLButtonDown(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy); | |
398 break; | |
399 case FWL_MouseCommand::LeftButtonUp: | |
400 OnLButtonUp(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy); | |
401 break; | |
402 case FWL_MouseCommand::Move: | |
403 OnMouseMove(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy); | |
404 break; | |
405 case FWL_MouseCommand::Leave: | |
406 OnMouseLeave(); | |
407 break; | |
408 default: | |
409 break; | |
410 } | |
411 } else if (dwMsgCode == CFWL_MessageType::MouseWheel) { | |
412 CFWL_MsgMouseWheel* pMsg = static_cast<CFWL_MsgMouseWheel*>(pMessage); | |
413 OnMouseWheel(pMsg->m_fx, pMsg->m_fy, pMsg->m_dwFlags, pMsg->m_fDeltaX, | |
414 pMsg->m_fDeltaY); | |
415 } | |
416 } | |
417 | |
418 void IFWL_ScrollBar::OnDrawWidget(CFX_Graphics* pGraphics, | |
419 const CFX_Matrix* pMatrix) { | |
420 DrawWidget(pGraphics, pMatrix); | |
421 } | |
422 | |
423 void IFWL_ScrollBar::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { | |
424 if (!IsEnabled()) | |
425 return; | |
426 | |
427 m_bMouseDown = true; | |
428 SetGrab(true); | |
429 m_cpTrackPointX = fx; | |
430 m_cpTrackPointY = fy; | |
431 m_fLastTrackPos = m_fTrackPos; | |
432 if (m_rtMinBtn.Contains(fx, fy)) | |
433 DoMouseDown(0, m_rtMinBtn, m_iMinButtonState, fx, fy); | |
434 else if (m_rtThumb.Contains(fx, fy)) | |
435 DoMouseDown(1, m_rtThumb, m_iThumbButtonState, fx, fy); | |
436 else if (m_rtMaxBtn.Contains(fx, fy)) | |
437 DoMouseDown(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy); | |
438 else if (m_rtMinTrack.Contains(fx, fy)) | |
439 DoMouseDown(3, m_rtMinTrack, m_iMinTrackState, fx, fy); | |
440 else | |
441 DoMouseDown(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy); | |
442 | |
443 if (!SendEvent()) | |
444 m_pTimerInfo = m_Timer.StartTimer(FWL_SCROLLBAR_Elapse, true); | |
445 } | |
446 | |
447 void IFWL_ScrollBar::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { | |
448 m_pTimerInfo->StopTimer(); | |
449 m_bMouseDown = false; | |
450 DoMouseUp(0, m_rtMinBtn, m_iMinButtonState, fx, fy); | |
451 DoMouseUp(1, m_rtThumb, m_iThumbButtonState, fx, fy); | |
452 DoMouseUp(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy); | |
453 DoMouseUp(3, m_rtMinTrack, m_iMinTrackState, fx, fy); | |
454 DoMouseUp(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy); | |
455 SetGrab(false); | |
456 } | |
457 | |
458 void IFWL_ScrollBar::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { | |
459 DoMouseMove(0, m_rtMinBtn, m_iMinButtonState, fx, fy); | |
460 DoMouseMove(1, m_rtThumb, m_iThumbButtonState, fx, fy); | |
461 DoMouseMove(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy); | |
462 DoMouseMove(3, m_rtMinTrack, m_iMinTrackState, fx, fy); | |
463 DoMouseMove(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy); | |
464 } | |
465 | |
466 void IFWL_ScrollBar::OnMouseLeave() { | |
467 DoMouseLeave(0, m_rtMinBtn, m_iMinButtonState); | |
468 DoMouseLeave(1, m_rtThumb, m_iThumbButtonState); | |
469 DoMouseLeave(2, m_rtMaxBtn, m_iMaxButtonState); | |
470 DoMouseLeave(3, m_rtMinTrack, m_iMinTrackState); | |
471 DoMouseLeave(4, m_rtMaxTrack, m_iMaxTrackState); | |
472 } | |
473 | |
474 void IFWL_ScrollBar::OnMouseWheel(FX_FLOAT fx, | |
475 FX_FLOAT fy, | |
476 uint32_t dwFlags, | |
477 FX_FLOAT fDeltaX, | |
478 FX_FLOAT fDeltaY) { | |
479 m_iMouseWheel = (int32_t)fDeltaX; | |
480 SendEvent(); | |
481 m_iMouseWheel = 0; | |
482 } | |
483 | |
484 void IFWL_ScrollBar::DoMouseDown(int32_t iItem, | |
485 const CFX_RectF& rtItem, | |
486 int32_t& iState, | |
487 FX_FLOAT fx, | |
488 FX_FLOAT fy) { | |
489 if (!rtItem.Contains(fx, fy)) | |
490 return; | |
491 if (iState == CFWL_PartState_Pressed) | |
492 return; | |
493 | |
494 iState = CFWL_PartState_Pressed; | |
495 Repaint(&rtItem); | |
496 } | |
497 | |
498 void IFWL_ScrollBar::DoMouseUp(int32_t iItem, | |
499 const CFX_RectF& rtItem, | |
500 int32_t& iState, | |
501 FX_FLOAT fx, | |
502 FX_FLOAT fy) { | |
503 int32_t iNewState = | |
504 rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered : CFWL_PartState_Normal; | |
505 if (iState == iNewState) | |
506 return; | |
507 | |
508 iState = iNewState; | |
509 Repaint(&rtItem); | |
510 OnScroll(FWL_SCBCODE::EndScroll, m_fTrackPos); | |
511 } | |
512 | |
513 void IFWL_ScrollBar::DoMouseMove(int32_t iItem, | |
514 const CFX_RectF& rtItem, | |
515 int32_t& iState, | |
516 FX_FLOAT fx, | |
517 FX_FLOAT fy) { | |
518 if (!m_bMouseDown) { | |
519 int32_t iNewState = rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered | |
520 : CFWL_PartState_Normal; | |
521 if (iState == iNewState) | |
522 return; | |
523 | |
524 iState = iNewState; | |
525 Repaint(&rtItem); | |
526 } else if ((2 == iItem) && (m_iThumbButtonState == CFWL_PartState_Pressed)) { | |
527 FX_FLOAT fPos = GetTrackPointPos(fx, fy); | |
528 m_fTrackPos = fPos; | |
529 OnScroll(FWL_SCBCODE::TrackPos, fPos); | |
530 } | |
531 } | |
532 | |
533 void IFWL_ScrollBar::DoMouseLeave(int32_t iItem, | |
534 const CFX_RectF& rtItem, | |
535 int32_t& iState) { | |
536 if (iState == CFWL_PartState_Normal) | |
537 return; | |
538 | |
539 iState = CFWL_PartState_Normal; | |
540 Repaint(&rtItem); | |
541 } | |
542 | |
543 void IFWL_ScrollBar::DoMouseHover(int32_t iItem, | |
544 const CFX_RectF& rtItem, | |
545 int32_t& iState) { | |
546 if (iState == CFWL_PartState_Hovered) | |
547 return; | |
548 | |
549 iState = CFWL_PartState_Hovered; | |
550 Repaint(&rtItem); | |
551 } | |
552 | |
553 IFWL_ScrollBar::Timer::Timer(IFWL_ScrollBar* pToolTip) : CFWL_Timer(pToolTip) {} | |
554 | |
555 void IFWL_ScrollBar::Timer::Run(CFWL_TimerInfo* pTimerInfo) { | |
556 IFWL_ScrollBar* pButton = static_cast<IFWL_ScrollBar*>(m_pWidget); | |
557 | |
558 if (pButton->m_pTimerInfo) | |
559 pButton->m_pTimerInfo->StopTimer(); | |
560 | |
561 if (!pButton->SendEvent()) | |
562 pButton->m_pTimerInfo = StartTimer(0, true); | |
563 } | |
OLD | NEW |