Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(962)

Side by Side Diff: xfa/fwl/core/cfwl_scrollbar.cpp

Issue 2559173002: Move xfa/fwl/core to xfa/fwl. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fwl/core/cfwl_scrollbar.h ('k') | xfa/fwl/core/cfwl_spinbutton.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/cfwl_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 CFWL_ScrollBar::CFWL_ScrollBar(
26 const CFWL_App* app,
27 std::unique_ptr<CFWL_WidgetProperties> properties,
28 CFWL_Widget* pOuter)
29 : CFWL_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 CFWL_ScrollBar::~CFWL_ScrollBar() {}
60
61 FWL_Type CFWL_ScrollBar::GetClassID() const {
62 return FWL_Type::ScrollBar;
63 }
64
65 void CFWL_ScrollBar::Update() {
66 if (IsLocked())
67 return;
68 if (!m_pProperties->m_pThemeProvider)
69 m_pProperties->m_pThemeProvider = GetAvailableTheme();
70
71 Layout();
72 }
73
74 void CFWL_ScrollBar::DrawWidget(CFX_Graphics* pGraphics,
75 const CFX_Matrix* pMatrix) {
76 if (!pGraphics)
77 return;
78 if (!m_pProperties->m_pThemeProvider)
79 return;
80
81 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
82 if (HasBorder())
83 DrawBorder(pGraphics, CFWL_Part::Border, pTheme, pMatrix);
84 if (HasEdge())
85 DrawEdge(pGraphics, CFWL_Part::Edge, pTheme, pMatrix);
86 DrawTrack(pGraphics, pTheme, true, pMatrix);
87 DrawTrack(pGraphics, pTheme, false, pMatrix);
88 DrawArrowBtn(pGraphics, pTheme, true, pMatrix);
89 DrawArrowBtn(pGraphics, pTheme, false, pMatrix);
90 DrawThumb(pGraphics, pTheme, pMatrix);
91 }
92
93 void CFWL_ScrollBar::SetTrackPos(FX_FLOAT fTrackPos) {
94 m_fTrackPos = fTrackPos;
95 CalcThumbButtonRect(m_rtThumb);
96 CalcMinTrackRect(m_rtMinTrack);
97 CalcMaxTrackRect(m_rtMaxTrack);
98 }
99
100 bool CFWL_ScrollBar::DoScroll(CFWL_EvtScroll::Code dwCode, FX_FLOAT fPos) {
101 if (dwCode == CFWL_EvtScroll::Code::None)
102 return false;
103 return OnScroll(dwCode, fPos);
104 }
105
106 void CFWL_ScrollBar::DrawTrack(CFX_Graphics* pGraphics,
107 IFWL_ThemeProvider* pTheme,
108 bool bLower,
109 const CFX_Matrix* pMatrix) {
110 CFWL_ThemeBackground param;
111 param.m_pWidget = this;
112 param.m_iPart = bLower ? CFWL_Part::LowerTrack : CFWL_Part::UpperTrack;
113 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
114 ? CFWL_PartState_Disabled
115 : (bLower ? m_iMinTrackState : m_iMaxTrackState);
116 param.m_pGraphics = pGraphics;
117 param.m_matrix.Concat(*pMatrix);
118 param.m_rtPart = bLower ? m_rtMinTrack : m_rtMaxTrack;
119 pTheme->DrawBackground(&param);
120 }
121
122 void CFWL_ScrollBar::DrawArrowBtn(CFX_Graphics* pGraphics,
123 IFWL_ThemeProvider* pTheme,
124 bool bMinBtn,
125 const CFX_Matrix* pMatrix) {
126 CFWL_ThemeBackground param;
127 param.m_pWidget = this;
128 param.m_iPart = bMinBtn ? CFWL_Part::ForeArrow : CFWL_Part::BackArrow;
129 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
130 ? CFWL_PartState_Disabled
131 : (bMinBtn ? m_iMinButtonState : m_iMaxButtonState);
132 param.m_pGraphics = pGraphics;
133 param.m_matrix.Concat(*pMatrix);
134 param.m_rtPart = bMinBtn ? m_rtMinBtn : m_rtMaxBtn;
135 if (param.m_rtPart.height > 0 && param.m_rtPart.width > 0)
136 pTheme->DrawBackground(&param);
137 }
138
139 void CFWL_ScrollBar::DrawThumb(CFX_Graphics* pGraphics,
140 IFWL_ThemeProvider* pTheme,
141 const CFX_Matrix* pMatrix) {
142 CFWL_ThemeBackground param;
143 param.m_pWidget = this;
144 param.m_iPart = CFWL_Part::Thumb;
145 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
146 ? CFWL_PartState_Disabled
147 : m_iThumbButtonState;
148 param.m_pGraphics = pGraphics;
149 param.m_matrix.Concat(*pMatrix);
150 param.m_rtPart = m_rtThumb;
151 pTheme->DrawBackground(&param);
152 }
153
154 void CFWL_ScrollBar::Layout() {
155 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
156 CFWL_ThemePart part;
157 part.m_pWidget = this;
158 m_fMinThumb = *static_cast<FX_FLOAT*>(
159 pTheme->GetCapacity(&part, CFWL_WidgetCapacity::Size));
160 GetClientRect(m_rtClient);
161 CalcButtonLen();
162 CalcMinButtonRect(m_rtMinBtn);
163 CalcMaxButtonRect(m_rtMaxBtn);
164 CalcThumbButtonRect(m_rtThumb);
165 CalcMinTrackRect(m_rtMinTrack);
166 CalcMaxTrackRect(m_rtMaxTrack);
167 }
168
169 void CFWL_ScrollBar::CalcButtonLen() {
170 m_fButtonLen = IsVertical() ? m_rtClient.width : m_rtClient.height;
171 FX_FLOAT fLength = IsVertical() ? m_rtClient.height : m_rtClient.width;
172 if (fLength < m_fButtonLen * 2) {
173 m_fButtonLen = fLength / 2;
174 m_bMinSize = true;
175 } else {
176 m_bMinSize = false;
177 }
178 }
179
180 void CFWL_ScrollBar::CalcMinButtonRect(CFX_RectF& rect) {
181 rect.left = m_rtClient.left;
182 rect.top = m_rtClient.top;
183 rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen;
184 rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height;
185 }
186
187 void CFWL_ScrollBar::CalcMaxButtonRect(CFX_RectF& rect) {
188 rect.left =
189 IsVertical() ? m_rtClient.left : m_rtClient.right() - m_fButtonLen;
190 rect.top = IsVertical() ? m_rtClient.bottom() - m_fButtonLen : m_rtClient.top;
191 rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen;
192 rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height;
193 }
194
195 void CFWL_ScrollBar::CalcThumbButtonRect(CFX_RectF& rect) {
196 if (!IsEnabled()) {
197 m_rtThumb.Reset();
198 return;
199 }
200 if (m_bMinSize) {
201 m_rtThumb.Empty();
202 return;
203 }
204
205 FX_FLOAT fRange = m_fRangeMax - m_fRangeMin;
206 memset(&rect, 0, sizeof(CFX_Rect));
207 if (fRange < 0) {
208 if (IsVertical())
209 rect.Set(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width, 0);
210 else
211 rect.Set(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height);
212 return;
213 }
214
215 CFX_RectF rtClient = m_rtClient;
216 FX_FLOAT fLength = IsVertical() ? rtClient.height : rtClient.width;
217 FX_FLOAT fSize = m_fButtonLen;
218 fLength -= fSize * 2.0f;
219 if (fLength < fSize)
220 fLength = 0.0f;
221
222 FX_FLOAT fThumbSize = fLength * fLength / (fRange + fLength);
223 fThumbSize = std::max(fThumbSize, m_fMinThumb);
224
225 FX_FLOAT fDiff = std::max(fLength - fThumbSize, 0.0f);
226 FX_FLOAT fTrackPos =
227 std::max(std::min(m_fTrackPos, m_fRangeMax), m_fRangeMin);
228 if (!fRange)
229 return;
230
231 FX_FLOAT iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange;
232 rect.left = rtClient.left;
233 if (!IsVertical())
234 rect.left += iPos;
235
236 rect.top = rtClient.top;
237 if (IsVertical())
238 rect.top += iPos;
239
240 rect.width = IsVertical() ? rtClient.width : fThumbSize;
241 rect.height = IsVertical() ? fThumbSize : rtClient.height;
242 }
243
244 void CFWL_ScrollBar::CalcMinTrackRect(CFX_RectF& rect) {
245 if (m_bMinSize) {
246 rect.Empty();
247 return;
248 }
249
250 FX_FLOAT fBottom = m_rtThumb.bottom();
251 FX_FLOAT fRight = m_rtThumb.right();
252 FX_FLOAT ix = (m_rtThumb.left + fRight) / 2;
253 FX_FLOAT iy = (m_rtThumb.top + fBottom) / 2;
254 rect.left = m_rtClient.left;
255 rect.top = m_rtClient.top;
256 bool bVertical = IsVertical();
257 rect.width = bVertical ? m_rtClient.width : ix;
258 rect.height = bVertical ? iy : m_rtClient.height;
259 }
260
261 void CFWL_ScrollBar::CalcMaxTrackRect(CFX_RectF& rect) {
262 if (m_bMinSize) {
263 rect.Empty();
264 return;
265 }
266
267 FX_FLOAT ix = (m_rtThumb.left + m_rtThumb.right()) / 2;
268 FX_FLOAT iy = (m_rtThumb.top + m_rtThumb.bottom()) / 2;
269 bool bVertical = IsVertical();
270 rect.left = bVertical ? m_rtClient.left : ix;
271 rect.top = bVertical ? iy : m_rtClient.top;
272 rect.width = bVertical ? m_rtClient.width : m_rtClient.right() - ix;
273 rect.height = bVertical ? m_rtClient.bottom() - iy : m_rtClient.height;
274 }
275
276 FX_FLOAT CFWL_ScrollBar::GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy) {
277 FX_FLOAT fDiffX = fx - m_cpTrackPointX;
278 FX_FLOAT fDiffY = fy - m_cpTrackPointY;
279 FX_FLOAT fRange = m_fRangeMax - m_fRangeMin;
280 FX_FLOAT fPos;
281
282 if (IsVertical()) {
283 fPos = fRange * fDiffY /
284 (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height);
285 } else {
286 fPos = fRange * fDiffX /
287 (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width);
288 }
289
290 fPos += m_fLastTrackPos;
291 return std::min(std::max(fPos, m_fRangeMin), m_fRangeMax);
292 }
293
294 bool CFWL_ScrollBar::SendEvent() {
295 if (m_iMinButtonState == CFWL_PartState_Pressed) {
296 DoScroll(CFWL_EvtScroll::Code::StepBackward, m_fTrackPos);
297 return false;
298 }
299 if (m_iMaxButtonState == CFWL_PartState_Pressed) {
300 DoScroll(CFWL_EvtScroll::Code::StepForward, m_fTrackPos);
301 return false;
302 }
303 if (m_iMinTrackState == CFWL_PartState_Pressed) {
304 DoScroll(CFWL_EvtScroll::Code::PageBackward, m_fTrackPos);
305 return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY);
306 }
307 if (m_iMaxTrackState == CFWL_PartState_Pressed) {
308 DoScroll(CFWL_EvtScroll::Code::PageForward, m_fTrackPos);
309 return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY);
310 }
311 if (m_iMouseWheel) {
312 CFWL_EvtScroll::Code dwCode = m_iMouseWheel < 0
313 ? CFWL_EvtScroll::Code::StepForward
314 : CFWL_EvtScroll::Code::StepBackward;
315 DoScroll(dwCode, m_fTrackPos);
316 }
317 return true;
318 }
319
320 bool CFWL_ScrollBar::OnScroll(CFWL_EvtScroll::Code dwCode, FX_FLOAT fPos) {
321 CFWL_EvtScroll ev(this);
322 ev.m_iScrollCode = dwCode;
323 ev.m_fPos = fPos;
324 DispatchEvent(&ev);
325 return true;
326 }
327
328 void CFWL_ScrollBar::OnProcessMessage(CFWL_Message* pMessage) {
329 if (!pMessage)
330 return;
331
332 CFWL_Message::Type type = pMessage->GetType();
333 if (type == CFWL_Message::Type::Mouse) {
334 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
335 switch (pMsg->m_dwCmd) {
336 case FWL_MouseCommand::LeftButtonDown:
337 OnLButtonDown(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
338 break;
339 case FWL_MouseCommand::LeftButtonUp:
340 OnLButtonUp(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
341 break;
342 case FWL_MouseCommand::Move:
343 OnMouseMove(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
344 break;
345 case FWL_MouseCommand::Leave:
346 OnMouseLeave();
347 break;
348 default:
349 break;
350 }
351 } else if (type == CFWL_Message::Type::MouseWheel) {
352 CFWL_MsgMouseWheel* pMsg = static_cast<CFWL_MsgMouseWheel*>(pMessage);
353 OnMouseWheel(pMsg->m_fx, pMsg->m_fy, pMsg->m_dwFlags, pMsg->m_fDeltaX,
354 pMsg->m_fDeltaY);
355 }
356 }
357
358 void CFWL_ScrollBar::OnDrawWidget(CFX_Graphics* pGraphics,
359 const CFX_Matrix* pMatrix) {
360 DrawWidget(pGraphics, pMatrix);
361 }
362
363 void CFWL_ScrollBar::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
364 if (!IsEnabled())
365 return;
366
367 m_bMouseDown = true;
368 SetGrab(true);
369 m_cpTrackPointX = fx;
370 m_cpTrackPointY = fy;
371 m_fLastTrackPos = m_fTrackPos;
372 if (m_rtMinBtn.Contains(fx, fy))
373 DoMouseDown(0, m_rtMinBtn, m_iMinButtonState, fx, fy);
374 else if (m_rtThumb.Contains(fx, fy))
375 DoMouseDown(1, m_rtThumb, m_iThumbButtonState, fx, fy);
376 else if (m_rtMaxBtn.Contains(fx, fy))
377 DoMouseDown(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy);
378 else if (m_rtMinTrack.Contains(fx, fy))
379 DoMouseDown(3, m_rtMinTrack, m_iMinTrackState, fx, fy);
380 else
381 DoMouseDown(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy);
382
383 if (!SendEvent())
384 m_pTimerInfo = m_Timer.StartTimer(FWL_SCROLLBAR_Elapse, true);
385 }
386
387 void CFWL_ScrollBar::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
388 m_pTimerInfo->StopTimer();
389 m_bMouseDown = false;
390 DoMouseUp(0, m_rtMinBtn, m_iMinButtonState, fx, fy);
391 DoMouseUp(1, m_rtThumb, m_iThumbButtonState, fx, fy);
392 DoMouseUp(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy);
393 DoMouseUp(3, m_rtMinTrack, m_iMinTrackState, fx, fy);
394 DoMouseUp(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy);
395 SetGrab(false);
396 }
397
398 void CFWL_ScrollBar::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
399 DoMouseMove(0, m_rtMinBtn, m_iMinButtonState, fx, fy);
400 DoMouseMove(1, m_rtThumb, m_iThumbButtonState, fx, fy);
401 DoMouseMove(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy);
402 DoMouseMove(3, m_rtMinTrack, m_iMinTrackState, fx, fy);
403 DoMouseMove(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy);
404 }
405
406 void CFWL_ScrollBar::OnMouseLeave() {
407 DoMouseLeave(0, m_rtMinBtn, m_iMinButtonState);
408 DoMouseLeave(1, m_rtThumb, m_iThumbButtonState);
409 DoMouseLeave(2, m_rtMaxBtn, m_iMaxButtonState);
410 DoMouseLeave(3, m_rtMinTrack, m_iMinTrackState);
411 DoMouseLeave(4, m_rtMaxTrack, m_iMaxTrackState);
412 }
413
414 void CFWL_ScrollBar::OnMouseWheel(FX_FLOAT fx,
415 FX_FLOAT fy,
416 uint32_t dwFlags,
417 FX_FLOAT fDeltaX,
418 FX_FLOAT fDeltaY) {
419 m_iMouseWheel = (int32_t)fDeltaX;
420 SendEvent();
421 m_iMouseWheel = 0;
422 }
423
424 void CFWL_ScrollBar::DoMouseDown(int32_t iItem,
425 const CFX_RectF& rtItem,
426 int32_t& iState,
427 FX_FLOAT fx,
428 FX_FLOAT fy) {
429 if (!rtItem.Contains(fx, fy))
430 return;
431 if (iState == CFWL_PartState_Pressed)
432 return;
433
434 iState = CFWL_PartState_Pressed;
435 Repaint(&rtItem);
436 }
437
438 void CFWL_ScrollBar::DoMouseUp(int32_t iItem,
439 const CFX_RectF& rtItem,
440 int32_t& iState,
441 FX_FLOAT fx,
442 FX_FLOAT fy) {
443 int32_t iNewState =
444 rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered : CFWL_PartState_Normal;
445 if (iState == iNewState)
446 return;
447
448 iState = iNewState;
449 Repaint(&rtItem);
450 OnScroll(CFWL_EvtScroll::Code::EndScroll, m_fTrackPos);
451 }
452
453 void CFWL_ScrollBar::DoMouseMove(int32_t iItem,
454 const CFX_RectF& rtItem,
455 int32_t& iState,
456 FX_FLOAT fx,
457 FX_FLOAT fy) {
458 if (!m_bMouseDown) {
459 int32_t iNewState = rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered
460 : CFWL_PartState_Normal;
461 if (iState == iNewState)
462 return;
463
464 iState = iNewState;
465 Repaint(&rtItem);
466 } else if ((2 == iItem) && (m_iThumbButtonState == CFWL_PartState_Pressed)) {
467 FX_FLOAT fPos = GetTrackPointPos(fx, fy);
468 m_fTrackPos = fPos;
469 OnScroll(CFWL_EvtScroll::Code::TrackPos, fPos);
470 }
471 }
472
473 void CFWL_ScrollBar::DoMouseLeave(int32_t iItem,
474 const CFX_RectF& rtItem,
475 int32_t& iState) {
476 if (iState == CFWL_PartState_Normal)
477 return;
478
479 iState = CFWL_PartState_Normal;
480 Repaint(&rtItem);
481 }
482
483 void CFWL_ScrollBar::DoMouseHover(int32_t iItem,
484 const CFX_RectF& rtItem,
485 int32_t& iState) {
486 if (iState == CFWL_PartState_Hovered)
487 return;
488
489 iState = CFWL_PartState_Hovered;
490 Repaint(&rtItem);
491 }
492
493 CFWL_ScrollBar::Timer::Timer(CFWL_ScrollBar* pToolTip) : CFWL_Timer(pToolTip) {}
494
495 void CFWL_ScrollBar::Timer::Run(CFWL_TimerInfo* pTimerInfo) {
496 CFWL_ScrollBar* pButton = static_cast<CFWL_ScrollBar*>(m_pWidget);
497
498 if (pButton->m_pTimerInfo)
499 pButton->m_pTimerInfo->StopTimer();
500
501 if (!pButton->SendEvent())
502 pButton->m_pTimerInfo = StartTimer(0, true);
503 }
OLDNEW
« no previous file with comments | « xfa/fwl/core/cfwl_scrollbar.h ('k') | xfa/fwl/core/cfwl_spinbutton.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698