blob: acc144f3611b7bbcfb65310554feb5848b874cb3 [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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
dsinclair447b1f32016-12-08 10:06:32 -08007#include "xfa/fwl/cfwl_scrollbar.h"
Dan Sinclair1770c022016-03-14 14:14:16 -04008
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05009#include <algorithm>
10#include <memory>
11#include <utility>
12
Tom Sepez3e5e563e2019-08-12 17:54:25 +000013#include "third_party/base/ptr_util.h"
Lei Zhang85f019a2017-03-17 15:14:19 -070014#include "third_party/base/stl_util.h"
Tom Sepez3e5e563e2019-08-12 17:54:25 +000015#include "xfa/fwl/cfwl_app.h"
dsinclair447b1f32016-12-08 10:06:32 -080016#include "xfa/fwl/cfwl_messagemouse.h"
17#include "xfa/fwl/cfwl_messagemousewheel.h"
18#include "xfa/fwl/cfwl_notedriver.h"
19#include "xfa/fwl/cfwl_themebackground.h"
20#include "xfa/fwl/cfwl_themepart.h"
dsinclair447b1f32016-12-08 10:06:32 -080021#include "xfa/fwl/ifwl_themeprovider.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040022
23#define FWL_SCROLLBAR_Elapse 500
Dan Sinclairc635c932017-01-03 15:46:55 -050024
25namespace {
26
27const float kMinThumbSize = 5.0f;
28
29} // namespace
Dan Sinclair1770c022016-03-14 14:14:16 -040030
dsinclair0ce11ee2016-11-23 16:03:10 -080031CFWL_ScrollBar::CFWL_ScrollBar(
dsinclair1a7534a2016-11-22 15:56:11 -080032 const CFWL_App* app,
dsinclaira5811f02016-11-03 12:27:25 -070033 std::unique_ptr<CFWL_WidgetProperties> properties,
dsinclair2c489cc2016-11-23 16:17:20 -080034 CFWL_Widget* pOuter)
Tom Sepez3e5e563e2019-08-12 17:54:25 +000035 : CFWL_Widget(app, std::move(properties), pOuter) {}
dsinclairb4d40ff2016-05-05 10:28:02 -070036
Tom Sepez3e5e563e2019-08-12 17:54:25 +000037CFWL_ScrollBar::~CFWL_ScrollBar() = default;
dsinclairb4d40ff2016-05-05 10:28:02 -070038
dsinclair0ce11ee2016-11-23 16:03:10 -080039FWL_Type CFWL_ScrollBar::GetClassID() const {
dsinclair20855382016-10-31 07:29:34 -070040 return FWL_Type::ScrollBar;
41}
42
dsinclair0ce11ee2016-11-23 16:03:10 -080043void CFWL_ScrollBar::Update() {
dsinclair058d2d62016-11-16 13:54:01 -080044 if (IsLocked())
dsinclair98329fe2016-11-10 09:40:14 -080045 return;
dsinclair058d2d62016-11-16 13:54:01 -080046 if (!m_pProperties->m_pThemeProvider)
Dan Sinclair1770c022016-03-14 14:14:16 -040047 m_pProperties->m_pThemeProvider = GetAvailableTheme();
dsinclair058d2d62016-11-16 13:54:01 -080048
Dan Sinclair1770c022016-03-14 14:14:16 -040049 Layout();
Dan Sinclair1770c022016-03-14 14:14:16 -040050}
dsinclairfb505592016-10-20 06:44:03 -070051
Dan Sinclair2b918c82017-07-13 14:47:10 -040052void CFWL_ScrollBar::DrawWidget(CXFA_Graphics* pGraphics,
Lei Zhang4b472142017-08-17 14:30:08 -070053 const CFX_Matrix& matrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -040054 if (!pGraphics)
dsinclair98329fe2016-11-10 09:40:14 -080055 return;
Dan Sinclair1770c022016-03-14 14:14:16 -040056 if (!m_pProperties->m_pThemeProvider)
dsinclair98329fe2016-11-10 09:40:14 -080057 return;
dsinclair058d2d62016-11-16 13:54:01 -080058
Tom Sepezbcdbeae2018-08-21 23:07:21 +000059 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider.Get();
dsinclair058d2d62016-11-16 13:54:01 -080060 if (HasBorder())
Lei Zhang4b472142017-08-17 14:30:08 -070061 DrawBorder(pGraphics, CFWL_Part::Border, pTheme, matrix);
62 DrawTrack(pGraphics, pTheme, true, &matrix);
63 DrawTrack(pGraphics, pTheme, false, &matrix);
64 DrawArrowBtn(pGraphics, pTheme, true, &matrix);
65 DrawArrowBtn(pGraphics, pTheme, false, &matrix);
66 DrawThumb(pGraphics, pTheme, &matrix);
Dan Sinclair1770c022016-03-14 14:14:16 -040067}
dsinclairfb505592016-10-20 06:44:03 -070068
Dan Sinclair05df0752017-03-14 14:43:42 -040069void CFWL_ScrollBar::SetTrackPos(float fTrackPos) {
Dan Sinclair1770c022016-03-14 14:14:16 -040070 m_fTrackPos = fTrackPos;
Dan Sinclairdb194cf2017-01-02 15:45:12 -050071 m_rtThumb = CalcThumbButtonRect(m_rtThumb);
72 m_rtMinTrack = CalcMinTrackRect(m_rtMinTrack);
73 m_rtMaxTrack = CalcMaxTrackRect(m_rtMaxTrack);
Dan Sinclair1770c022016-03-14 14:14:16 -040074}
dsinclairfb505592016-10-20 06:44:03 -070075
Dan Sinclair05df0752017-03-14 14:43:42 -040076bool CFWL_ScrollBar::DoScroll(CFWL_EventScroll::Code dwCode, float fPos) {
dsinclair447b1f32016-12-08 10:06:32 -080077 if (dwCode == CFWL_EventScroll::Code::None)
dsinclair3e577c22016-11-10 11:01:16 -080078 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -040079 return OnScroll(dwCode, fPos);
80}
tsepez6f4f2332016-06-06 13:23:55 -070081
Dan Sinclair2b918c82017-07-13 14:47:10 -040082void CFWL_ScrollBar::DrawTrack(CXFA_Graphics* pGraphics,
dsinclairfb505592016-10-20 06:44:03 -070083 IFWL_ThemeProvider* pTheme,
tsepezd19e9122016-11-02 15:43:18 -070084 bool bLower,
dsinclairfb505592016-10-20 06:44:03 -070085 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -040086 CFWL_ThemeBackground param;
dsinclairfb505592016-10-20 06:44:03 -070087 param.m_pWidget = this;
dsinclairf87058d2016-04-21 06:22:11 -070088 param.m_iPart = bLower ? CFWL_Part::LowerTrack : CFWL_Part::UpperTrack;
Dan Sinclair1770c022016-03-14 14:14:16 -040089 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
dsinclairf87058d2016-04-21 06:22:11 -070090 ? CFWL_PartState_Disabled
Dan Sinclair1770c022016-03-14 14:14:16 -040091 : (bLower ? m_iMinTrackState : m_iMaxTrackState);
92 param.m_pGraphics = pGraphics;
93 param.m_matrix.Concat(*pMatrix);
94 param.m_rtPart = bLower ? m_rtMinTrack : m_rtMaxTrack;
Tom Sepezf8014512019-01-17 21:59:24 +000095 pTheme->DrawBackground(param);
Dan Sinclair1770c022016-03-14 14:14:16 -040096}
dsinclairfb505592016-10-20 06:44:03 -070097
Dan Sinclair2b918c82017-07-13 14:47:10 -040098void CFWL_ScrollBar::DrawArrowBtn(CXFA_Graphics* pGraphics,
dsinclairfb505592016-10-20 06:44:03 -070099 IFWL_ThemeProvider* pTheme,
tsepezd19e9122016-11-02 15:43:18 -0700100 bool bMinBtn,
dsinclairfb505592016-10-20 06:44:03 -0700101 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400102 CFWL_ThemeBackground param;
dsinclairfb505592016-10-20 06:44:03 -0700103 param.m_pWidget = this;
dsinclairf87058d2016-04-21 06:22:11 -0700104 param.m_iPart = bMinBtn ? CFWL_Part::ForeArrow : CFWL_Part::BackArrow;
Dan Sinclair1770c022016-03-14 14:14:16 -0400105 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
dsinclairf87058d2016-04-21 06:22:11 -0700106 ? CFWL_PartState_Disabled
Dan Sinclair1770c022016-03-14 14:14:16 -0400107 : (bMinBtn ? m_iMinButtonState : m_iMaxButtonState);
108 param.m_pGraphics = pGraphics;
109 param.m_matrix.Concat(*pMatrix);
110 param.m_rtPart = bMinBtn ? m_rtMinBtn : m_rtMaxBtn;
dsinclair058d2d62016-11-16 13:54:01 -0800111 if (param.m_rtPart.height > 0 && param.m_rtPart.width > 0)
Tom Sepezf8014512019-01-17 21:59:24 +0000112 pTheme->DrawBackground(param);
Dan Sinclair1770c022016-03-14 14:14:16 -0400113}
dsinclairfb505592016-10-20 06:44:03 -0700114
Dan Sinclair2b918c82017-07-13 14:47:10 -0400115void CFWL_ScrollBar::DrawThumb(CXFA_Graphics* pGraphics,
dsinclairfb505592016-10-20 06:44:03 -0700116 IFWL_ThemeProvider* pTheme,
117 const CFX_Matrix* pMatrix) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400118 CFWL_ThemeBackground param;
dsinclairfb505592016-10-20 06:44:03 -0700119 param.m_pWidget = this;
dsinclairf87058d2016-04-21 06:22:11 -0700120 param.m_iPart = CFWL_Part::Thumb;
Dan Sinclair1770c022016-03-14 14:14:16 -0400121 param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)
dsinclairf87058d2016-04-21 06:22:11 -0700122 ? CFWL_PartState_Disabled
Dan Sinclair1770c022016-03-14 14:14:16 -0400123 : m_iThumbButtonState;
124 param.m_pGraphics = pGraphics;
125 param.m_matrix.Concat(*pMatrix);
126 param.m_rtPart = m_rtThumb;
Tom Sepezf8014512019-01-17 21:59:24 +0000127 pTheme->DrawBackground(param);
Dan Sinclair1770c022016-03-14 14:14:16 -0400128}
dsinclairfb505592016-10-20 06:44:03 -0700129
dsinclair0ce11ee2016-11-23 16:03:10 -0800130void CFWL_ScrollBar::Layout() {
dsinclair43ac44c2016-12-08 14:05:14 -0800131 m_rtClient = GetClientRect();
Dan Sinclairc635c932017-01-03 15:46:55 -0500132
Dan Sinclair1770c022016-03-14 14:14:16 -0400133 CalcButtonLen();
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500134 m_rtMinBtn = CalcMinButtonRect();
135 m_rtMaxBtn = CalcMaxButtonRect();
136 m_rtThumb = CalcThumbButtonRect(m_rtThumb);
137 m_rtMinTrack = CalcMinTrackRect(m_rtMinTrack);
138 m_rtMaxTrack = CalcMaxTrackRect(m_rtMaxTrack);
Dan Sinclair1770c022016-03-14 14:14:16 -0400139}
dsinclairfb505592016-10-20 06:44:03 -0700140
dsinclair0ce11ee2016-11-23 16:03:10 -0800141void CFWL_ScrollBar::CalcButtonLen() {
Dan Sinclair1770c022016-03-14 14:14:16 -0400142 m_fButtonLen = IsVertical() ? m_rtClient.width : m_rtClient.height;
Dan Sinclair05df0752017-03-14 14:43:42 -0400143 float fLength = IsVertical() ? m_rtClient.height : m_rtClient.width;
Dan Sinclair1770c022016-03-14 14:14:16 -0400144 if (fLength < m_fButtonLen * 2) {
145 m_fButtonLen = fLength / 2;
tsepezd19e9122016-11-02 15:43:18 -0700146 m_bMinSize = true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400147 } else {
tsepezd19e9122016-11-02 15:43:18 -0700148 m_bMinSize = false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400149 }
150}
dsinclairfb505592016-10-20 06:44:03 -0700151
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500152CFX_RectF CFWL_ScrollBar::CalcMinButtonRect() {
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500153 if (IsVertical())
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500154 return CFX_RectF(m_rtClient.TopLeft(), m_rtClient.width, m_fButtonLen);
155 return CFX_RectF(m_rtClient.TopLeft(), m_fButtonLen, m_rtClient.height);
Dan Sinclair1770c022016-03-14 14:14:16 -0400156}
dsinclair878dd5b2016-10-17 18:14:25 -0700157
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500158CFX_RectF CFWL_ScrollBar::CalcMaxButtonRect() {
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500159 if (IsVertical()) {
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500160 return CFX_RectF(m_rtClient.left, m_rtClient.bottom() - m_fButtonLen,
161 m_rtClient.width, m_fButtonLen);
Dan Sinclair1770c022016-03-14 14:14:16 -0400162 }
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500163 return CFX_RectF(m_rtClient.right() - m_fButtonLen, m_rtClient.top,
164 m_fButtonLen, m_rtClient.height);
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500165}
166
167CFX_RectF CFWL_ScrollBar::CalcThumbButtonRect(const CFX_RectF& rtThumb) {
168 CFX_RectF rect;
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500169 if (!IsEnabled())
170 return rect;
171
Dan Sinclair1770c022016-03-14 14:14:16 -0400172 if (m_bMinSize) {
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500173 rect.left = rtThumb.left;
174 rect.top = rtThumb.top;
175 return rect;
Dan Sinclair1770c022016-03-14 14:14:16 -0400176 }
dsinclair058d2d62016-11-16 13:54:01 -0800177
Dan Sinclair05df0752017-03-14 14:43:42 -0400178 float fRange = m_fRangeMax - m_fRangeMin;
Dan Sinclair1770c022016-03-14 14:14:16 -0400179 if (fRange < 0) {
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500180 if (IsVertical()) {
181 return CFX_RectF(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width,
182 0);
183 }
184 return CFX_RectF(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height);
Dan Sinclair1770c022016-03-14 14:14:16 -0400185 }
dsinclair058d2d62016-11-16 13:54:01 -0800186
Dan Sinclair1770c022016-03-14 14:14:16 -0400187 CFX_RectF rtClient = m_rtClient;
Dan Sinclair05df0752017-03-14 14:43:42 -0400188 float fLength = IsVertical() ? rtClient.height : rtClient.width;
189 float fSize = m_fButtonLen;
dsinclair30e5f302016-11-21 12:18:28 -0800190 fLength -= fSize * 2.0f;
191 if (fLength < fSize)
192 fLength = 0.0f;
dsinclair058d2d62016-11-16 13:54:01 -0800193
Dan Sinclair05df0752017-03-14 14:43:42 -0400194 float fThumbSize = fLength * fLength / (fRange + fLength);
Dan Sinclairc635c932017-01-03 15:46:55 -0500195 fThumbSize = std::max(fThumbSize, kMinThumbSize);
dsinclair058d2d62016-11-16 13:54:01 -0800196
Dan Sinclair05df0752017-03-14 14:43:42 -0400197 float fDiff = std::max(fLength - fThumbSize, 0.0f);
Lei Zhang85f019a2017-03-17 15:14:19 -0700198 float fTrackPos = pdfium::clamp(m_fTrackPos, m_fRangeMin, m_fRangeMax);
Dan Sinclair1770c022016-03-14 14:14:16 -0400199 if (!fRange)
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500200 return rect;
dsinclair058d2d62016-11-16 13:54:01 -0800201
Dan Sinclair05df0752017-03-14 14:43:42 -0400202 float iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange;
dsinclair30e5f302016-11-21 12:18:28 -0800203 rect.left = rtClient.left;
dsinclair30e5f302016-11-21 12:18:28 -0800204 rect.top = rtClient.top;
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500205 if (IsVertical()) {
dsinclair30e5f302016-11-21 12:18:28 -0800206 rect.top += iPos;
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500207 rect.width = rtClient.width;
208 rect.height = fThumbSize;
209 } else {
210 rect.left += iPos;
211 rect.width = fThumbSize;
212 rect.height = rtClient.height;
213 }
214 return rect;
Dan Sinclair1770c022016-03-14 14:14:16 -0400215}
dsinclairfb505592016-10-20 06:44:03 -0700216
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500217CFX_RectF CFWL_ScrollBar::CalcMinTrackRect(const CFX_RectF& rtMinRect) {
218 CFX_RectF rect;
Dan Sinclair1770c022016-03-14 14:14:16 -0400219 if (m_bMinSize) {
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500220 rect.left = rtMinRect.left;
221 rect.top = rtMinRect.top;
222 return rect;
Dan Sinclair1770c022016-03-14 14:14:16 -0400223 }
dsinclair058d2d62016-11-16 13:54:01 -0800224
Dan Sinclair1770c022016-03-14 14:14:16 -0400225 rect.left = m_rtClient.left;
226 rect.top = m_rtClient.top;
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500227 if (IsVertical()) {
228 rect.width = m_rtClient.width;
229 rect.height = (m_rtThumb.top + m_rtThumb.bottom()) / 2;
230 } else {
231 rect.width = (m_rtThumb.left + m_rtThumb.right()) / 2;
232 rect.height = m_rtClient.height;
233 }
234 return rect;
Dan Sinclair1770c022016-03-14 14:14:16 -0400235}
dsinclairfb505592016-10-20 06:44:03 -0700236
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500237CFX_RectF CFWL_ScrollBar::CalcMaxTrackRect(const CFX_RectF& rtMaxRect) {
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500238 if (m_bMinSize)
239 return CFX_RectF(rtMaxRect.TopLeft(), 0, 0);
dsinclair058d2d62016-11-16 13:54:01 -0800240
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500241 if (IsVertical()) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400242 float iy = (m_rtThumb.top + m_rtThumb.bottom()) / 2;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500243 return CFX_RectF(m_rtClient.left, iy, m_rtClient.width,
244 m_rtClient.bottom() - iy);
Dan Sinclairdb194cf2017-01-02 15:45:12 -0500245 }
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500246
Dan Sinclair05df0752017-03-14 14:43:42 -0400247 float ix = (m_rtThumb.left + m_rtThumb.right()) / 2;
Dan Sinclairbba2a7c2017-02-07 16:36:39 -0500248 return CFX_RectF(ix, m_rtClient.top, m_rtClient.height - ix,
249 m_rtClient.height);
Dan Sinclair1770c022016-03-14 14:14:16 -0400250}
dsinclairfb505592016-10-20 06:44:03 -0700251
Dan Sinclair05df0752017-03-14 14:43:42 -0400252float CFWL_ScrollBar::GetTrackPointPos(const CFX_PointF& point) {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500253 CFX_PointF diff = point - m_cpTrackPoint;
Dan Sinclair05df0752017-03-14 14:43:42 -0400254 float fRange = m_fRangeMax - m_fRangeMin;
255 float fPos;
dsinclair30e5f302016-11-21 12:18:28 -0800256
257 if (IsVertical()) {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500258 fPos = fRange * diff.y /
dsinclair30e5f302016-11-21 12:18:28 -0800259 (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height);
Dan Sinclair1770c022016-03-14 14:14:16 -0400260 } else {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500261 fPos = fRange * diff.x /
dsinclair30e5f302016-11-21 12:18:28 -0800262 (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width);
Dan Sinclair1770c022016-03-14 14:14:16 -0400263 }
dsinclair30e5f302016-11-21 12:18:28 -0800264
Dan Sinclair1770c022016-03-14 14:14:16 -0400265 fPos += m_fLastTrackPos;
Lei Zhang85f019a2017-03-17 15:14:19 -0700266 return pdfium::clamp(fPos, m_fRangeMin, m_fRangeMax);
Dan Sinclair1770c022016-03-14 14:14:16 -0400267}
dsinclairfb505592016-10-20 06:44:03 -0700268
dsinclair0ce11ee2016-11-23 16:03:10 -0800269bool CFWL_ScrollBar::SendEvent() {
dsinclairf87058d2016-04-21 06:22:11 -0700270 if (m_iMinButtonState == CFWL_PartState_Pressed) {
dsinclair447b1f32016-12-08 10:06:32 -0800271 DoScroll(CFWL_EventScroll::Code::StepBackward, m_fTrackPos);
tsepezd19e9122016-11-02 15:43:18 -0700272 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400273 }
dsinclairf87058d2016-04-21 06:22:11 -0700274 if (m_iMaxButtonState == CFWL_PartState_Pressed) {
dsinclair447b1f32016-12-08 10:06:32 -0800275 DoScroll(CFWL_EventScroll::Code::StepForward, m_fTrackPos);
tsepezd19e9122016-11-02 15:43:18 -0700276 return false;
Dan Sinclair1770c022016-03-14 14:14:16 -0400277 }
dsinclairf87058d2016-04-21 06:22:11 -0700278 if (m_iMinTrackState == CFWL_PartState_Pressed) {
dsinclair447b1f32016-12-08 10:06:32 -0800279 DoScroll(CFWL_EventScroll::Code::PageBackward, m_fTrackPos);
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500280 return m_rtThumb.Contains(m_cpTrackPoint);
Dan Sinclair1770c022016-03-14 14:14:16 -0400281 }
dsinclairf87058d2016-04-21 06:22:11 -0700282 if (m_iMaxTrackState == CFWL_PartState_Pressed) {
dsinclair447b1f32016-12-08 10:06:32 -0800283 DoScroll(CFWL_EventScroll::Code::PageForward, m_fTrackPos);
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500284 return m_rtThumb.Contains(m_cpTrackPoint);
Dan Sinclair1770c022016-03-14 14:14:16 -0400285 }
286 if (m_iMouseWheel) {
dsinclair447b1f32016-12-08 10:06:32 -0800287 CFWL_EventScroll::Code dwCode = m_iMouseWheel < 0
288 ? CFWL_EventScroll::Code::StepForward
289 : CFWL_EventScroll::Code::StepBackward;
Dan Sinclair1770c022016-03-14 14:14:16 -0400290 DoScroll(dwCode, m_fTrackPos);
291 }
tsepezd19e9122016-11-02 15:43:18 -0700292 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400293}
dsinclairfb505592016-10-20 06:44:03 -0700294
Dan Sinclair05df0752017-03-14 14:43:42 -0400295bool CFWL_ScrollBar::OnScroll(CFWL_EventScroll::Code dwCode, float fPos) {
dsinclair447b1f32016-12-08 10:06:32 -0800296 CFWL_EventScroll ev(this);
Dan Sinclair1770c022016-03-14 14:14:16 -0400297 ev.m_iScrollCode = dwCode;
Dan Sinclair1770c022016-03-14 14:14:16 -0400298 ev.m_fPos = fPos;
Dan Sinclair1770c022016-03-14 14:14:16 -0400299 DispatchEvent(&ev);
dsinclair4614b452016-12-07 17:01:58 -0800300 return true;
Dan Sinclair1770c022016-03-14 14:14:16 -0400301}
dsinclair5d9da0c2016-04-21 13:12:06 -0700302
dsinclair0ce11ee2016-11-23 16:03:10 -0800303void CFWL_ScrollBar::OnProcessMessage(CFWL_Message* pMessage) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400304 if (!pMessage)
dsinclairc777f482016-05-04 17:57:03 -0700305 return;
dsinclair5d9da0c2016-04-21 13:12:06 -0700306
dsinclair4614b452016-12-07 17:01:58 -0800307 CFWL_Message::Type type = pMessage->GetType();
308 if (type == CFWL_Message::Type::Mouse) {
dsinclair447b1f32016-12-08 10:06:32 -0800309 CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage);
dsinclair8f4bf9a2016-05-04 13:51:51 -0700310 switch (pMsg->m_dwCmd) {
dsinclair3b3ce1a2016-11-02 14:51:25 -0700311 case FWL_MouseCommand::LeftButtonDown:
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500312 OnLButtonDown(pMsg->m_pos);
Dan Sinclair1770c022016-03-14 14:14:16 -0400313 break;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700314 case FWL_MouseCommand::LeftButtonUp:
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500315 OnLButtonUp(pMsg->m_pos);
Dan Sinclair1770c022016-03-14 14:14:16 -0400316 break;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700317 case FWL_MouseCommand::Move:
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500318 OnMouseMove(pMsg->m_pos);
Dan Sinclair1770c022016-03-14 14:14:16 -0400319 break;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700320 case FWL_MouseCommand::Leave:
Dan Sinclair1770c022016-03-14 14:14:16 -0400321 OnMouseLeave();
322 break;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700323 default:
324 break;
Dan Sinclair1770c022016-03-14 14:14:16 -0400325 }
dsinclair4614b452016-12-07 17:01:58 -0800326 } else if (type == CFWL_Message::Type::MouseWheel) {
dsinclair447b1f32016-12-08 10:06:32 -0800327 CFWL_MessageMouseWheel* pMsg =
328 static_cast<CFWL_MessageMouseWheel*>(pMessage);
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500329 OnMouseWheel(pMsg->m_delta);
Dan Sinclair1770c022016-03-14 14:14:16 -0400330 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400331}
dsinclair5d9da0c2016-04-21 13:12:06 -0700332
Dan Sinclair2b918c82017-07-13 14:47:10 -0400333void CFWL_ScrollBar::OnDrawWidget(CXFA_Graphics* pGraphics,
Lei Zhang4b472142017-08-17 14:30:08 -0700334 const CFX_Matrix& matrix) {
335 DrawWidget(pGraphics, matrix);
Dan Sinclair1770c022016-03-14 14:14:16 -0400336}
dsinclairc777f482016-05-04 17:57:03 -0700337
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500338void CFWL_ScrollBar::OnLButtonDown(const CFX_PointF& point) {
dsinclair3b3ce1a2016-11-02 14:51:25 -0700339 if (!IsEnabled())
Dan Sinclair1770c022016-03-14 14:14:16 -0400340 return;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700341
tsepezd19e9122016-11-02 15:43:18 -0700342 m_bMouseDown = true;
343 SetGrab(true);
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500344
345 m_cpTrackPoint = point;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700346 m_fLastTrackPos = m_fTrackPos;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500347 if (m_rtMinBtn.Contains(point))
348 DoMouseDown(0, m_rtMinBtn, m_iMinButtonState, point);
349 else if (m_rtThumb.Contains(point))
350 DoMouseDown(1, m_rtThumb, m_iThumbButtonState, point);
351 else if (m_rtMaxBtn.Contains(point))
352 DoMouseDown(2, m_rtMaxBtn, m_iMaxButtonState, point);
353 else if (m_rtMinTrack.Contains(point))
354 DoMouseDown(3, m_rtMinTrack, m_iMinTrackState, point);
dsinclair3b3ce1a2016-11-02 14:51:25 -0700355 else
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500356 DoMouseDown(4, m_rtMaxTrack, m_iMaxTrackState, point);
dsinclair3b3ce1a2016-11-02 14:51:25 -0700357
Tom Sepez3e5e563e2019-08-12 17:54:25 +0000358 if (!SendEvent()) {
359 m_pTimer = pdfium::MakeUnique<CFX_Timer>(
360 GetOwnerApp()->GetAdapterNative()->GetTimerHandler(), this,
361 FWL_SCROLLBAR_Elapse);
362 }
Dan Sinclair1770c022016-03-14 14:14:16 -0400363}
tsepez6f4f2332016-06-06 13:23:55 -0700364
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500365void CFWL_ScrollBar::OnLButtonUp(const CFX_PointF& point) {
Tom Sepez3e5e563e2019-08-12 17:54:25 +0000366 m_pTimer.reset();
tsepezd19e9122016-11-02 15:43:18 -0700367 m_bMouseDown = false;
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500368 DoMouseUp(0, m_rtMinBtn, m_iMinButtonState, point);
369 DoMouseUp(1, m_rtThumb, m_iThumbButtonState, point);
370 DoMouseUp(2, m_rtMaxBtn, m_iMaxButtonState, point);
371 DoMouseUp(3, m_rtMinTrack, m_iMinTrackState, point);
372 DoMouseUp(4, m_rtMaxTrack, m_iMaxTrackState, point);
tsepezd19e9122016-11-02 15:43:18 -0700373 SetGrab(false);
Dan Sinclair1770c022016-03-14 14:14:16 -0400374}
dsinclairfb505592016-10-20 06:44:03 -0700375
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500376void CFWL_ScrollBar::OnMouseMove(const CFX_PointF& point) {
377 DoMouseMove(0, m_rtMinBtn, m_iMinButtonState, point);
378 DoMouseMove(1, m_rtThumb, m_iThumbButtonState, point);
379 DoMouseMove(2, m_rtMaxBtn, m_iMaxButtonState, point);
380 DoMouseMove(3, m_rtMinTrack, m_iMinTrackState, point);
381 DoMouseMove(4, m_rtMaxTrack, m_iMaxTrackState, point);
Dan Sinclair1770c022016-03-14 14:14:16 -0400382}
dsinclairfb505592016-10-20 06:44:03 -0700383
dsinclair0ce11ee2016-11-23 16:03:10 -0800384void CFWL_ScrollBar::OnMouseLeave() {
dsinclair3b3ce1a2016-11-02 14:51:25 -0700385 DoMouseLeave(0, m_rtMinBtn, m_iMinButtonState);
386 DoMouseLeave(1, m_rtThumb, m_iThumbButtonState);
387 DoMouseLeave(2, m_rtMaxBtn, m_iMaxButtonState);
388 DoMouseLeave(3, m_rtMinTrack, m_iMinTrackState);
389 DoMouseLeave(4, m_rtMaxTrack, m_iMaxTrackState);
Dan Sinclair1770c022016-03-14 14:14:16 -0400390}
dsinclairfb505592016-10-20 06:44:03 -0700391
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500392void CFWL_ScrollBar::OnMouseWheel(const CFX_PointF& delta) {
393 m_iMouseWheel = static_cast<int32_t>(delta.x);
dsinclair3b3ce1a2016-11-02 14:51:25 -0700394 SendEvent();
395 m_iMouseWheel = 0;
Dan Sinclair1770c022016-03-14 14:14:16 -0400396}
dsinclairfb505592016-10-20 06:44:03 -0700397
dsinclair0ce11ee2016-11-23 16:03:10 -0800398void CFWL_ScrollBar::DoMouseDown(int32_t iItem,
dsinclair3b3ce1a2016-11-02 14:51:25 -0700399 const CFX_RectF& rtItem,
400 int32_t& iState,
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500401 const CFX_PointF& point) {
402 if (!rtItem.Contains(point))
Dan Sinclair1770c022016-03-14 14:14:16 -0400403 return;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700404 if (iState == CFWL_PartState_Pressed)
Dan Sinclair1770c022016-03-14 14:14:16 -0400405 return;
dsinclair058d2d62016-11-16 13:54:01 -0800406
dsinclairf87058d2016-04-21 06:22:11 -0700407 iState = CFWL_PartState_Pressed;
dsinclair43ac44c2016-12-08 14:05:14 -0800408 RepaintRect(rtItem);
Dan Sinclair1770c022016-03-14 14:14:16 -0400409}
dsinclairfb505592016-10-20 06:44:03 -0700410
dsinclair0ce11ee2016-11-23 16:03:10 -0800411void CFWL_ScrollBar::DoMouseUp(int32_t iItem,
dsinclair3b3ce1a2016-11-02 14:51:25 -0700412 const CFX_RectF& rtItem,
413 int32_t& iState,
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500414 const CFX_PointF& point) {
dsinclairf87058d2016-04-21 06:22:11 -0700415 int32_t iNewState =
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500416 rtItem.Contains(point) ? CFWL_PartState_Hovered : CFWL_PartState_Normal;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700417 if (iState == iNewState)
Dan Sinclair1770c022016-03-14 14:14:16 -0400418 return;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700419
Dan Sinclair1770c022016-03-14 14:14:16 -0400420 iState = iNewState;
dsinclair43ac44c2016-12-08 14:05:14 -0800421 RepaintRect(rtItem);
dsinclair447b1f32016-12-08 10:06:32 -0800422 OnScroll(CFWL_EventScroll::Code::EndScroll, m_fTrackPos);
Dan Sinclair1770c022016-03-14 14:14:16 -0400423}
dsinclairfb505592016-10-20 06:44:03 -0700424
dsinclair0ce11ee2016-11-23 16:03:10 -0800425void CFWL_ScrollBar::DoMouseMove(int32_t iItem,
dsinclair3b3ce1a2016-11-02 14:51:25 -0700426 const CFX_RectF& rtItem,
427 int32_t& iState,
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500428 const CFX_PointF& point) {
dsinclair3b3ce1a2016-11-02 14:51:25 -0700429 if (!m_bMouseDown) {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500430 int32_t iNewState =
431 rtItem.Contains(point) ? CFWL_PartState_Hovered : CFWL_PartState_Normal;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700432 if (iState == iNewState)
Dan Sinclair1770c022016-03-14 14:14:16 -0400433 return;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700434
Dan Sinclair1770c022016-03-14 14:14:16 -0400435 iState = iNewState;
dsinclair43ac44c2016-12-08 14:05:14 -0800436 RepaintRect(rtItem);
dsinclair3b3ce1a2016-11-02 14:51:25 -0700437 } else if ((2 == iItem) && (m_iThumbButtonState == CFWL_PartState_Pressed)) {
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500438 m_fTrackPos = GetTrackPointPos(point);
439 OnScroll(CFWL_EventScroll::Code::TrackPos, m_fTrackPos);
Dan Sinclair1770c022016-03-14 14:14:16 -0400440 }
441}
dsinclairfb505592016-10-20 06:44:03 -0700442
dsinclair0ce11ee2016-11-23 16:03:10 -0800443void CFWL_ScrollBar::DoMouseLeave(int32_t iItem,
dsinclair3b3ce1a2016-11-02 14:51:25 -0700444 const CFX_RectF& rtItem,
445 int32_t& iState) {
446 if (iState == CFWL_PartState_Normal)
Dan Sinclair1770c022016-03-14 14:14:16 -0400447 return;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700448
dsinclairf87058d2016-04-21 06:22:11 -0700449 iState = CFWL_PartState_Normal;
dsinclair43ac44c2016-12-08 14:05:14 -0800450 RepaintRect(rtItem);
Dan Sinclair1770c022016-03-14 14:14:16 -0400451}
dsinclairfb505592016-10-20 06:44:03 -0700452
dsinclair0ce11ee2016-11-23 16:03:10 -0800453void CFWL_ScrollBar::DoMouseHover(int32_t iItem,
dsinclair3b3ce1a2016-11-02 14:51:25 -0700454 const CFX_RectF& rtItem,
455 int32_t& iState) {
456 if (iState == CFWL_PartState_Hovered)
Dan Sinclair1770c022016-03-14 14:14:16 -0400457 return;
dsinclair3b3ce1a2016-11-02 14:51:25 -0700458
dsinclairf87058d2016-04-21 06:22:11 -0700459 iState = CFWL_PartState_Hovered;
dsinclair43ac44c2016-12-08 14:05:14 -0800460 RepaintRect(rtItem);
Dan Sinclair1770c022016-03-14 14:14:16 -0400461}
dsinclair20855382016-10-31 07:29:34 -0700462
Tom Sepez3e5e563e2019-08-12 17:54:25 +0000463void CFWL_ScrollBar::OnTimerFired() {
464 m_pTimer.reset();
465 if (!SendEvent()) {
466 m_pTimer = pdfium::MakeUnique<CFX_Timer>(
467 GetOwnerApp()->GetAdapterNative()->GetTimerHandler(), this, 0);
Henrique Nakashima5a7e3302018-03-08 20:41:59 +0000468 }
dsinclair20855382016-10-31 07:29:34 -0700469}