blob: 3ec936730eec93bb518e7de1ad299ab24eca9505 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhang60f507b2015-06-13 00:41:00 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairc411eb92017-07-25 09:39:30 -04007#include "fpdfsdk/pwl/cpwl_scroll_bar.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -04008
Dan Sinclairfb00ec22017-07-05 09:28:15 -04009#include <algorithm>
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -040010#include <sstream>
Dan Sinclairc0993812017-07-05 17:17:08 -040011#include <vector>
Henrique Nakashimaf1eae2c2017-06-29 11:18:49 -040012
dsinclair74a34fc2016-09-29 16:41:42 -070013#include "core/fxge/cfx_pathdata.h"
14#include "core/fxge/cfx_renderdevice.h"
Dan Sinclairc411eb92017-07-25 09:39:30 -040015#include "fpdfsdk/pwl/cpwl_wnd.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070016
Dan Sinclaira9e28432017-07-05 14:18:14 -040017namespace {
18
19constexpr float kButtonWidth = 9.0f;
20constexpr float kPosButtonMinWidth = 2.0f;
21constexpr float kTriangleHalfLength = 2.0f;
22
23} // namespace
24
Dan Sinclair8e7f9322017-10-16 11:35:42 -040025#define PWL_DEFAULT_HEAVYGRAYCOLOR CFX_Color(CFX_Color::kGray, 0.50)
Dan Sinclaira9e28432017-07-05 14:18:14 -040026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027PWL_FLOATRANGE::PWL_FLOATRANGE() {
28 Default();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070029}
30
Dan Sinclair05df0752017-03-14 14:43:42 -040031PWL_FLOATRANGE::PWL_FLOATRANGE(float min, float max) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032 Set(min, max);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033}
34
Nico Weber9d8ec5a2015-08-04 13:00:21 -070035void PWL_FLOATRANGE::Default() {
36 fMin = 0;
37 fMax = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038}
39
Dan Sinclair05df0752017-03-14 14:43:42 -040040void PWL_FLOATRANGE::Set(float min, float max) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070041 if (min > max) {
42 fMin = max;
43 fMax = min;
44 } else {
45 fMin = min;
46 fMax = max;
47 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048}
49
Dan Sinclair05df0752017-03-14 14:43:42 -040050bool PWL_FLOATRANGE::In(float x) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051 return (IsFloatBigger(x, fMin) || IsFloatEqual(x, fMin)) &&
52 (IsFloatSmaller(x, fMax) || IsFloatEqual(x, fMax));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070053}
54
Dan Sinclair05df0752017-03-14 14:43:42 -040055float PWL_FLOATRANGE::GetWidth() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056 return fMax - fMin;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070057}
58
Nico Weber9d8ec5a2015-08-04 13:00:21 -070059PWL_SCROLL_PRIVATEDATA::PWL_SCROLL_PRIVATEDATA() {
60 Default();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070061}
62
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063void PWL_SCROLL_PRIVATEDATA::Default() {
64 ScrollRange.Default();
65 fScrollPos = ScrollRange.fMin;
66 fClientWidth = 0;
67 fBigStep = 10;
68 fSmallStep = 1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069}
70
Dan Sinclair05df0752017-03-14 14:43:42 -040071void PWL_SCROLL_PRIVATEDATA::SetScrollRange(float min, float max) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 ScrollRange.Set(min, max);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070073
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 if (IsFloatSmaller(fScrollPos, ScrollRange.fMin))
75 fScrollPos = ScrollRange.fMin;
76 if (IsFloatBigger(fScrollPos, ScrollRange.fMax))
77 fScrollPos = ScrollRange.fMax;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070078}
79
Dan Sinclair05df0752017-03-14 14:43:42 -040080void PWL_SCROLL_PRIVATEDATA::SetClientWidth(float width) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 fClientWidth = width;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082}
83
Dan Sinclair05df0752017-03-14 14:43:42 -040084void PWL_SCROLL_PRIVATEDATA::SetSmallStep(float step) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 fSmallStep = step;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070086}
87
Dan Sinclair05df0752017-03-14 14:43:42 -040088void PWL_SCROLL_PRIVATEDATA::SetBigStep(float step) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 fBigStep = step;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090}
91
Dan Sinclair05df0752017-03-14 14:43:42 -040092bool PWL_SCROLL_PRIVATEDATA::SetPos(float pos) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070093 if (ScrollRange.In(pos)) {
94 fScrollPos = pos;
tsepez4cf55152016-11-02 14:37:54 -070095 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096 }
tsepez4cf55152016-11-02 14:37:54 -070097 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100void PWL_SCROLL_PRIVATEDATA::AddSmall() {
101 if (!SetPos(fScrollPos + fSmallStep))
102 SetPos(ScrollRange.fMax);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700103}
104
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105void PWL_SCROLL_PRIVATEDATA::SubSmall() {
106 if (!SetPos(fScrollPos - fSmallStep))
107 SetPos(ScrollRange.fMin);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700108}
109
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110void PWL_SCROLL_PRIVATEDATA::AddBig() {
111 if (!SetPos(fScrollPos + fBigStep))
112 SetPos(ScrollRange.fMax);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700113}
114
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115void PWL_SCROLL_PRIVATEDATA::SubBig() {
116 if (!SetPos(fScrollPos - fBigStep))
117 SetPos(ScrollRange.fMin);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700118}
119
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120CPWL_SBButton::CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,
121 PWL_SBBUTTON_TYPE eButtonType) {
122 m_eScrollBarType = eScrollBarType;
123 m_eSBButtonType = eButtonType;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700124
tsepez4cf55152016-11-02 14:37:54 -0700125 m_bMouseDown = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126}
127
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700128CPWL_SBButton::~CPWL_SBButton() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700129
Ryan Harrison275e2602017-09-18 14:23:18 -0400130ByteString CPWL_SBButton::GetClassName() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 return "CPWL_SBButton";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700132}
133
Tom Sepezbf157302017-09-15 13:26:32 -0700134void CPWL_SBButton::OnCreate(CreateParams* pParamsToAdjust) {
135 pParamsToAdjust->eCursorType = FXCT_ARROW;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136}
137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
Lei Zhangeb14e042017-08-15 13:56:43 -0700139 const CFX_Matrix& mtUser2Device) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700140 if (!IsVisible())
141 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700142
Tom Sepez281a9ea2016-02-26 14:24:28 -0800143 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (rectWnd.IsEmpty())
145 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700146
Dan Sinclairf528eee2017-02-14 11:52:07 -0500147 CFX_PointF ptCenter = GetCenterPoint();
Dan Sinclairfc54e052017-02-23 09:59:05 -0500148 int32_t nTransparency = GetTransparency();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700149
Dan Sinclairc0993812017-07-05 17:17:08 -0400150 if (m_eScrollBarType == SBT_HSCROLL) {
Lei Zhangeb14e042017-08-15 13:56:43 -0700151 CPWL_Wnd::DrawThisAppearance(pDevice, mtUser2Device);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700152
Dan Sinclairc0993812017-07-05 17:17:08 -0400153 CFX_PointF pt1;
154 CFX_PointF pt2;
155 CFX_PointF pt3;
156 if (m_eSBButtonType == PSBT_MIN) {
157 pt1 = CFX_PointF(ptCenter.x - kTriangleHalfLength * 0.5f, ptCenter.y);
158 pt2 = CFX_PointF(ptCenter.x + kTriangleHalfLength * 0.5f,
159 ptCenter.y + kTriangleHalfLength);
160 pt3 = CFX_PointF(ptCenter.x + kTriangleHalfLength * 0.5f,
161 ptCenter.y - kTriangleHalfLength);
162 } else if (m_eSBButtonType == PSBT_MAX) {
163 pt1 = CFX_PointF(ptCenter.x + kTriangleHalfLength * 0.5f, ptCenter.y);
164 pt2 = CFX_PointF(ptCenter.x - kTriangleHalfLength * 0.5f,
165 ptCenter.y + kTriangleHalfLength);
166 pt3 = CFX_PointF(ptCenter.x - kTriangleHalfLength * 0.5f,
167 ptCenter.y - kTriangleHalfLength);
168 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700169
Dan Sinclairc0993812017-07-05 17:17:08 -0400170 if (rectWnd.right - rectWnd.left > kTriangleHalfLength * 2 &&
171 rectWnd.top - rectWnd.bottom > kTriangleHalfLength) {
172 CFX_PathData path;
173 path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false);
174 path.AppendPoint(pt2, FXPT_TYPE::LineTo, false);
175 path.AppendPoint(pt3, FXPT_TYPE::LineTo, false);
176 path.AppendPoint(pt1, FXPT_TYPE::LineTo, false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700177
Lei Zhangeb14e042017-08-15 13:56:43 -0700178 pDevice->DrawPath(&path, &mtUser2Device, nullptr,
Dan Sinclairc0993812017-07-05 17:17:08 -0400179 PWL_DEFAULT_BLACKCOLOR.ToFXColor(nTransparency), 0,
180 FXFILL_ALTERNATE);
181 }
182 return;
183 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184
Dan Sinclairc0993812017-07-05 17:17:08 -0400185 // draw border
Lei Zhangeb14e042017-08-15 13:56:43 -0700186 pDevice->DrawStrokeRect(&mtUser2Device, rectWnd,
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400187 ArgbEncode(nTransparency, 100, 100, 100), 0.0f);
Lei Zhangeb14e042017-08-15 13:56:43 -0700188 pDevice->DrawStrokeRect(&mtUser2Device, rectWnd.GetDeflated(0.5f, 0.5f),
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400189 ArgbEncode(nTransparency, 255, 255, 255), 1.0f);
Dan Sinclairc0993812017-07-05 17:17:08 -0400190
191 if (m_eSBButtonType != PSBT_POS) {
192 // draw background
Dan Sinclairc0993812017-07-05 17:17:08 -0400193 if (IsEnabled()) {
Lei Zhangeb14e042017-08-15 13:56:43 -0700194 pDevice->DrawShadow(&mtUser2Device, true, false,
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400195 rectWnd.GetDeflated(1.0f, 1.0f), nTransparency, 80,
196 220);
Dan Sinclairc0993812017-07-05 17:17:08 -0400197 } else {
Lei Zhangeb14e042017-08-15 13:56:43 -0700198 pDevice->DrawFillRect(&mtUser2Device, rectWnd.GetDeflated(1.0f, 1.0f),
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400199 ArgbEncode(255, 255, 255, 255));
Dan Sinclairc0993812017-07-05 17:17:08 -0400200 }
201
202 // draw arrow
203 if (rectWnd.top - rectWnd.bottom > 6.0f) {
204 float fX = rectWnd.left + 1.5f;
205 float fY = rectWnd.bottom;
206 std::vector<CFX_PointF> pts;
207 if (m_eSBButtonType == PSBT_MIN) {
208 pts.push_back(CFX_PointF(fX + 2.5f, fY + 4.0f));
209 pts.push_back(CFX_PointF(fX + 2.5f, fY + 3.0f));
210 pts.push_back(CFX_PointF(fX + 4.5f, fY + 5.0f));
211 pts.push_back(CFX_PointF(fX + 6.5f, fY + 3.0f));
212 pts.push_back(CFX_PointF(fX + 6.5f, fY + 4.0f));
213 pts.push_back(CFX_PointF(fX + 4.5f, fY + 6.0f));
214 pts.push_back(CFX_PointF(fX + 2.5f, fY + 4.0f));
215 } else {
216 pts.push_back(CFX_PointF(fX + 2.5f, fY + 5.0f));
217 pts.push_back(CFX_PointF(fX + 2.5f, fY + 6.0f));
218 pts.push_back(CFX_PointF(fX + 4.5f, fY + 4.0f));
219 pts.push_back(CFX_PointF(fX + 6.5f, fY + 6.0f));
220 pts.push_back(CFX_PointF(fX + 6.5f, fY + 5.0f));
221 pts.push_back(CFX_PointF(fX + 4.5f, fY + 3.0f));
222 pts.push_back(CFX_PointF(fX + 2.5f, fY + 5.0f));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 }
Lei Zhangeb14e042017-08-15 13:56:43 -0700224 pDevice->DrawFillArea(&mtUser2Device, pts.data(), 7,
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400225 IsEnabled()
226 ? ArgbEncode(nTransparency, 255, 255, 255)
227 : PWL_DEFAULT_HEAVYGRAYCOLOR.ToFXColor(255));
Dan Sinclairc0993812017-07-05 17:17:08 -0400228 }
229 return;
230 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700231
Dan Sinclairc0993812017-07-05 17:17:08 -0400232 if (IsEnabled()) {
233 // draw shadow effect
234 CFX_PointF ptTop = CFX_PointF(rectWnd.left, rectWnd.top - 1.0f);
235 CFX_PointF ptBottom = CFX_PointF(rectWnd.left, rectWnd.bottom + 1.0f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700236
Dan Sinclairc0993812017-07-05 17:17:08 -0400237 ptTop.x += 1.5f;
238 ptBottom.x += 1.5f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239
Dan Sinclairc0993812017-07-05 17:17:08 -0400240 const FX_COLORREF refs[] = {ArgbEncode(nTransparency, 210, 210, 210),
241 ArgbEncode(nTransparency, 220, 220, 220),
242 ArgbEncode(nTransparency, 240, 240, 240),
243 ArgbEncode(nTransparency, 240, 240, 240),
244 ArgbEncode(nTransparency, 210, 210, 210),
245 ArgbEncode(nTransparency, 180, 180, 180),
246 ArgbEncode(nTransparency, 150, 150, 150),
247 ArgbEncode(nTransparency, 150, 150, 150),
248 ArgbEncode(nTransparency, 180, 180, 180),
249 ArgbEncode(nTransparency, 210, 210, 210)};
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400250 for (FX_COLORREF ref : refs) {
Lei Zhangeb14e042017-08-15 13:56:43 -0700251 pDevice->DrawStrokeLine(&mtUser2Device, ptTop, ptBottom, ref, 1.0f);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252
Dan Sinclairc0993812017-07-05 17:17:08 -0400253 ptTop.x += 1.0f;
254 ptBottom.x += 1.0f;
255 }
256 } else {
Lei Zhangeb14e042017-08-15 13:56:43 -0700257 pDevice->DrawFillRect(&mtUser2Device, rectWnd.GetDeflated(0.5f, 0.5f),
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400258 ArgbEncode(255, 255, 255, 255));
Dan Sinclairc0993812017-07-05 17:17:08 -0400259 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260
Dan Sinclairc0993812017-07-05 17:17:08 -0400261 // draw friction
262 if (rectWnd.Height() <= 8.0f)
263 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700264
Dan Sinclairc0993812017-07-05 17:17:08 -0400265 FX_COLORREF crStroke = ArgbEncode(nTransparency, 120, 120, 120);
266 if (!IsEnabled())
267 crStroke = PWL_DEFAULT_HEAVYGRAYCOLOR.ToFXColor(255);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268
Dan Sinclairc0993812017-07-05 17:17:08 -0400269 float nFrictionWidth = 5.0f;
270 float nFrictionHeight = 5.5f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271
Dan Sinclairc0993812017-07-05 17:17:08 -0400272 CFX_PointF ptLeft = CFX_PointF(ptCenter.x - nFrictionWidth / 2.0f,
273 ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
274 CFX_PointF ptRight = CFX_PointF(ptCenter.x + nFrictionWidth / 2.0f,
275 ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276
Dan Sinclairc0993812017-07-05 17:17:08 -0400277 for (size_t i = 0; i < 3; ++i) {
Lei Zhangeb14e042017-08-15 13:56:43 -0700278 pDevice->DrawStrokeLine(&mtUser2Device, ptLeft, ptRight, crStroke, 1.0f);
Dan Sinclairc0993812017-07-05 17:17:08 -0400279 ptLeft.y += 2.0f;
280 ptRight.y += 2.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700282}
283
Dan Sinclairf528eee2017-02-14 11:52:07 -0500284bool CPWL_SBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 if (CPWL_Wnd* pParent = GetParentWindow())
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400288 pParent->NotifyLButtonDown(this, point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700289
tsepez4cf55152016-11-02 14:37:54 -0700290 m_bMouseDown = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 SetCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700292
tsepez4cf55152016-11-02 14:37:54 -0700293 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700294}
295
Dan Sinclairf528eee2017-02-14 11:52:07 -0500296bool CPWL_SBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700297 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700299 if (CPWL_Wnd* pParent = GetParentWindow())
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400300 pParent->NotifyLButtonUp(this, point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700301
tsepez4cf55152016-11-02 14:37:54 -0700302 m_bMouseDown = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303 ReleaseCapture();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700304
tsepez4cf55152016-11-02 14:37:54 -0700305 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700306}
307
Dan Sinclairf528eee2017-02-14 11:52:07 -0500308bool CPWL_SBButton::OnMouseMove(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700309 CPWL_Wnd::OnMouseMove(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700310
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400311 if (CPWL_Wnd* pParent = GetParentWindow())
312 pParent->NotifyMouseMove(this, point);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313
tsepez4cf55152016-11-02 14:37:54 -0700314 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700315}
316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317CPWL_ScrollBar::CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType)
318 : m_sbType(sbType),
thestig1cd352e2016-06-07 17:53:06 -0700319 m_pMinButton(nullptr),
320 m_pMaxButton(nullptr),
321 m_pPosButton(nullptr),
tsepez4cf55152016-11-02 14:37:54 -0700322 m_bMouseDown(false),
323 m_bMinOrMax(false),
324 m_bNotifyForever(true) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700325
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326CPWL_ScrollBar::~CPWL_ScrollBar() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700327
Ryan Harrison275e2602017-09-18 14:23:18 -0400328ByteString CPWL_ScrollBar::GetClassName() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700329 return "CPWL_ScrollBar";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
331
Tom Sepezbf157302017-09-15 13:26:32 -0700332void CPWL_ScrollBar::OnCreate(CreateParams* pParamsToAdjust) {
333 pParamsToAdjust->eCursorType = FXCT_ARROW;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700334}
335
Tom Sepez5e042a12017-05-30 14:13:44 -0700336void CPWL_ScrollBar::OnDestroy() {
337 // Until cleanup takes place in the virtual destructor for CPWL_Wnd
338 // subclasses, implement the virtual OnDestroy method that does the
339 // cleanup first, then invokes the superclass OnDestroy ... gee,
340 // like a dtor would.
341 m_pMinButton.Release();
342 m_pMaxButton.Release();
343 m_pPosButton.Release();
344 CPWL_Wnd::OnDestroy();
345}
346
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400347bool CPWL_ScrollBar::RePosChildWnd() {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800348 CFX_FloatRect rcClient = GetClientRect();
349 CFX_FloatRect rcMinButton, rcMaxButton;
Dan Sinclair05df0752017-03-14 14:43:42 -0400350 float fBWidth = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351
352 switch (m_sbType) {
353 case SBT_HSCROLL:
354 if (rcClient.right - rcClient.left >
Dan Sinclaira9e28432017-07-05 14:18:14 -0400355 kButtonWidth * 2 + kPosButtonMinWidth + 2) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800356 rcMinButton = CFX_FloatRect(rcClient.left, rcClient.bottom,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400357 rcClient.left + kButtonWidth, rcClient.top);
Tom Sepez281a9ea2016-02-26 14:24:28 -0800358 rcMaxButton =
Dan Sinclaira9e28432017-07-05 14:18:14 -0400359 CFX_FloatRect(rcClient.right - kButtonWidth, rcClient.bottom,
360 rcClient.right, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700361 } else {
Dan Sinclaira9e28432017-07-05 14:18:14 -0400362 fBWidth = (rcClient.right - rcClient.left - kPosButtonMinWidth - 2) / 2;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363
364 if (fBWidth > 0) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800365 rcMinButton = CFX_FloatRect(rcClient.left, rcClient.bottom,
366 rcClient.left + fBWidth, rcClient.top);
367 rcMaxButton = CFX_FloatRect(rcClient.right - fBWidth, rcClient.bottom,
368 rcClient.right, rcClient.top);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800369 } else {
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400370 if (!SetVisible(false))
371 return false;
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800372 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 }
374 break;
375 case SBT_VSCROLL:
376 if (IsFloatBigger(rcClient.top - rcClient.bottom,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400377 kButtonWidth * 2 + kPosButtonMinWidth + 2)) {
378 rcMinButton = CFX_FloatRect(rcClient.left, rcClient.top - kButtonWidth,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800379 rcClient.right, rcClient.top);
380 rcMaxButton =
381 CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400382 rcClient.bottom + kButtonWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700383 } else {
Dan Sinclaira9e28432017-07-05 14:18:14 -0400384 fBWidth = (rcClient.top - rcClient.bottom - kPosButtonMinWidth - 2) / 2;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700385
386 if (IsFloatBigger(fBWidth, 0)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800387 rcMinButton = CFX_FloatRect(rcClient.left, rcClient.top - fBWidth,
388 rcClient.right, rcClient.top);
389 rcMaxButton =
390 CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
391 rcClient.bottom + fBWidth);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800392 } else {
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400393 if (!SetVisible(false))
394 return false;
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800395 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700396 }
397 break;
398 }
399
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400400 ObservedPtr thisObserved(this);
401
402 if (m_pMinButton) {
tsepez4cf55152016-11-02 14:37:54 -0700403 m_pMinButton->Move(rcMinButton, true, false);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400404 if (!thisObserved)
405 return false;
406 }
407
408 if (m_pMaxButton) {
tsepez4cf55152016-11-02 14:37:54 -0700409 m_pMaxButton->Move(rcMaxButton, true, false);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400410 if (!thisObserved)
411 return false;
412 }
413
414 if (!MovePosButton(false))
415 return false;
416
417 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700418}
419
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice,
Lei Zhangeb14e042017-08-15 13:56:43 -0700421 const CFX_Matrix& mtUser2Device) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800422 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423
424 if (IsVisible() && !rectWnd.IsEmpty()) {
Lei Zhangeb14e042017-08-15 13:56:43 -0700425 pDevice->DrawFillRect(&mtUser2Device, rectWnd, GetBackgroundColor(),
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400426 GetTransparency());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700427
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400428 pDevice->DrawStrokeLine(
Lei Zhangeb14e042017-08-15 13:56:43 -0700429 &mtUser2Device, CFX_PointF(rectWnd.left + 2.0f, rectWnd.top - 2.0f),
Dan Sinclairf528eee2017-02-14 11:52:07 -0500430 CFX_PointF(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
432
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400433 pDevice->DrawStrokeLine(
Lei Zhangeb14e042017-08-15 13:56:43 -0700434 &mtUser2Device, CFX_PointF(rectWnd.right - 2.0f, rectWnd.top - 2.0f),
Dan Sinclairf528eee2017-02-14 11:52:07 -0500435 CFX_PointF(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700436 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
437 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700438}
439
Dan Sinclairf528eee2017-02-14 11:52:07 -0500440bool CPWL_ScrollBar::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700441 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700442
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700443 if (HasFlag(PWS_AUTOTRANSPARENT)) {
444 if (GetTransparency() != 255) {
445 SetTransparency(255);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400446 if (!InvalidateRect(nullptr))
447 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700448 }
449 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700450
Tom Sepez281a9ea2016-02-26 14:24:28 -0800451 CFX_FloatRect rcMinArea, rcMaxArea;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700452
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700453 if (m_pPosButton && m_pPosButton->IsVisible()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800454 CFX_FloatRect rcClient = GetClientRect();
455 CFX_FloatRect rcPosButton = m_pPosButton->GetWindowRect();
Lei Zhang60f507b2015-06-13 00:41:00 -0700456
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700457 switch (m_sbType) {
458 case SBT_HSCROLL:
Dan Sinclaira9e28432017-07-05 14:18:14 -0400459 rcMinArea = CFX_FloatRect(rcClient.left + kButtonWidth, rcClient.bottom,
460 rcPosButton.left, rcClient.top);
Tom Sepez281a9ea2016-02-26 14:24:28 -0800461 rcMaxArea = CFX_FloatRect(rcPosButton.right, rcClient.bottom,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400462 rcClient.right - kButtonWidth, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463
464 break;
465 case SBT_VSCROLL:
Dan Sinclaira9e28432017-07-05 14:18:14 -0400466 rcMinArea = CFX_FloatRect(rcClient.left, rcPosButton.top,
467 rcClient.right, rcClient.top - kButtonWidth);
468 rcMaxArea = CFX_FloatRect(rcClient.left, rcClient.bottom + kButtonWidth,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800469 rcClient.right, rcPosButton.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700470 break;
471 }
472
473 rcMinArea.Normalize();
474 rcMaxArea.Normalize();
475
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500476 if (rcMinArea.Contains(point)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477 m_sData.SubBig();
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400478 if (!MovePosButton(true))
479 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700480 NotifyScrollWindow();
481 }
482
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500483 if (rcMaxArea.Contains(point)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484 m_sData.AddBig();
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400485 if (!MovePosButton(true))
486 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700487 NotifyScrollWindow();
488 }
489 }
490
tsepez4cf55152016-11-02 14:37:54 -0700491 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700492}
493
Dan Sinclairf528eee2017-02-14 11:52:07 -0500494bool CPWL_ScrollBar::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700496
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497 if (HasFlag(PWS_AUTOTRANSPARENT)) {
Dan Sinclairfc54e052017-02-23 09:59:05 -0500498 if (GetTransparency() != PWL_SCROLLBAR_TRANSPARENCY) {
499 SetTransparency(PWL_SCROLLBAR_TRANSPARENCY);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400500 if (!InvalidateRect(nullptr))
501 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700502 }
503 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700505 EndTimer();
tsepez4cf55152016-11-02 14:37:54 -0700506 m_bMouseDown = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700507
tsepez4cf55152016-11-02 14:37:54 -0700508 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700509}
510
Dan Sinclairfb00ec22017-07-05 09:28:15 -0400511void CPWL_ScrollBar::SetScrollInfo(const PWL_SCROLL_INFO& info) {
512 if (info == m_OriginInfo)
513 return;
514
515 m_OriginInfo = info;
516 float fMax =
517 std::max(0.0f, info.fContentMax - info.fContentMin - info.fPlateWidth);
518 SetScrollRange(0, fMax, info.fPlateWidth);
519 SetScrollStep(info.fBigStep, info.fSmallStep);
520}
521
Dan Sinclair7e0336e2017-07-05 09:39:50 -0400522void CPWL_ScrollBar::SetScrollPosition(float pos) {
523 switch (m_sbType) {
524 case SBT_HSCROLL:
525 pos = pos - m_OriginInfo.fContentMin;
526 break;
527 case SBT_VSCROLL:
528 pos = m_OriginInfo.fContentMax - pos;
529 break;
530 }
531 SetScrollPos(pos);
532}
533
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400534void CPWL_ScrollBar::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
535 if (child == m_pMinButton)
536 OnMinButtonLBDown(pos);
537 else if (child == m_pMaxButton)
538 OnMaxButtonLBDown(pos);
539 else if (child == m_pPosButton)
540 OnPosButtonLBDown(pos);
541}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700542
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400543void CPWL_ScrollBar::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
544 if (child == m_pMinButton)
545 OnMinButtonLBUp(pos);
546 else if (child == m_pMaxButton)
547 OnMaxButtonLBUp(pos);
548 else if (child == m_pPosButton)
549 OnPosButtonLBUp(pos);
550}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700551
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400552void CPWL_ScrollBar::NotifyMouseMove(CPWL_Wnd* child, const CFX_PointF& pos) {
553 if (child == m_pMinButton)
554 OnMinButtonMouseMove(pos);
555 else if (child == m_pMaxButton)
556 OnMaxButtonMouseMove(pos);
557 else if (child == m_pPosButton)
558 OnPosButtonMouseMove(pos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700559}
560
Tom Sepezbf157302017-09-15 13:26:32 -0700561void CPWL_ScrollBar::CreateButtons(const CreateParams& cp) {
562 CreateParams scp = cp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700563 scp.pParentWnd = this;
564 scp.dwBorderWidth = 2;
dsinclair92cb5e52016-05-16 11:38:28 -0700565 scp.nBorderStyle = BorderStyle::BEVELED;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700566
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700567 scp.dwFlags =
568 PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PWS_NOREFRESHCLIP;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700569
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570 if (!m_pMinButton) {
571 m_pMinButton = new CPWL_SBButton(m_sbType, PSBT_MIN);
572 m_pMinButton->Create(scp);
573 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700574
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700575 if (!m_pMaxButton) {
576 m_pMaxButton = new CPWL_SBButton(m_sbType, PSBT_MAX);
577 m_pMaxButton->Create(scp);
578 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700579
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700580 if (!m_pPosButton) {
581 m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400582
583 ObservedPtr thisObserved(this);
584 if (!m_pPosButton->SetVisible(false) || !thisObserved)
585 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700586 m_pPosButton->Create(scp);
587 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700588}
589
Dan Sinclair05df0752017-03-14 14:43:42 -0400590float CPWL_ScrollBar::GetScrollBarWidth() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700591 if (!IsVisible())
592 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700593
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700594 return PWL_SCROLLBAR_WIDTH;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700595}
596
Dan Sinclair05df0752017-03-14 14:43:42 -0400597void CPWL_ScrollBar::SetScrollRange(float fMin,
598 float fMax,
599 float fClientWidth) {
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400600 if (!m_pPosButton)
601 return;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700602
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400603 m_sData.SetScrollRange(fMin, fMax);
604 m_sData.SetClientWidth(fClientWidth);
605
606 ObservedPtr thisObserved(this);
607
608 if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
609 m_pPosButton->SetVisible(false);
610 // Note, |this| may no longer be viable at this point. If more work needs
611 // to be done, check thisObserved.
612 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700613 }
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400614
615 if (!m_pPosButton->SetVisible(true) || !thisObserved)
616 return;
617
618 MovePosButton(true);
619 // Note, |this| may no longer be viable at this point. If more work needs
620 // to be done, check the return value of MovePosButton().
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700621}
622
Dan Sinclair05df0752017-03-14 14:43:42 -0400623void CPWL_ScrollBar::SetScrollPos(float fPos) {
624 float fOldPos = m_sData.fScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700625 m_sData.SetPos(fPos);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400626 if (!IsFloatEqual(m_sData.fScrollPos, fOldPos)) {
tsepez4cf55152016-11-02 14:37:54 -0700627 MovePosButton(true);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400628 // Note, |this| may no longer be viable at this point. If more work needs
629 // to be done, check the return value of MovePosButton().
630 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700631}
632
Dan Sinclair05df0752017-03-14 14:43:42 -0400633void CPWL_ScrollBar::SetScrollStep(float fBigStep, float fSmallStep) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700634 m_sData.SetBigStep(fBigStep);
635 m_sData.SetSmallStep(fSmallStep);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700636}
637
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400638bool CPWL_ScrollBar::MovePosButton(bool bRefresh) {
Lei Zhang96660d62015-12-14 18:27:25 -0800639 ASSERT(m_pMinButton);
640 ASSERT(m_pMaxButton);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700641
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700642 if (m_pPosButton->IsVisible()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800643 CFX_FloatRect rcClient;
644 CFX_FloatRect rcPosArea, rcPosButton;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700645
646 rcClient = GetClientRect();
647 rcPosArea = GetScrollArea();
648
Dan Sinclair05df0752017-03-14 14:43:42 -0400649 float fLeft, fRight, fTop, fBottom;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700650
651 switch (m_sbType) {
652 case SBT_HSCROLL:
653 fLeft = TrueToFace(m_sData.fScrollPos);
654 fRight = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
655
Dan Sinclaira9e28432017-07-05 14:18:14 -0400656 if (fRight - fLeft < kPosButtonMinWidth)
657 fRight = fLeft + kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658
659 if (fRight > rcPosArea.right) {
660 fRight = rcPosArea.right;
Dan Sinclaira9e28432017-07-05 14:18:14 -0400661 fLeft = fRight - kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700662 }
663
Tom Sepez281a9ea2016-02-26 14:24:28 -0800664 rcPosButton =
665 CFX_FloatRect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700666
667 break;
668 case SBT_VSCROLL:
669 fBottom = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
670 fTop = TrueToFace(m_sData.fScrollPos);
671
Dan Sinclaira9e28432017-07-05 14:18:14 -0400672 if (IsFloatSmaller(fTop - fBottom, kPosButtonMinWidth))
673 fBottom = fTop - kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700674
675 if (IsFloatSmaller(fBottom, rcPosArea.bottom)) {
676 fBottom = rcPosArea.bottom;
Dan Sinclaira9e28432017-07-05 14:18:14 -0400677 fTop = fBottom + kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700678 }
679
Tom Sepez281a9ea2016-02-26 14:24:28 -0800680 rcPosButton =
681 CFX_FloatRect(rcPosArea.left, fBottom, rcPosArea.right, fTop);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700682
683 break;
684 }
685
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400686 ObservedPtr thisObserved(this);
687
tsepez4cf55152016-11-02 14:37:54 -0700688 m_pPosButton->Move(rcPosButton, true, bRefresh);
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400689 if (!thisObserved)
690 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700691 }
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400692
693 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700694}
695
Dan Sinclairf528eee2017-02-14 11:52:07 -0500696void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700697 m_sData.SubSmall();
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400698 if (!MovePosButton(true))
699 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700700 NotifyScrollWindow();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700701
tsepez4cf55152016-11-02 14:37:54 -0700702 m_bMinOrMax = true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700703
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700704 EndTimer();
705 BeginTimer(100);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700706}
707
Dan Sinclairf528eee2017-02-14 11:52:07 -0500708void CPWL_ScrollBar::OnMinButtonLBUp(const CFX_PointF& point) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700709
Dan Sinclairf528eee2017-02-14 11:52:07 -0500710void CPWL_ScrollBar::OnMinButtonMouseMove(const CFX_PointF& point) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700711
Dan Sinclairf528eee2017-02-14 11:52:07 -0500712void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700713 m_sData.AddSmall();
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400714 if (!MovePosButton(true))
715 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700716 NotifyScrollWindow();
717
tsepez4cf55152016-11-02 14:37:54 -0700718 m_bMinOrMax = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700719
720 EndTimer();
721 BeginTimer(100);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700722}
723
Dan Sinclairf528eee2017-02-14 11:52:07 -0500724void CPWL_ScrollBar::OnMaxButtonLBUp(const CFX_PointF& point) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700725
Dan Sinclairf528eee2017-02-14 11:52:07 -0500726void CPWL_ScrollBar::OnMaxButtonMouseMove(const CFX_PointF& point) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700727
Dan Sinclairf528eee2017-02-14 11:52:07 -0500728void CPWL_ScrollBar::OnPosButtonLBDown(const CFX_PointF& point) {
tsepez4cf55152016-11-02 14:37:54 -0700729 m_bMouseDown = true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700730
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700731 if (m_pPosButton) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800732 CFX_FloatRect rcPosButton = m_pPosButton->GetWindowRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700733
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700734 switch (m_sbType) {
735 case SBT_HSCROLL:
736 m_nOldPos = point.x;
737 m_fOldPosButton = rcPosButton.left;
738 break;
739 case SBT_VSCROLL:
740 m_nOldPos = point.y;
741 m_fOldPosButton = rcPosButton.top;
742 break;
743 }
744 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700745}
746
Dan Sinclairf528eee2017-02-14 11:52:07 -0500747void CPWL_ScrollBar::OnPosButtonLBUp(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700748 if (m_bMouseDown) {
749 if (!m_bNotifyForever)
750 NotifyScrollWindow();
751 }
tsepez4cf55152016-11-02 14:37:54 -0700752 m_bMouseDown = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700753}
754
Dan Sinclairf528eee2017-02-14 11:52:07 -0500755void CPWL_ScrollBar::OnPosButtonMouseMove(const CFX_PointF& point) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400756 float fOldScrollPos = m_sData.fScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700757
Dan Sinclair05df0752017-03-14 14:43:42 -0400758 float fNewPos = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759
760 switch (m_sbType) {
761 case SBT_HSCROLL:
Dan Sinclair669a4182017-04-03 14:51:45 -0400762 if (fabs(point.x - m_nOldPos) < 1)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700763 return;
764 fNewPos = FaceToTrue(m_fOldPosButton + point.x - m_nOldPos);
765 break;
766 case SBT_VSCROLL:
Dan Sinclair669a4182017-04-03 14:51:45 -0400767 if (fabs(point.y - m_nOldPos) < 1)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700768 return;
769 fNewPos = FaceToTrue(m_fOldPosButton + point.y - m_nOldPos);
770 break;
771 }
772
773 if (m_bMouseDown) {
774 switch (m_sbType) {
775 case SBT_HSCROLL:
776
777 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
778 fNewPos = m_sData.ScrollRange.fMin;
779 }
780
781 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
782 fNewPos = m_sData.ScrollRange.fMax;
783 }
784
785 m_sData.SetPos(fNewPos);
786
787 break;
788 case SBT_VSCROLL:
789
790 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
791 fNewPos = m_sData.ScrollRange.fMin;
792 }
793
794 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
795 fNewPos = m_sData.ScrollRange.fMax;
796 }
797
798 m_sData.SetPos(fNewPos);
799
800 break;
801 }
802
803 if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) {
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400804 if (!MovePosButton(true))
805 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700806
807 if (m_bNotifyForever)
808 NotifyScrollWindow();
809 }
810 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700811}
812
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700813void CPWL_ScrollBar::NotifyScrollWindow() {
Dan Sinclair63fbd8d2017-07-05 14:10:36 -0400814 CPWL_Wnd* pParent = GetParentWindow();
815 if (!pParent || m_sbType != SBT_VSCROLL)
816 return;
817
818 pParent->ScrollWindowVertically(m_OriginInfo.fContentMax -
819 m_sData.fScrollPos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700820}
821
Tom Sepez281a9ea2016-02-26 14:24:28 -0800822CFX_FloatRect CPWL_ScrollBar::GetScrollArea() const {
823 CFX_FloatRect rcClient = GetClientRect();
824 CFX_FloatRect rcArea;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700825
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700826 if (!m_pMinButton || !m_pMaxButton)
827 return rcClient;
Lei Zhang60f507b2015-06-13 00:41:00 -0700828
Tom Sepez281a9ea2016-02-26 14:24:28 -0800829 CFX_FloatRect rcMin = m_pMinButton->GetWindowRect();
830 CFX_FloatRect rcMax = m_pMaxButton->GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700831
Dan Sinclair05df0752017-03-14 14:43:42 -0400832 float fMinWidth = rcMin.right - rcMin.left;
833 float fMinHeight = rcMin.top - rcMin.bottom;
834 float fMaxWidth = rcMax.right - rcMax.left;
835 float fMaxHeight = rcMax.top - rcMax.bottom;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700836
837 switch (m_sbType) {
838 case SBT_HSCROLL:
839 if (rcClient.right - rcClient.left > fMinWidth + fMaxWidth + 2) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800840 rcArea = CFX_FloatRect(rcClient.left + fMinWidth + 1, rcClient.bottom,
841 rcClient.right - fMaxWidth - 1, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700842 } else {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800843 rcArea = CFX_FloatRect(rcClient.left + fMinWidth + 1, rcClient.bottom,
844 rcClient.left + fMinWidth + 1, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700845 }
846 break;
847 case SBT_VSCROLL:
848 if (rcClient.top - rcClient.bottom > fMinHeight + fMaxHeight + 2) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800849 rcArea = CFX_FloatRect(rcClient.left, rcClient.bottom + fMinHeight + 1,
850 rcClient.right, rcClient.top - fMaxHeight - 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700851 } else {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800852 rcArea =
853 CFX_FloatRect(rcClient.left, rcClient.bottom + fMinHeight + 1,
854 rcClient.right, rcClient.bottom + fMinHeight + 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700855 }
856 break;
857 }
858
859 rcArea.Normalize();
860
861 return rcArea;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700862}
863
Dan Sinclair05df0752017-03-14 14:43:42 -0400864float CPWL_ScrollBar::TrueToFace(float fTrue) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800865 CFX_FloatRect rcPosArea;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700866 rcPosArea = GetScrollArea();
867
Dan Sinclair05df0752017-03-14 14:43:42 -0400868 float fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700869 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;
870
Dan Sinclair05df0752017-03-14 14:43:42 -0400871 float fFace = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700872
873 switch (m_sbType) {
874 case SBT_HSCROLL:
875 fFace = rcPosArea.left +
876 fTrue * (rcPosArea.right - rcPosArea.left) / fFactWidth;
877 break;
878 case SBT_VSCROLL:
879 fFace = rcPosArea.top -
880 fTrue * (rcPosArea.top - rcPosArea.bottom) / fFactWidth;
881 break;
882 }
883
884 return fFace;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885}
886
Dan Sinclair05df0752017-03-14 14:43:42 -0400887float CPWL_ScrollBar::FaceToTrue(float fFace) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800888 CFX_FloatRect rcPosArea;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700889 rcPosArea = GetScrollArea();
890
Dan Sinclair05df0752017-03-14 14:43:42 -0400891 float fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700892 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;
893
Dan Sinclair05df0752017-03-14 14:43:42 -0400894 float fTrue = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700895
896 switch (m_sbType) {
897 case SBT_HSCROLL:
898 fTrue = (fFace - rcPosArea.left) * fFactWidth /
899 (rcPosArea.right - rcPosArea.left);
900 break;
901 case SBT_VSCROLL:
902 fTrue = (rcPosArea.top - fFace) * fFactWidth /
903 (rcPosArea.top - rcPosArea.bottom);
904 break;
905 }
906
907 return fTrue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700908}
909
Tom Sepezbf157302017-09-15 13:26:32 -0700910void CPWL_ScrollBar::CreateChildWnd(const CreateParams& cp) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700911 CreateButtons(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700912}
913
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700914void CPWL_ScrollBar::TimerProc() {
915 PWL_SCROLL_PRIVATEDATA sTemp = m_sData;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700916 if (m_bMinOrMax)
917 m_sData.SubSmall();
918 else
919 m_sData.AddSmall();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700920
tsepezf86ca382016-09-13 12:23:30 -0700921 if (sTemp != m_sData) {
Henrique Nakashima55469ae2017-10-04 11:08:45 -0400922 if (!MovePosButton(true))
923 return;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700924 NotifyScrollWindow();
925 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700926}