blob: 142988a8150c1fa9e5041d97f506c361837e53a3 [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 Sinclair7f55a542017-07-13 14:17:10 -040025#define PWL_DEFAULT_HEAVYGRAYCOLOR CFX_Color(COLORTYPE_GRAY, 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130CFX_ByteString CPWL_SBButton::GetClassName() const {
131 return "CPWL_SBButton";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700132}
133
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134void CPWL_SBButton::OnCreate(PWL_CREATEPARAM& cp) {
135 cp.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,
Tom Sepez60d909e2015-12-10 15:34:55 -0800139 CFX_Matrix* pUser2Device) {
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) {
151 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
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
Dan Sinclairc0993812017-07-05 17:17:08 -0400178 pDevice->DrawPath(&path, pUser2Device, nullptr,
179 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
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400186 pDevice->DrawStrokeRect(pUser2Device, rectWnd,
187 ArgbEncode(nTransparency, 100, 100, 100), 0.0f);
188 pDevice->DrawStrokeRect(pUser2Device, rectWnd.GetDeflated(0.5f, 0.5f),
189 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()) {
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400194 pDevice->DrawShadow(pUser2Device, true, false,
195 rectWnd.GetDeflated(1.0f, 1.0f), nTransparency, 80,
196 220);
Dan Sinclairc0993812017-07-05 17:17:08 -0400197 } else {
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400198 pDevice->DrawFillRect(pUser2Device, rectWnd.GetDeflated(1.0f, 1.0f),
199 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 }
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400224 pDevice->DrawFillArea(pUser2Device, pts.data(), 7,
225 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) {
251 pDevice->DrawStrokeLine(pUser2Device, 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 {
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400257 pDevice->DrawFillRect(pUser2Device, rectWnd.GetDeflated(0.5f, 0.5f),
258 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) {
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400278 pDevice->DrawStrokeLine(pUser2Device, 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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328CFX_ByteString CPWL_ScrollBar::GetClassName() const {
329 return "CPWL_ScrollBar";
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
331
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332void CPWL_ScrollBar::OnCreate(PWL_CREATEPARAM& cp) {
333 cp.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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347void 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 {
tsepez4cf55152016-11-02 14:37:54 -0700370 SetVisible(false);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800371 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 }
373 break;
374 case SBT_VSCROLL:
375 if (IsFloatBigger(rcClient.top - rcClient.bottom,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400376 kButtonWidth * 2 + kPosButtonMinWidth + 2)) {
377 rcMinButton = CFX_FloatRect(rcClient.left, rcClient.top - kButtonWidth,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800378 rcClient.right, rcClient.top);
379 rcMaxButton =
380 CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400381 rcClient.bottom + kButtonWidth);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382 } else {
Dan Sinclaira9e28432017-07-05 14:18:14 -0400383 fBWidth = (rcClient.top - rcClient.bottom - kPosButtonMinWidth - 2) / 2;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384
385 if (IsFloatBigger(fBWidth, 0)) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800386 rcMinButton = CFX_FloatRect(rcClient.left, rcClient.top - fBWidth,
387 rcClient.right, rcClient.top);
388 rcMaxButton =
389 CFX_FloatRect(rcClient.left, rcClient.bottom, rcClient.right,
390 rcClient.bottom + fBWidth);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800391 } else {
tsepez4cf55152016-11-02 14:37:54 -0700392 SetVisible(false);
Lei Zhangc2fb35f2016-01-05 16:46:58 -0800393 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394 }
395 break;
396 }
397
398 if (m_pMinButton)
tsepez4cf55152016-11-02 14:37:54 -0700399 m_pMinButton->Move(rcMinButton, true, false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700400 if (m_pMaxButton)
tsepez4cf55152016-11-02 14:37:54 -0700401 m_pMaxButton->Move(rcMaxButton, true, false);
402 MovePosButton(false);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700403}
404
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700405void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice,
Tom Sepez60d909e2015-12-10 15:34:55 -0800406 CFX_Matrix* pUser2Device) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800407 CFX_FloatRect rectWnd = GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408
409 if (IsVisible() && !rectWnd.IsEmpty()) {
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400410 pDevice->DrawFillRect(pUser2Device, rectWnd, GetBackgroundColor(),
411 GetTransparency());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400413 pDevice->DrawStrokeLine(
414 pUser2Device, CFX_PointF(rectWnd.left + 2.0f, rectWnd.top - 2.0f),
Dan Sinclairf528eee2017-02-14 11:52:07 -0500415 CFX_PointF(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700416 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
417
Dan Sinclair0b7378a2017-07-17 12:05:40 -0400418 pDevice->DrawStrokeLine(
419 pUser2Device, CFX_PointF(rectWnd.right - 2.0f, rectWnd.top - 2.0f),
Dan Sinclairf528eee2017-02-14 11:52:07 -0500420 CFX_PointF(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f),
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
422 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700423}
424
Dan Sinclairf528eee2017-02-14 11:52:07 -0500425bool CPWL_ScrollBar::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426 CPWL_Wnd::OnLButtonDown(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700427
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700428 if (HasFlag(PWS_AUTOTRANSPARENT)) {
429 if (GetTransparency() != 255) {
430 SetTransparency(255);
Lei Zhang33c03002017-08-15 11:18:19 -0700431 InvalidateRect(nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432 }
433 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700434
Tom Sepez281a9ea2016-02-26 14:24:28 -0800435 CFX_FloatRect rcMinArea, rcMaxArea;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700436
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700437 if (m_pPosButton && m_pPosButton->IsVisible()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800438 CFX_FloatRect rcClient = GetClientRect();
439 CFX_FloatRect rcPosButton = m_pPosButton->GetWindowRect();
Lei Zhang60f507b2015-06-13 00:41:00 -0700440
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700441 switch (m_sbType) {
442 case SBT_HSCROLL:
Dan Sinclaira9e28432017-07-05 14:18:14 -0400443 rcMinArea = CFX_FloatRect(rcClient.left + kButtonWidth, rcClient.bottom,
444 rcPosButton.left, rcClient.top);
Tom Sepez281a9ea2016-02-26 14:24:28 -0800445 rcMaxArea = CFX_FloatRect(rcPosButton.right, rcClient.bottom,
Dan Sinclaira9e28432017-07-05 14:18:14 -0400446 rcClient.right - kButtonWidth, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447
448 break;
449 case SBT_VSCROLL:
Dan Sinclaira9e28432017-07-05 14:18:14 -0400450 rcMinArea = CFX_FloatRect(rcClient.left, rcPosButton.top,
451 rcClient.right, rcClient.top - kButtonWidth);
452 rcMaxArea = CFX_FloatRect(rcClient.left, rcClient.bottom + kButtonWidth,
Tom Sepez281a9ea2016-02-26 14:24:28 -0800453 rcClient.right, rcPosButton.bottom);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454 break;
455 }
456
457 rcMinArea.Normalize();
458 rcMaxArea.Normalize();
459
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500460 if (rcMinArea.Contains(point)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461 m_sData.SubBig();
tsepez4cf55152016-11-02 14:37:54 -0700462 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463 NotifyScrollWindow();
464 }
465
Dan Sinclairb45ea1f2017-02-21 14:27:59 -0500466 if (rcMaxArea.Contains(point)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700467 m_sData.AddBig();
tsepez4cf55152016-11-02 14:37:54 -0700468 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700469 NotifyScrollWindow();
470 }
471 }
472
tsepez4cf55152016-11-02 14:37:54 -0700473 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700474}
475
Dan Sinclairf528eee2017-02-14 11:52:07 -0500476bool CPWL_ScrollBar::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477 CPWL_Wnd::OnLButtonUp(point, nFlag);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700478
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700479 if (HasFlag(PWS_AUTOTRANSPARENT)) {
Dan Sinclairfc54e052017-02-23 09:59:05 -0500480 if (GetTransparency() != PWL_SCROLLBAR_TRANSPARENCY) {
481 SetTransparency(PWL_SCROLLBAR_TRANSPARENCY);
Lei Zhang33c03002017-08-15 11:18:19 -0700482 InvalidateRect(nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700483 }
484 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700485
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486 EndTimer();
tsepez4cf55152016-11-02 14:37:54 -0700487 m_bMouseDown = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700488
tsepez4cf55152016-11-02 14:37:54 -0700489 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700490}
491
Dan Sinclairfb00ec22017-07-05 09:28:15 -0400492void CPWL_ScrollBar::SetScrollInfo(const PWL_SCROLL_INFO& info) {
493 if (info == m_OriginInfo)
494 return;
495
496 m_OriginInfo = info;
497 float fMax =
498 std::max(0.0f, info.fContentMax - info.fContentMin - info.fPlateWidth);
499 SetScrollRange(0, fMax, info.fPlateWidth);
500 SetScrollStep(info.fBigStep, info.fSmallStep);
501}
502
Dan Sinclair7e0336e2017-07-05 09:39:50 -0400503void CPWL_ScrollBar::SetScrollPosition(float pos) {
504 switch (m_sbType) {
505 case SBT_HSCROLL:
506 pos = pos - m_OriginInfo.fContentMin;
507 break;
508 case SBT_VSCROLL:
509 pos = m_OriginInfo.fContentMax - pos;
510 break;
511 }
512 SetScrollPos(pos);
513}
514
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400515void CPWL_ScrollBar::NotifyLButtonDown(CPWL_Wnd* child, const CFX_PointF& pos) {
516 if (child == m_pMinButton)
517 OnMinButtonLBDown(pos);
518 else if (child == m_pMaxButton)
519 OnMaxButtonLBDown(pos);
520 else if (child == m_pPosButton)
521 OnPosButtonLBDown(pos);
522}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700523
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400524void CPWL_ScrollBar::NotifyLButtonUp(CPWL_Wnd* child, const CFX_PointF& pos) {
525 if (child == m_pMinButton)
526 OnMinButtonLBUp(pos);
527 else if (child == m_pMaxButton)
528 OnMaxButtonLBUp(pos);
529 else if (child == m_pPosButton)
530 OnPosButtonLBUp(pos);
531}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700532
Dan Sinclair7f6bec92017-07-05 14:13:16 -0400533void CPWL_ScrollBar::NotifyMouseMove(CPWL_Wnd* child, const CFX_PointF& pos) {
534 if (child == m_pMinButton)
535 OnMinButtonMouseMove(pos);
536 else if (child == m_pMaxButton)
537 OnMaxButtonMouseMove(pos);
538 else if (child == m_pPosButton)
539 OnPosButtonMouseMove(pos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700540}
541
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542void CPWL_ScrollBar::CreateButtons(const PWL_CREATEPARAM& cp) {
543 PWL_CREATEPARAM scp = cp;
544 scp.pParentWnd = this;
545 scp.dwBorderWidth = 2;
dsinclair92cb5e52016-05-16 11:38:28 -0700546 scp.nBorderStyle = BorderStyle::BEVELED;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700547
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700548 scp.dwFlags =
549 PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PWS_NOREFRESHCLIP;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700550
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551 if (!m_pMinButton) {
552 m_pMinButton = new CPWL_SBButton(m_sbType, PSBT_MIN);
553 m_pMinButton->Create(scp);
554 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700555
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556 if (!m_pMaxButton) {
557 m_pMaxButton = new CPWL_SBButton(m_sbType, PSBT_MAX);
558 m_pMaxButton->Create(scp);
559 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700560
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700561 if (!m_pPosButton) {
562 m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS);
tsepez4cf55152016-11-02 14:37:54 -0700563 m_pPosButton->SetVisible(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564 m_pPosButton->Create(scp);
565 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700566}
567
Dan Sinclair05df0752017-03-14 14:43:42 -0400568float CPWL_ScrollBar::GetScrollBarWidth() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569 if (!IsVisible())
570 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700571
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700572 return PWL_SCROLLBAR_WIDTH;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700573}
574
Dan Sinclair05df0752017-03-14 14:43:42 -0400575void CPWL_ScrollBar::SetScrollRange(float fMin,
576 float fMax,
577 float fClientWidth) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700578 if (m_pPosButton) {
579 m_sData.SetScrollRange(fMin, fMax);
580 m_sData.SetClientWidth(fClientWidth);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700581
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582 if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
tsepez4cf55152016-11-02 14:37:54 -0700583 m_pPosButton->SetVisible(false);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700584 } else {
tsepez4cf55152016-11-02 14:37:54 -0700585 m_pPosButton->SetVisible(true);
586 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700587 }
588 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700589}
590
Dan Sinclair05df0752017-03-14 14:43:42 -0400591void CPWL_ScrollBar::SetScrollPos(float fPos) {
592 float fOldPos = m_sData.fScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700593 m_sData.SetPos(fPos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700594 if (!IsFloatEqual(m_sData.fScrollPos, fOldPos))
tsepez4cf55152016-11-02 14:37:54 -0700595 MovePosButton(true);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700596}
597
Dan Sinclair05df0752017-03-14 14:43:42 -0400598void CPWL_ScrollBar::SetScrollStep(float fBigStep, float fSmallStep) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700599 m_sData.SetBigStep(fBigStep);
600 m_sData.SetSmallStep(fSmallStep);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700601}
602
tsepez4cf55152016-11-02 14:37:54 -0700603void CPWL_ScrollBar::MovePosButton(bool bRefresh) {
Lei Zhang96660d62015-12-14 18:27:25 -0800604 ASSERT(m_pMinButton);
605 ASSERT(m_pMaxButton);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700606
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700607 if (m_pPosButton->IsVisible()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800608 CFX_FloatRect rcClient;
609 CFX_FloatRect rcPosArea, rcPosButton;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700610
611 rcClient = GetClientRect();
612 rcPosArea = GetScrollArea();
613
Dan Sinclair05df0752017-03-14 14:43:42 -0400614 float fLeft, fRight, fTop, fBottom;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700615
616 switch (m_sbType) {
617 case SBT_HSCROLL:
618 fLeft = TrueToFace(m_sData.fScrollPos);
619 fRight = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
620
Dan Sinclaira9e28432017-07-05 14:18:14 -0400621 if (fRight - fLeft < kPosButtonMinWidth)
622 fRight = fLeft + kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700623
624 if (fRight > rcPosArea.right) {
625 fRight = rcPosArea.right;
Dan Sinclaira9e28432017-07-05 14:18:14 -0400626 fLeft = fRight - kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700627 }
628
Tom Sepez281a9ea2016-02-26 14:24:28 -0800629 rcPosButton =
630 CFX_FloatRect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700631
632 break;
633 case SBT_VSCROLL:
634 fBottom = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
635 fTop = TrueToFace(m_sData.fScrollPos);
636
Dan Sinclaira9e28432017-07-05 14:18:14 -0400637 if (IsFloatSmaller(fTop - fBottom, kPosButtonMinWidth))
638 fBottom = fTop - kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700639
640 if (IsFloatSmaller(fBottom, rcPosArea.bottom)) {
641 fBottom = rcPosArea.bottom;
Dan Sinclaira9e28432017-07-05 14:18:14 -0400642 fTop = fBottom + kPosButtonMinWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700643 }
644
Tom Sepez281a9ea2016-02-26 14:24:28 -0800645 rcPosButton =
646 CFX_FloatRect(rcPosArea.left, fBottom, rcPosArea.right, fTop);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700647
648 break;
649 }
650
tsepez4cf55152016-11-02 14:37:54 -0700651 m_pPosButton->Move(rcPosButton, true, bRefresh);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700652 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700653}
654
Dan Sinclairf528eee2017-02-14 11:52:07 -0500655void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700656 m_sData.SubSmall();
tsepez4cf55152016-11-02 14:37:54 -0700657 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658 NotifyScrollWindow();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700659
tsepez4cf55152016-11-02 14:37:54 -0700660 m_bMinOrMax = true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700661
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700662 EndTimer();
663 BeginTimer(100);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700664}
665
Dan Sinclairf528eee2017-02-14 11:52:07 -0500666void CPWL_ScrollBar::OnMinButtonLBUp(const CFX_PointF& point) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700667
Dan Sinclairf528eee2017-02-14 11:52:07 -0500668void CPWL_ScrollBar::OnMinButtonMouseMove(const CFX_PointF& point) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700669
Dan Sinclairf528eee2017-02-14 11:52:07 -0500670void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700671 m_sData.AddSmall();
tsepez4cf55152016-11-02 14:37:54 -0700672 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700673 NotifyScrollWindow();
674
tsepez4cf55152016-11-02 14:37:54 -0700675 m_bMinOrMax = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700676
677 EndTimer();
678 BeginTimer(100);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700679}
680
Dan Sinclairf528eee2017-02-14 11:52:07 -0500681void CPWL_ScrollBar::OnMaxButtonLBUp(const CFX_PointF& point) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700682
Dan Sinclairf528eee2017-02-14 11:52:07 -0500683void CPWL_ScrollBar::OnMaxButtonMouseMove(const CFX_PointF& point) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700684
Dan Sinclairf528eee2017-02-14 11:52:07 -0500685void CPWL_ScrollBar::OnPosButtonLBDown(const CFX_PointF& point) {
tsepez4cf55152016-11-02 14:37:54 -0700686 m_bMouseDown = true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700687
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700688 if (m_pPosButton) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800689 CFX_FloatRect rcPosButton = m_pPosButton->GetWindowRect();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700690
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700691 switch (m_sbType) {
692 case SBT_HSCROLL:
693 m_nOldPos = point.x;
694 m_fOldPosButton = rcPosButton.left;
695 break;
696 case SBT_VSCROLL:
697 m_nOldPos = point.y;
698 m_fOldPosButton = rcPosButton.top;
699 break;
700 }
701 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700702}
703
Dan Sinclairf528eee2017-02-14 11:52:07 -0500704void CPWL_ScrollBar::OnPosButtonLBUp(const CFX_PointF& point) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700705 if (m_bMouseDown) {
706 if (!m_bNotifyForever)
707 NotifyScrollWindow();
708 }
tsepez4cf55152016-11-02 14:37:54 -0700709 m_bMouseDown = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700710}
711
Dan Sinclairf528eee2017-02-14 11:52:07 -0500712void CPWL_ScrollBar::OnPosButtonMouseMove(const CFX_PointF& point) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400713 float fOldScrollPos = m_sData.fScrollPos;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700714
Dan Sinclair05df0752017-03-14 14:43:42 -0400715 float fNewPos = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700716
717 switch (m_sbType) {
718 case SBT_HSCROLL:
Dan Sinclair669a4182017-04-03 14:51:45 -0400719 if (fabs(point.x - m_nOldPos) < 1)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700720 return;
721 fNewPos = FaceToTrue(m_fOldPosButton + point.x - m_nOldPos);
722 break;
723 case SBT_VSCROLL:
Dan Sinclair669a4182017-04-03 14:51:45 -0400724 if (fabs(point.y - m_nOldPos) < 1)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700725 return;
726 fNewPos = FaceToTrue(m_fOldPosButton + point.y - m_nOldPos);
727 break;
728 }
729
730 if (m_bMouseDown) {
731 switch (m_sbType) {
732 case SBT_HSCROLL:
733
734 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
735 fNewPos = m_sData.ScrollRange.fMin;
736 }
737
738 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
739 fNewPos = m_sData.ScrollRange.fMax;
740 }
741
742 m_sData.SetPos(fNewPos);
743
744 break;
745 case SBT_VSCROLL:
746
747 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
748 fNewPos = m_sData.ScrollRange.fMin;
749 }
750
751 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
752 fNewPos = m_sData.ScrollRange.fMax;
753 }
754
755 m_sData.SetPos(fNewPos);
756
757 break;
758 }
759
760 if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) {
tsepez4cf55152016-11-02 14:37:54 -0700761 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700762
763 if (m_bNotifyForever)
764 NotifyScrollWindow();
765 }
766 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700767}
768
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700769void CPWL_ScrollBar::NotifyScrollWindow() {
Dan Sinclair63fbd8d2017-07-05 14:10:36 -0400770 CPWL_Wnd* pParent = GetParentWindow();
771 if (!pParent || m_sbType != SBT_VSCROLL)
772 return;
773
774 pParent->ScrollWindowVertically(m_OriginInfo.fContentMax -
775 m_sData.fScrollPos);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700776}
777
Tom Sepez281a9ea2016-02-26 14:24:28 -0800778CFX_FloatRect CPWL_ScrollBar::GetScrollArea() const {
779 CFX_FloatRect rcClient = GetClientRect();
780 CFX_FloatRect rcArea;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700781
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700782 if (!m_pMinButton || !m_pMaxButton)
783 return rcClient;
Lei Zhang60f507b2015-06-13 00:41:00 -0700784
Tom Sepez281a9ea2016-02-26 14:24:28 -0800785 CFX_FloatRect rcMin = m_pMinButton->GetWindowRect();
786 CFX_FloatRect rcMax = m_pMaxButton->GetWindowRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700787
Dan Sinclair05df0752017-03-14 14:43:42 -0400788 float fMinWidth = rcMin.right - rcMin.left;
789 float fMinHeight = rcMin.top - rcMin.bottom;
790 float fMaxWidth = rcMax.right - rcMax.left;
791 float fMaxHeight = rcMax.top - rcMax.bottom;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700792
793 switch (m_sbType) {
794 case SBT_HSCROLL:
795 if (rcClient.right - rcClient.left > fMinWidth + fMaxWidth + 2) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800796 rcArea = CFX_FloatRect(rcClient.left + fMinWidth + 1, rcClient.bottom,
797 rcClient.right - fMaxWidth - 1, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700798 } else {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800799 rcArea = CFX_FloatRect(rcClient.left + fMinWidth + 1, rcClient.bottom,
800 rcClient.left + fMinWidth + 1, rcClient.top);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700801 }
802 break;
803 case SBT_VSCROLL:
804 if (rcClient.top - rcClient.bottom > fMinHeight + fMaxHeight + 2) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800805 rcArea = CFX_FloatRect(rcClient.left, rcClient.bottom + fMinHeight + 1,
806 rcClient.right, rcClient.top - fMaxHeight - 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700807 } else {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800808 rcArea =
809 CFX_FloatRect(rcClient.left, rcClient.bottom + fMinHeight + 1,
810 rcClient.right, rcClient.bottom + fMinHeight + 1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700811 }
812 break;
813 }
814
815 rcArea.Normalize();
816
817 return rcArea;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700818}
819
Dan Sinclair05df0752017-03-14 14:43:42 -0400820float CPWL_ScrollBar::TrueToFace(float fTrue) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800821 CFX_FloatRect rcPosArea;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700822 rcPosArea = GetScrollArea();
823
Dan Sinclair05df0752017-03-14 14:43:42 -0400824 float fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700825 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;
826
Dan Sinclair05df0752017-03-14 14:43:42 -0400827 float fFace = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700828
829 switch (m_sbType) {
830 case SBT_HSCROLL:
831 fFace = rcPosArea.left +
832 fTrue * (rcPosArea.right - rcPosArea.left) / fFactWidth;
833 break;
834 case SBT_VSCROLL:
835 fFace = rcPosArea.top -
836 fTrue * (rcPosArea.top - rcPosArea.bottom) / fFactWidth;
837 break;
838 }
839
840 return fFace;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700841}
842
Dan Sinclair05df0752017-03-14 14:43:42 -0400843float CPWL_ScrollBar::FaceToTrue(float fFace) {
Tom Sepez281a9ea2016-02-26 14:24:28 -0800844 CFX_FloatRect rcPosArea;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700845 rcPosArea = GetScrollArea();
846
Dan Sinclair05df0752017-03-14 14:43:42 -0400847 float fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700848 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;
849
Dan Sinclair05df0752017-03-14 14:43:42 -0400850 float fTrue = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700851
852 switch (m_sbType) {
853 case SBT_HSCROLL:
854 fTrue = (fFace - rcPosArea.left) * fFactWidth /
855 (rcPosArea.right - rcPosArea.left);
856 break;
857 case SBT_VSCROLL:
858 fTrue = (rcPosArea.top - fFace) * fFactWidth /
859 (rcPosArea.top - rcPosArea.bottom);
860 break;
861 }
862
863 return fTrue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700864}
865
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700866void CPWL_ScrollBar::CreateChildWnd(const PWL_CREATEPARAM& cp) {
867 CreateButtons(cp);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700868}
869
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700870void CPWL_ScrollBar::TimerProc() {
871 PWL_SCROLL_PRIVATEDATA sTemp = m_sData;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700872 if (m_bMinOrMax)
873 m_sData.SubSmall();
874 else
875 m_sData.AddSmall();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700876
tsepezf86ca382016-09-13 12:23:30 -0700877 if (sTemp != m_sData) {
tsepez4cf55152016-11-02 14:37:54 -0700878 MovePosButton(true);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700879 NotifyScrollWindow();
880 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700881}