blob: 36dd9e567e89431ef18852ae2dce325a2be150bb [file] [log] [blame]
kumarashishg826308d2023-06-23 13:21:22 +00001// Copyright 2014 The PDFium Authors
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -07002// 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/cfwl_scrollbar.h"
8
9#include <algorithm>
10#include <memory>
11#include <utility>
12
kumarashishg826308d2023-06-23 13:21:22 +000013#include "third_party/base/cxx17_backports.h"
Haibo Huang49cc9302020-04-27 16:14:24 -070014#include "xfa/fwl/cfwl_app.h"
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070015#include "xfa/fwl/cfwl_messagemouse.h"
16#include "xfa/fwl/cfwl_messagemousewheel.h"
17#include "xfa/fwl/cfwl_notedriver.h"
18#include "xfa/fwl/cfwl_themebackground.h"
19#include "xfa/fwl/cfwl_themepart.h"
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070020#include "xfa/fwl/ifwl_themeprovider.h"
21
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070022namespace {
23
kumarashishg826308d2023-06-23 13:21:22 +000024constexpr int kScrollbarElapsedMsecs = 500;
25constexpr float kMinThumbSize = 5.0f;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070026
27} // namespace
28
kumarashishg826308d2023-06-23 13:21:22 +000029CFWL_ScrollBar::CFWL_ScrollBar(CFWL_App* app,
30 const Properties& properties,
31 CFWL_Widget* pOuter)
32 : CFWL_Widget(app, properties, pOuter) {}
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070033
Haibo Huang49cc9302020-04-27 16:14:24 -070034CFWL_ScrollBar::~CFWL_ScrollBar() = default;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070035
36FWL_Type CFWL_ScrollBar::GetClassID() const {
37 return FWL_Type::ScrollBar;
38}
39
40void CFWL_ScrollBar::Update() {
41 if (IsLocked())
42 return;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070043
44 Layout();
45}
46
kumarashishg826308d2023-06-23 13:21:22 +000047void CFWL_ScrollBar::DrawWidget(CFGAS_GEGraphics* pGraphics,
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070048 const CFX_Matrix& matrix) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070049 if (!pGraphics)
50 return;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070051
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070052 if (HasBorder())
kumarashishg826308d2023-06-23 13:21:22 +000053 DrawBorder(pGraphics, CFWL_ThemePart::Part::kBorder, matrix);
54
55 DrawLowerTrack(pGraphics, matrix);
56 DrawUpperTrack(pGraphics, matrix);
57 DrawMinArrowBtn(pGraphics, matrix);
58 DrawMaxArrowBtn(pGraphics, matrix);
59 DrawThumb(pGraphics, matrix);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070060}
61
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070062void CFWL_ScrollBar::SetTrackPos(float fTrackPos) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070063 m_fTrackPos = fTrackPos;
kumarashishg826308d2023-06-23 13:21:22 +000064 m_ThumbRect = CalcThumbButtonRect(m_ThumbRect);
65 m_MinTrackRect = CalcMinTrackRect(m_MinTrackRect);
66 m_MaxTrackRect = CalcMaxTrackRect(m_MaxTrackRect);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070067}
68
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -070069bool CFWL_ScrollBar::DoScroll(CFWL_EventScroll::Code dwCode, float fPos) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070070 if (dwCode == CFWL_EventScroll::Code::None)
71 return false;
72 return OnScroll(dwCode, fPos);
73}
74
kumarashishg826308d2023-06-23 13:21:22 +000075void CFWL_ScrollBar::DrawUpperTrack(CFGAS_GEGraphics* pGraphics,
76 const CFX_Matrix& mtMatrix) {
77 CFWL_ThemeBackground param(CFWL_ThemePart::Part::kUpperTrack, this,
78 pGraphics);
79 param.m_dwStates = (m_Properties.m_dwStates & FWL_STATE_WGT_Disabled)
80 ? CFWL_PartState::kDisabled
81 : m_iMaxTrackState;
82 param.m_matrix = mtMatrix;
83 param.m_PartRect = m_MaxTrackRect;
84 GetThemeProvider()->DrawBackground(param);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070085}
86
kumarashishg826308d2023-06-23 13:21:22 +000087void CFWL_ScrollBar::DrawLowerTrack(CFGAS_GEGraphics* pGraphics,
88 const CFX_Matrix& mtMatrix) {
89 CFWL_ThemeBackground param(CFWL_ThemePart::Part::kLowerTrack, this,
90 pGraphics);
91 param.m_dwStates = (m_Properties.m_dwStates & FWL_STATE_WGT_Disabled)
92 ? CFWL_PartState::kDisabled
93 : m_iMinTrackState;
94 param.m_matrix = mtMatrix;
95 param.m_PartRect = m_MinTrackRect;
96 GetThemeProvider()->DrawBackground(param);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -070097}
98
kumarashishg826308d2023-06-23 13:21:22 +000099void CFWL_ScrollBar::DrawMaxArrowBtn(CFGAS_GEGraphics* pGraphics,
100 const CFX_Matrix& mtMatrix) {
101 CFWL_ThemeBackground param(CFWL_ThemePart::Part::kBackArrow, this, pGraphics);
102 param.m_dwStates = (m_Properties.m_dwStates & FWL_STATE_WGT_Disabled)
103 ? CFWL_PartState::kDisabled
104 : m_iMaxButtonState;
105 param.m_matrix = mtMatrix;
106 param.m_PartRect = m_MaxBtnRect;
107 if (param.m_PartRect.height > 0 && param.m_PartRect.width > 0)
108 GetThemeProvider()->DrawBackground(param);
109}
110
111void CFWL_ScrollBar::DrawMinArrowBtn(CFGAS_GEGraphics* pGraphics,
112 const CFX_Matrix& mtMatrix) {
113 CFWL_ThemeBackground param(CFWL_ThemePart::Part::kForeArrow, this, pGraphics);
114 param.m_dwStates = (m_Properties.m_dwStates & FWL_STATE_WGT_Disabled)
115 ? CFWL_PartState::kDisabled
116 : m_iMinButtonState;
117 param.m_matrix = mtMatrix;
118 param.m_PartRect = m_MinBtnRect;
119 if (param.m_PartRect.height > 0 && param.m_PartRect.width > 0)
120 GetThemeProvider()->DrawBackground(param);
121}
122
123void CFWL_ScrollBar::DrawThumb(CFGAS_GEGraphics* pGraphics,
124 const CFX_Matrix& mtMatrix) {
125 CFWL_ThemeBackground param(CFWL_ThemePart::Part::kThumb, this, pGraphics);
126 param.m_dwStates = (m_Properties.m_dwStates & FWL_STATE_WGT_Disabled)
127 ? CFWL_PartState::kDisabled
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700128 : m_iThumbButtonState;
kumarashishg826308d2023-06-23 13:21:22 +0000129 param.m_matrix = mtMatrix;
130 param.m_PartRect = m_ThumbRect;
131 GetThemeProvider()->DrawBackground(param);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700132}
133
134void CFWL_ScrollBar::Layout() {
kumarashishg826308d2023-06-23 13:21:22 +0000135 m_ClientRect = GetClientRect();
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700136
137 CalcButtonLen();
kumarashishg826308d2023-06-23 13:21:22 +0000138 m_MinBtnRect = CalcMinButtonRect();
139 m_MaxBtnRect = CalcMaxButtonRect();
140 m_ThumbRect = CalcThumbButtonRect(m_ThumbRect);
141 m_MinTrackRect = CalcMinTrackRect(m_MinTrackRect);
142 m_MaxTrackRect = CalcMaxTrackRect(m_MaxTrackRect);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700143}
144
145void CFWL_ScrollBar::CalcButtonLen() {
kumarashishg826308d2023-06-23 13:21:22 +0000146 m_fButtonLen = IsVertical() ? m_ClientRect.width : m_ClientRect.height;
147 float fLength = IsVertical() ? m_ClientRect.height : m_ClientRect.width;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700148 if (fLength < m_fButtonLen * 2) {
149 m_fButtonLen = fLength / 2;
150 m_bMinSize = true;
151 } else {
152 m_bMinSize = false;
153 }
154}
155
156CFX_RectF CFWL_ScrollBar::CalcMinButtonRect() {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700157 if (IsVertical())
kumarashishg826308d2023-06-23 13:21:22 +0000158 return CFX_RectF(m_ClientRect.TopLeft(), m_ClientRect.width, m_fButtonLen);
159 return CFX_RectF(m_ClientRect.TopLeft(), m_fButtonLen, m_ClientRect.height);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700160}
161
162CFX_RectF CFWL_ScrollBar::CalcMaxButtonRect() {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700163 if (IsVertical()) {
kumarashishg826308d2023-06-23 13:21:22 +0000164 return CFX_RectF(m_ClientRect.left, m_ClientRect.bottom() - m_fButtonLen,
165 m_ClientRect.width, m_fButtonLen);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700166 }
kumarashishg826308d2023-06-23 13:21:22 +0000167 return CFX_RectF(m_ClientRect.right() - m_fButtonLen, m_ClientRect.top,
168 m_fButtonLen, m_ClientRect.height);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700169}
170
171CFX_RectF CFWL_ScrollBar::CalcThumbButtonRect(const CFX_RectF& rtThumb) {
172 CFX_RectF rect;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700173 if (!IsEnabled())
174 return rect;
175
176 if (m_bMinSize) {
177 rect.left = rtThumb.left;
178 rect.top = rtThumb.top;
179 return rect;
180 }
181
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700182 float fRange = m_fRangeMax - m_fRangeMin;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700183 if (fRange < 0) {
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700184 if (IsVertical()) {
kumarashishg826308d2023-06-23 13:21:22 +0000185 return CFX_RectF(m_ClientRect.left, m_MaxBtnRect.bottom(),
186 m_ClientRect.width, 0);
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700187 }
kumarashishg826308d2023-06-23 13:21:22 +0000188 return CFX_RectF(m_MaxBtnRect.right(), m_ClientRect.top, 0,
189 m_ClientRect.height);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700190 }
191
kumarashishg826308d2023-06-23 13:21:22 +0000192 CFX_RectF rtClient = m_ClientRect;
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700193 float fLength = IsVertical() ? rtClient.height : rtClient.width;
194 float fSize = m_fButtonLen;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700195 fLength -= fSize * 2.0f;
196 if (fLength < fSize)
197 fLength = 0.0f;
198
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700199 float fThumbSize = fLength * fLength / (fRange + fLength);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700200 fThumbSize = std::max(fThumbSize, kMinThumbSize);
201
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700202 float fDiff = std::max(fLength - fThumbSize, 0.0f);
203 float fTrackPos = pdfium::clamp(m_fTrackPos, m_fRangeMin, m_fRangeMax);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700204 if (!fRange)
205 return rect;
206
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700207 float iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700208 rect.left = rtClient.left;
209 rect.top = rtClient.top;
210 if (IsVertical()) {
211 rect.top += iPos;
212 rect.width = rtClient.width;
213 rect.height = fThumbSize;
214 } else {
215 rect.left += iPos;
216 rect.width = fThumbSize;
217 rect.height = rtClient.height;
218 }
219 return rect;
220}
221
222CFX_RectF CFWL_ScrollBar::CalcMinTrackRect(const CFX_RectF& rtMinRect) {
223 CFX_RectF rect;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700224 if (m_bMinSize) {
225 rect.left = rtMinRect.left;
226 rect.top = rtMinRect.top;
227 return rect;
228 }
229
kumarashishg826308d2023-06-23 13:21:22 +0000230 rect.left = m_ClientRect.left;
231 rect.top = m_ClientRect.top;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700232 if (IsVertical()) {
kumarashishg826308d2023-06-23 13:21:22 +0000233 rect.width = m_ClientRect.width;
234 rect.height = (m_ThumbRect.top + m_ThumbRect.bottom()) / 2;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700235 } else {
kumarashishg826308d2023-06-23 13:21:22 +0000236 rect.width = (m_ThumbRect.left + m_ThumbRect.right()) / 2;
237 rect.height = m_ClientRect.height;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700238 }
239 return rect;
240}
241
242CFX_RectF CFWL_ScrollBar::CalcMaxTrackRect(const CFX_RectF& rtMaxRect) {
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700243 if (m_bMinSize)
244 return CFX_RectF(rtMaxRect.TopLeft(), 0, 0);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700245
246 if (IsVertical()) {
kumarashishg826308d2023-06-23 13:21:22 +0000247 float iy = (m_ThumbRect.top + m_ThumbRect.bottom()) / 2;
248 return CFX_RectF(m_ClientRect.left, iy, m_ClientRect.width,
249 m_ClientRect.bottom() - iy);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700250 }
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700251
kumarashishg826308d2023-06-23 13:21:22 +0000252 float ix = (m_ThumbRect.left + m_ThumbRect.right()) / 2;
253 return CFX_RectF(ix, m_ClientRect.top, m_ClientRect.height - ix,
254 m_ClientRect.height);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700255}
256
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700257float CFWL_ScrollBar::GetTrackPointPos(const CFX_PointF& point) {
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700258 CFX_PointF diff = point - m_cpTrackPoint;
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700259 float fRange = m_fRangeMax - m_fRangeMin;
260 float fPos;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700261
262 if (IsVertical()) {
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700263 fPos = fRange * diff.y /
kumarashishg826308d2023-06-23 13:21:22 +0000264 (m_MaxBtnRect.top - m_MinBtnRect.bottom() - m_ThumbRect.height);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700265 } else {
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700266 fPos = fRange * diff.x /
kumarashishg826308d2023-06-23 13:21:22 +0000267 (m_MaxBtnRect.left - m_MinBtnRect.right() - m_ThumbRect.width);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700268 }
269
270 fPos += m_fLastTrackPos;
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700271 return pdfium::clamp(fPos, m_fRangeMin, m_fRangeMax);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700272}
273
274bool CFWL_ScrollBar::SendEvent() {
kumarashishg826308d2023-06-23 13:21:22 +0000275 if (m_iMinButtonState == CFWL_PartState::kPressed) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700276 DoScroll(CFWL_EventScroll::Code::StepBackward, m_fTrackPos);
277 return false;
278 }
kumarashishg826308d2023-06-23 13:21:22 +0000279 if (m_iMaxButtonState == CFWL_PartState::kPressed) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700280 DoScroll(CFWL_EventScroll::Code::StepForward, m_fTrackPos);
281 return false;
282 }
kumarashishg826308d2023-06-23 13:21:22 +0000283 if (m_iMinTrackState == CFWL_PartState::kPressed) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700284 DoScroll(CFWL_EventScroll::Code::PageBackward, m_fTrackPos);
kumarashishg826308d2023-06-23 13:21:22 +0000285 return m_ThumbRect.Contains(m_cpTrackPoint);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700286 }
kumarashishg826308d2023-06-23 13:21:22 +0000287 if (m_iMaxTrackState == CFWL_PartState::kPressed) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700288 DoScroll(CFWL_EventScroll::Code::PageForward, m_fTrackPos);
kumarashishg826308d2023-06-23 13:21:22 +0000289 return m_ThumbRect.Contains(m_cpTrackPoint);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700290 }
291 if (m_iMouseWheel) {
292 CFWL_EventScroll::Code dwCode = m_iMouseWheel < 0
293 ? CFWL_EventScroll::Code::StepForward
294 : CFWL_EventScroll::Code::StepBackward;
295 DoScroll(dwCode, m_fTrackPos);
296 }
297 return true;
298}
299
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700300bool CFWL_ScrollBar::OnScroll(CFWL_EventScroll::Code dwCode, float fPos) {
kumarashishg826308d2023-06-23 13:21:22 +0000301 CFWL_EventScroll ev(this, dwCode, fPos);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700302 DispatchEvent(&ev);
303 return true;
304}
305
306void CFWL_ScrollBar::OnProcessMessage(CFWL_Message* pMessage) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700307 CFWL_Message::Type type = pMessage->GetType();
kumarashishg826308d2023-06-23 13:21:22 +0000308 if (type == CFWL_Message::Type::kMouse) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700309 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
310 switch (pMsg->m_dwCmd) {
kumarashishg826308d2023-06-23 13:21:22 +0000311 case CFWL_MessageMouse::MouseCommand::kLeftButtonDown:
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700312 OnLButtonDown(pMsg->m_pos);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700313 break;
kumarashishg826308d2023-06-23 13:21:22 +0000314 case CFWL_MessageMouse::MouseCommand::kLeftButtonUp:
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700315 OnLButtonUp(pMsg->m_pos);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700316 break;
kumarashishg826308d2023-06-23 13:21:22 +0000317 case CFWL_MessageMouse::MouseCommand::kMove:
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700318 OnMouseMove(pMsg->m_pos);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700319 break;
kumarashishg826308d2023-06-23 13:21:22 +0000320 case CFWL_MessageMouse::MouseCommand::kLeave:
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700321 OnMouseLeave();
322 break;
323 default:
324 break;
325 }
kumarashishg826308d2023-06-23 13:21:22 +0000326 } else if (type == CFWL_Message::Type::kMouseWheel) {
327 auto* pMsg = static_cast<CFWL_MessageMouseWheel*>(pMessage);
328 OnMouseWheel(pMsg->delta());
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700329 }
330}
331
kumarashishg826308d2023-06-23 13:21:22 +0000332void CFWL_ScrollBar::OnDrawWidget(CFGAS_GEGraphics* pGraphics,
Philip P. Moltmannd904c1e2018-03-19 09:26:45 -0700333 const CFX_Matrix& matrix) {
334 DrawWidget(pGraphics, matrix);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700335}
336
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700337void CFWL_ScrollBar::OnLButtonDown(const CFX_PointF& point) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700338 if (!IsEnabled())
339 return;
340
341 m_bMouseDown = true;
342 SetGrab(true);
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700343
344 m_cpTrackPoint = point;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700345 m_fLastTrackPos = m_fTrackPos;
kumarashishg826308d2023-06-23 13:21:22 +0000346 if (m_MinBtnRect.Contains(point))
347 DoMouseDown(0, m_MinBtnRect, &m_iMinButtonState, point);
348 else if (m_ThumbRect.Contains(point))
349 DoMouseDown(1, m_ThumbRect, &m_iThumbButtonState, point);
350 else if (m_MaxBtnRect.Contains(point))
351 DoMouseDown(2, m_MaxBtnRect, &m_iMaxButtonState, point);
352 else if (m_MinTrackRect.Contains(point))
353 DoMouseDown(3, m_MinTrackRect, &m_iMinTrackState, point);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700354 else
kumarashishg826308d2023-06-23 13:21:22 +0000355 DoMouseDown(4, m_MaxTrackRect, &m_iMaxTrackState, point);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700356
Haibo Huang49cc9302020-04-27 16:14:24 -0700357 if (!SendEvent()) {
kumarashishg826308d2023-06-23 13:21:22 +0000358 m_pTimer = std::make_unique<CFX_Timer>(GetFWLApp()->GetTimerHandler(), this,
359 kScrollbarElapsedMsecs);
Haibo Huang49cc9302020-04-27 16:14:24 -0700360 }
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700361}
362
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700363void CFWL_ScrollBar::OnLButtonUp(const CFX_PointF& point) {
Haibo Huang49cc9302020-04-27 16:14:24 -0700364 m_pTimer.reset();
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700365 m_bMouseDown = false;
kumarashishg826308d2023-06-23 13:21:22 +0000366 DoMouseUp(0, m_MinBtnRect, &m_iMinButtonState, point);
367 DoMouseUp(1, m_ThumbRect, &m_iThumbButtonState, point);
368 DoMouseUp(2, m_MaxBtnRect, &m_iMaxButtonState, point);
369 DoMouseUp(3, m_MinTrackRect, &m_iMinTrackState, point);
370 DoMouseUp(4, m_MaxTrackRect, &m_iMaxTrackState, point);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700371 SetGrab(false);
372}
373
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700374void CFWL_ScrollBar::OnMouseMove(const CFX_PointF& point) {
kumarashishg826308d2023-06-23 13:21:22 +0000375 DoMouseMove(0, m_MinBtnRect, &m_iMinButtonState, point);
376 DoMouseMove(1, m_ThumbRect, &m_iThumbButtonState, point);
377 DoMouseMove(2, m_MaxBtnRect, &m_iMaxButtonState, point);
378 DoMouseMove(3, m_MinTrackRect, &m_iMinTrackState, point);
379 DoMouseMove(4, m_MaxTrackRect, &m_iMaxTrackState, point);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700380}
381
382void CFWL_ScrollBar::OnMouseLeave() {
kumarashishg826308d2023-06-23 13:21:22 +0000383 DoMouseLeave(0, m_MinBtnRect, &m_iMinButtonState);
384 DoMouseLeave(1, m_ThumbRect, &m_iThumbButtonState);
385 DoMouseLeave(2, m_MaxBtnRect, &m_iMaxButtonState);
386 DoMouseLeave(3, m_MinTrackRect, &m_iMinTrackState);
387 DoMouseLeave(4, m_MaxTrackRect, &m_iMaxTrackState);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700388}
389
kumarashishg826308d2023-06-23 13:21:22 +0000390void CFWL_ScrollBar::OnMouseWheel(const CFX_Vector& delta) {
391 m_iMouseWheel = delta.y;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700392 SendEvent();
393 m_iMouseWheel = 0;
394}
395
396void CFWL_ScrollBar::DoMouseDown(int32_t iItem,
397 const CFX_RectF& rtItem,
kumarashishg826308d2023-06-23 13:21:22 +0000398 CFWL_PartState* pState,
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700399 const CFX_PointF& point) {
400 if (!rtItem.Contains(point))
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700401 return;
kumarashishg826308d2023-06-23 13:21:22 +0000402 if (*pState == CFWL_PartState::kPressed)
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700403 return;
404
kumarashishg826308d2023-06-23 13:21:22 +0000405 *pState = CFWL_PartState::kPressed;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700406 RepaintRect(rtItem);
407}
408
409void CFWL_ScrollBar::DoMouseUp(int32_t iItem,
410 const CFX_RectF& rtItem,
kumarashishg826308d2023-06-23 13:21:22 +0000411 CFWL_PartState* pState,
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700412 const CFX_PointF& point) {
kumarashishg826308d2023-06-23 13:21:22 +0000413 CFWL_PartState iNewState = rtItem.Contains(point) ? CFWL_PartState::kHovered
414 : CFWL_PartState::kNormal;
415 if (*pState == iNewState)
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700416 return;
417
kumarashishg826308d2023-06-23 13:21:22 +0000418 *pState = iNewState;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700419 RepaintRect(rtItem);
420 OnScroll(CFWL_EventScroll::Code::EndScroll, m_fTrackPos);
421}
422
423void CFWL_ScrollBar::DoMouseMove(int32_t iItem,
424 const CFX_RectF& rtItem,
kumarashishg826308d2023-06-23 13:21:22 +0000425 CFWL_PartState* pState,
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700426 const CFX_PointF& point) {
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700427 if (!m_bMouseDown) {
kumarashishg826308d2023-06-23 13:21:22 +0000428 CFWL_PartState iNewState = rtItem.Contains(point) ? CFWL_PartState::kHovered
429 : CFWL_PartState::kNormal;
430 if (*pState == iNewState)
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700431 return;
432
kumarashishg826308d2023-06-23 13:21:22 +0000433 *pState = iNewState;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700434 RepaintRect(rtItem);
kumarashishg826308d2023-06-23 13:21:22 +0000435 } else if ((2 == iItem) &&
436 (m_iThumbButtonState == CFWL_PartState::kPressed)) {
Philip P. Moltmann33357ca2017-05-11 09:25:13 -0700437 m_fTrackPos = GetTrackPointPos(point);
438 OnScroll(CFWL_EventScroll::Code::TrackPos, m_fTrackPos);
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700439 }
440}
441
442void CFWL_ScrollBar::DoMouseLeave(int32_t iItem,
443 const CFX_RectF& rtItem,
kumarashishg826308d2023-06-23 13:21:22 +0000444 CFWL_PartState* pState) {
445 if (*pState == CFWL_PartState::kNormal)
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700446 return;
447
kumarashishg826308d2023-06-23 13:21:22 +0000448 *pState = CFWL_PartState::kNormal;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700449 RepaintRect(rtItem);
450}
451
452void CFWL_ScrollBar::DoMouseHover(int32_t iItem,
453 const CFX_RectF& rtItem,
kumarashishg826308d2023-06-23 13:21:22 +0000454 CFWL_PartState* pState) {
455 if (*pState == CFWL_PartState::kHovered)
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700456 return;
457
kumarashishg826308d2023-06-23 13:21:22 +0000458 *pState = CFWL_PartState::kHovered;
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700459 RepaintRect(rtItem);
460}
461
Haibo Huang49cc9302020-04-27 16:14:24 -0700462void CFWL_ScrollBar::OnTimerFired() {
463 m_pTimer.reset();
464 if (!SendEvent()) {
kumarashishg826308d2023-06-23 13:21:22 +0000465 m_pTimer =
466 std::make_unique<CFX_Timer>(GetFWLApp()->GetTimerHandler(), this, 0);
Haibo Huang49cc9302020-04-27 16:14:24 -0700467 }
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -0700468}