1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
8 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
9 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"
10
11 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
12 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
13 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
14 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))
15
PWL_FLOATRANGE()16 PWL_FLOATRANGE::PWL_FLOATRANGE() {
17 Default();
18 }
19
PWL_FLOATRANGE(FX_FLOAT min,FX_FLOAT max)20 PWL_FLOATRANGE::PWL_FLOATRANGE(FX_FLOAT min, FX_FLOAT max) {
21 Set(min, max);
22 }
23
Default()24 void PWL_FLOATRANGE::Default() {
25 fMin = 0;
26 fMax = 0;
27 }
28
Set(FX_FLOAT min,FX_FLOAT max)29 void PWL_FLOATRANGE::Set(FX_FLOAT min, FX_FLOAT max) {
30 if (min > max) {
31 fMin = max;
32 fMax = min;
33 } else {
34 fMin = min;
35 fMax = max;
36 }
37 }
38
In(FX_FLOAT x) const39 FX_BOOL PWL_FLOATRANGE::In(FX_FLOAT x) const {
40 return (IsFloatBigger(x, fMin) || IsFloatEqual(x, fMin)) &&
41 (IsFloatSmaller(x, fMax) || IsFloatEqual(x, fMax));
42 }
43
GetWidth() const44 FX_FLOAT PWL_FLOATRANGE::GetWidth() const {
45 return fMax - fMin;
46 }
47
PWL_SCROLL_PRIVATEDATA()48 PWL_SCROLL_PRIVATEDATA::PWL_SCROLL_PRIVATEDATA() {
49 Default();
50 }
51
Default()52 void PWL_SCROLL_PRIVATEDATA::Default() {
53 ScrollRange.Default();
54 fScrollPos = ScrollRange.fMin;
55 fClientWidth = 0;
56 fBigStep = 10;
57 fSmallStep = 1;
58 }
59
SetScrollRange(FX_FLOAT min,FX_FLOAT max)60 void PWL_SCROLL_PRIVATEDATA::SetScrollRange(FX_FLOAT min, FX_FLOAT max) {
61 ScrollRange.Set(min, max);
62
63 if (IsFloatSmaller(fScrollPos, ScrollRange.fMin))
64 fScrollPos = ScrollRange.fMin;
65 if (IsFloatBigger(fScrollPos, ScrollRange.fMax))
66 fScrollPos = ScrollRange.fMax;
67 }
68
SetClientWidth(FX_FLOAT width)69 void PWL_SCROLL_PRIVATEDATA::SetClientWidth(FX_FLOAT width) {
70 fClientWidth = width;
71 }
72
SetSmallStep(FX_FLOAT step)73 void PWL_SCROLL_PRIVATEDATA::SetSmallStep(FX_FLOAT step) {
74 fSmallStep = step;
75 }
76
SetBigStep(FX_FLOAT step)77 void PWL_SCROLL_PRIVATEDATA::SetBigStep(FX_FLOAT step) {
78 fBigStep = step;
79 }
80
SetPos(FX_FLOAT pos)81 FX_BOOL PWL_SCROLL_PRIVATEDATA::SetPos(FX_FLOAT pos) {
82 if (ScrollRange.In(pos)) {
83 fScrollPos = pos;
84 return TRUE;
85 }
86 return FALSE;
87 }
88
AddSmall()89 void PWL_SCROLL_PRIVATEDATA::AddSmall() {
90 if (!SetPos(fScrollPos + fSmallStep))
91 SetPos(ScrollRange.fMax);
92 }
93
SubSmall()94 void PWL_SCROLL_PRIVATEDATA::SubSmall() {
95 if (!SetPos(fScrollPos - fSmallStep))
96 SetPos(ScrollRange.fMin);
97 }
98
AddBig()99 void PWL_SCROLL_PRIVATEDATA::AddBig() {
100 if (!SetPos(fScrollPos + fBigStep))
101 SetPos(ScrollRange.fMax);
102 }
103
SubBig()104 void PWL_SCROLL_PRIVATEDATA::SubBig() {
105 if (!SetPos(fScrollPos - fBigStep))
106 SetPos(ScrollRange.fMin);
107 }
108
CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,PWL_SBBUTTON_TYPE eButtonType)109 CPWL_SBButton::CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,
110 PWL_SBBUTTON_TYPE eButtonType) {
111 m_eScrollBarType = eScrollBarType;
112 m_eSBButtonType = eButtonType;
113
114 m_bMouseDown = FALSE;
115 }
116
~CPWL_SBButton()117 CPWL_SBButton::~CPWL_SBButton() {}
118
GetClassName() const119 CFX_ByteString CPWL_SBButton::GetClassName() const {
120 return "CPWL_SBButton";
121 }
122
OnCreate(PWL_CREATEPARAM & cp)123 void CPWL_SBButton::OnCreate(PWL_CREATEPARAM& cp) {
124 cp.eCursorType = FXCT_ARROW;
125 }
126
GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)127 void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
128 CPWL_Wnd::GetThisAppearanceStream(sAppStream);
129
130 if (!IsVisible())
131 return;
132
133 CFX_ByteTextBuf sButton;
134
135 CPDF_Rect rectWnd = GetWindowRect();
136
137 if (rectWnd.IsEmpty())
138 return;
139
140 sAppStream << "q\n";
141
142 CPDF_Point ptCenter = GetCenterPoint();
143
144 switch (m_eScrollBarType) {
145 case SBT_HSCROLL:
146 switch (m_eSBButtonType) {
147 case PSBT_MIN: {
148 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
149 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
150 ptCenter.y + PWL_TRIANGLE_HALFLEN);
151 CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
152 ptCenter.y - PWL_TRIANGLE_HALFLEN);
153
154 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
155 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
156 sButton << "0 g\n";
157 sButton << pt1.x << " " << pt1.y << " m\n";
158 sButton << pt2.x << " " << pt2.y << " l\n";
159 sButton << pt3.x << " " << pt3.y << " l\n";
160 sButton << pt1.x << " " << pt1.y << " l f\n";
161
162 sAppStream << sButton;
163 }
164 } break;
165 case PSBT_MAX: {
166 CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
167 CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
168 ptCenter.y + PWL_TRIANGLE_HALFLEN);
169 CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
170 ptCenter.y - PWL_TRIANGLE_HALFLEN);
171
172 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
173 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
174 sButton << "0 g\n";
175 sButton << pt1.x << " " << pt1.y << " m\n";
176 sButton << pt2.x << " " << pt2.y << " l\n";
177 sButton << pt3.x << " " << pt3.y << " l\n";
178 sButton << pt1.x << " " << pt1.y << " l f\n";
179
180 sAppStream << sButton;
181 }
182 } break;
183 default:
184 break;
185 }
186 break;
187 case SBT_VSCROLL:
188 switch (m_eSBButtonType) {
189 case PSBT_MIN: {
190 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
191 ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
192 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
193 ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
194 CPDF_Point pt3(ptCenter.x, ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
195
196 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
197 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
198 sButton << "0 g\n";
199 sButton << pt1.x << " " << pt1.y << " m\n";
200 sButton << pt2.x << " " << pt2.y << " l\n";
201 sButton << pt3.x << " " << pt3.y << " l\n";
202 sButton << pt1.x << " " << pt1.y << " l f\n";
203
204 sAppStream << sButton;
205 }
206 } break;
207 case PSBT_MAX: {
208 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
209 ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
210 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
211 ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
212 CPDF_Point pt3(ptCenter.x, ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
213
214 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
215 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
216 sButton << "0 g\n";
217 sButton << pt1.x << " " << pt1.y << " m\n";
218 sButton << pt2.x << " " << pt2.y << " l\n";
219 sButton << pt3.x << " " << pt3.y << " l\n";
220 sButton << pt1.x << " " << pt1.y << " l f\n";
221
222 sAppStream << sButton;
223 }
224 } break;
225 default:
226 break;
227 }
228 break;
229 default:
230 break;
231 }
232
233 sAppStream << "Q\n";
234 }
235
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)236 void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
237 CFX_Matrix* pUser2Device) {
238 if (!IsVisible())
239 return;
240
241 CPDF_Rect rectWnd = GetWindowRect();
242 if (rectWnd.IsEmpty())
243 return;
244
245 CPDF_Point ptCenter = GetCenterPoint();
246 int32_t nTransparancy = GetTransparency();
247
248 switch (m_eScrollBarType) {
249 case SBT_HSCROLL:
250 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
251 switch (m_eSBButtonType) {
252 case PSBT_MIN: {
253 CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
254 CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
255 ptCenter.y + PWL_TRIANGLE_HALFLEN);
256 CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
257 ptCenter.y - PWL_TRIANGLE_HALFLEN);
258
259 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
260 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
261 CFX_PathData path;
262
263 path.SetPointCount(4);
264 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
265 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
266 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
267 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
268
269 pDevice->DrawPath(&path, pUser2Device, NULL,
270 CPWL_Utils::PWLColorToFXColor(
271 PWL_DEFAULT_BLACKCOLOR, nTransparancy),
272 0, FXFILL_ALTERNATE);
273 }
274 } break;
275 case PSBT_MAX: {
276 CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
277 CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
278 ptCenter.y + PWL_TRIANGLE_HALFLEN);
279 CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
280 ptCenter.y - PWL_TRIANGLE_HALFLEN);
281
282 if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
283 rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
284 CFX_PathData path;
285
286 path.SetPointCount(4);
287 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
288 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
289 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
290 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);
291
292 pDevice->DrawPath(&path, pUser2Device, NULL,
293 CPWL_Utils::PWLColorToFXColor(
294 PWL_DEFAULT_BLACKCOLOR, nTransparancy),
295 0, FXFILL_ALTERNATE);
296 }
297 } break;
298 default:
299 break;
300 }
301 break;
302 case SBT_VSCROLL:
303 switch (m_eSBButtonType) {
304 case PSBT_MIN: {
305 // draw border
306 CPDF_Rect rcDraw = rectWnd;
307 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
308 ArgbEncode(nTransparancy, 100, 100, 100),
309 0.0f);
310
311 // draw inner border
312 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f);
313 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
314 ArgbEncode(nTransparancy, 255, 255, 255),
315 1.0f);
316
317 // draw background
318
319 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f);
320
321 if (IsEnabled())
322 CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw,
323 nTransparancy, 80, 220);
324 else
325 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
326 ArgbEncode(255, 255, 255, 255));
327
328 // draw arrow
329
330 if (rectWnd.top - rectWnd.bottom > 6.0f) {
331 FX_FLOAT fX = rectWnd.left + 1.5f;
332 FX_FLOAT fY = rectWnd.bottom;
333 CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 4.0f),
334 CPDF_Point(fX + 2.5f, fY + 3.0f),
335 CPDF_Point(fX + 4.5f, fY + 5.0f),
336 CPDF_Point(fX + 6.5f, fY + 3.0f),
337 CPDF_Point(fX + 6.5f, fY + 4.0f),
338 CPDF_Point(fX + 4.5f, fY + 6.0f),
339 CPDF_Point(fX + 2.5f, fY + 4.0f)};
340
341 if (IsEnabled())
342 CPWL_Utils::DrawFillArea(
343 pDevice, pUser2Device, pts, 7,
344 ArgbEncode(nTransparancy, 255, 255, 255));
345 else
346 CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7,
347 CPWL_Utils::PWLColorToFXColor(
348 PWL_DEFAULT_HEAVYGRAYCOLOR, 255));
349 }
350 } break;
351 case PSBT_MAX: {
352 // draw border
353 CPDF_Rect rcDraw = rectWnd;
354 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
355 ArgbEncode(nTransparancy, 100, 100, 100),
356 0.0f);
357
358 // draw inner border
359 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f);
360 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
361 ArgbEncode(nTransparancy, 255, 255, 255),
362 1.0f);
363
364 // draw background
365 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f);
366 if (IsEnabled())
367 CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw,
368 nTransparancy, 80, 220);
369 else
370 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
371 ArgbEncode(255, 255, 255, 255));
372
373 // draw arrow
374
375 if (rectWnd.top - rectWnd.bottom > 6.0f) {
376 FX_FLOAT fX = rectWnd.left + 1.5f;
377 FX_FLOAT fY = rectWnd.bottom;
378
379 CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 5.0f),
380 CPDF_Point(fX + 2.5f, fY + 6.0f),
381 CPDF_Point(fX + 4.5f, fY + 4.0f),
382 CPDF_Point(fX + 6.5f, fY + 6.0f),
383 CPDF_Point(fX + 6.5f, fY + 5.0f),
384 CPDF_Point(fX + 4.5f, fY + 3.0f),
385 CPDF_Point(fX + 2.5f, fY + 5.0f)};
386
387 if (IsEnabled())
388 CPWL_Utils::DrawFillArea(
389 pDevice, pUser2Device, pts, 7,
390 ArgbEncode(nTransparancy, 255, 255, 255));
391 else
392 CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7,
393 CPWL_Utils::PWLColorToFXColor(
394 PWL_DEFAULT_HEAVYGRAYCOLOR, 255));
395 }
396 } break;
397 case PSBT_POS: {
398 // draw border
399 CPDF_Rect rcDraw = rectWnd;
400 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
401 ArgbEncode(nTransparancy, 100, 100, 100),
402 0.0f);
403
404 // draw inner border
405 rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f);
406 CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
407 ArgbEncode(nTransparancy, 255, 255, 255),
408 1.0f);
409
410 if (IsEnabled()) {
411 // draw shadow effect
412
413 CPDF_Point ptTop = CPDF_Point(rectWnd.left, rectWnd.top - 1.0f);
414 CPDF_Point ptBottom =
415 CPDF_Point(rectWnd.left, rectWnd.bottom + 1.0f);
416
417 ptTop.x += 1.5f;
418 ptBottom.x += 1.5f;
419
420 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
421 ArgbEncode(nTransparancy, 210, 210, 210),
422 1.0f);
423
424 ptTop.x += 1.0f;
425 ptBottom.x += 1.0f;
426
427 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
428 ArgbEncode(nTransparancy, 220, 220, 220),
429 1.0f);
430
431 ptTop.x += 1.0f;
432 ptBottom.x += 1.0f;
433
434 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
435 ArgbEncode(nTransparancy, 240, 240, 240),
436 1.0f);
437
438 ptTop.x += 1.0f;
439 ptBottom.x += 1.0f;
440
441 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
442 ArgbEncode(nTransparancy, 240, 240, 240),
443 1.0f);
444
445 ptTop.x += 1.0f;
446 ptBottom.x += 1.0f;
447
448 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
449 ArgbEncode(nTransparancy, 210, 210, 210),
450 1.0f);
451
452 ptTop.x += 1.0f;
453 ptBottom.x += 1.0f;
454
455 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
456 ArgbEncode(nTransparancy, 180, 180, 180),
457 1.0f);
458
459 ptTop.x += 1.0f;
460 ptBottom.x += 1.0f;
461
462 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
463 ArgbEncode(nTransparancy, 150, 150, 150),
464 1.0f);
465
466 ptTop.x += 1.0f;
467 ptBottom.x += 1.0f;
468
469 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
470 ArgbEncode(nTransparancy, 150, 150, 150),
471 1.0f);
472
473 ptTop.x += 1.0f;
474 ptBottom.x += 1.0f;
475
476 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
477 ArgbEncode(nTransparancy, 180, 180, 180),
478 1.0f);
479
480 ptTop.x += 1.0f;
481 ptBottom.x += 1.0f;
482
483 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
484 ArgbEncode(nTransparancy, 210, 210, 210),
485 1.0f);
486 } else {
487 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
488 ArgbEncode(255, 255, 255, 255));
489 }
490
491 // draw friction
492
493 if (rectWnd.Height() > 8.0f) {
494 FX_COLORREF crStroke = ArgbEncode(nTransparancy, 120, 120, 120);
495 if (!IsEnabled())
496 crStroke = CPWL_Utils::PWLColorToFXColor(
497 PWL_DEFAULT_HEAVYGRAYCOLOR, 255);
498
499 FX_FLOAT nFrictionWidth = 5.0f;
500 FX_FLOAT nFrictionHeight = 5.5f;
501
502 CPDF_Point ptLeft =
503 CPDF_Point(ptCenter.x - nFrictionWidth / 2.0f,
504 ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
505 CPDF_Point ptRight =
506 CPDF_Point(ptCenter.x + nFrictionWidth / 2.0f,
507 ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
508
509 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
510 crStroke, 1.0f);
511
512 ptLeft.y += 2.0f;
513 ptRight.y += 2.0f;
514
515 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
516 crStroke, 1.0f);
517
518 ptLeft.y += 2.0f;
519 ptRight.y += 2.0f;
520
521 CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
522 crStroke, 1.0f);
523 }
524 } break;
525 default:
526 break;
527 }
528 break;
529 default:
530 break;
531 }
532 }
533
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)534 FX_BOOL CPWL_SBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
535 CPWL_Wnd::OnLButtonDown(point, nFlag);
536
537 if (CPWL_Wnd* pParent = GetParentWindow())
538 pParent->OnNotify(this, PNM_LBUTTONDOWN, 0, (intptr_t)&point);
539
540 m_bMouseDown = TRUE;
541 SetCapture();
542
543 return TRUE;
544 }
545
OnLButtonUp(const CPDF_Point & point,FX_DWORD nFlag)546 FX_BOOL CPWL_SBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
547 CPWL_Wnd::OnLButtonUp(point, nFlag);
548
549 if (CPWL_Wnd* pParent = GetParentWindow())
550 pParent->OnNotify(this, PNM_LBUTTONUP, 0, (intptr_t)&point);
551
552 m_bMouseDown = FALSE;
553 ReleaseCapture();
554
555 return TRUE;
556 }
557
OnMouseMove(const CPDF_Point & point,FX_DWORD nFlag)558 FX_BOOL CPWL_SBButton::OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) {
559 CPWL_Wnd::OnMouseMove(point, nFlag);
560
561 if (CPWL_Wnd* pParent = GetParentWindow()) {
562 pParent->OnNotify(this, PNM_MOUSEMOVE, 0, (intptr_t)&point);
563 }
564
565 return TRUE;
566 }
567
CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType)568 CPWL_ScrollBar::CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType)
569 : m_sbType(sbType),
570 m_pMinButton(NULL),
571 m_pMaxButton(NULL),
572 m_pPosButton(NULL),
573 m_bMouseDown(FALSE),
574 m_bMinOrMax(FALSE),
575 m_bNotifyForever(TRUE) {}
576
~CPWL_ScrollBar()577 CPWL_ScrollBar::~CPWL_ScrollBar() {}
578
GetClassName() const579 CFX_ByteString CPWL_ScrollBar::GetClassName() const {
580 return "CPWL_ScrollBar";
581 }
582
OnCreate(PWL_CREATEPARAM & cp)583 void CPWL_ScrollBar::OnCreate(PWL_CREATEPARAM& cp) {
584 cp.eCursorType = FXCT_ARROW;
585 }
586
RePosChildWnd()587 void CPWL_ScrollBar::RePosChildWnd() {
588 CPDF_Rect rcClient = GetClientRect();
589 CPDF_Rect rcMinButton, rcMaxButton;
590 FX_FLOAT fBWidth = 0;
591
592 switch (m_sbType) {
593 case SBT_HSCROLL:
594 if (rcClient.right - rcClient.left >
595 PWL_SCROLLBAR_BUTTON_WIDTH * 2 + PWL_SCROLLBAR_POSBUTTON_MINWIDTH +
596 2) {
597 rcMinButton =
598 CPDF_Rect(rcClient.left, rcClient.bottom,
599 rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH, rcClient.top);
600 rcMaxButton = CPDF_Rect(rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
601 rcClient.bottom, rcClient.right, rcClient.top);
602 } else {
603 fBWidth = (rcClient.right - rcClient.left -
604 PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) /
605 2;
606
607 if (fBWidth > 0) {
608 rcMinButton = CPDF_Rect(rcClient.left, rcClient.bottom,
609 rcClient.left + fBWidth, rcClient.top);
610 rcMaxButton = CPDF_Rect(rcClient.right - fBWidth, rcClient.bottom,
611 rcClient.right, rcClient.top);
612 } else {
613 SetVisible(FALSE);
614 }
615 }
616 break;
617 case SBT_VSCROLL:
618 if (IsFloatBigger(rcClient.top - rcClient.bottom,
619 PWL_SCROLLBAR_BUTTON_WIDTH * 2 +
620 PWL_SCROLLBAR_POSBUTTON_MINWIDTH + 2)) {
621 rcMinButton =
622 CPDF_Rect(rcClient.left, rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH,
623 rcClient.right, rcClient.top);
624 rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom, rcClient.right,
625 rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH);
626 } else {
627 fBWidth = (rcClient.top - rcClient.bottom -
628 PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) /
629 2;
630
631 if (IsFloatBigger(fBWidth, 0)) {
632 rcMinButton = CPDF_Rect(rcClient.left, rcClient.top - fBWidth,
633 rcClient.right, rcClient.top);
634 rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom,
635 rcClient.right, rcClient.bottom + fBWidth);
636 } else {
637 SetVisible(FALSE);
638 }
639 }
640 break;
641 }
642
643 if (m_pMinButton)
644 m_pMinButton->Move(rcMinButton, TRUE, FALSE);
645 if (m_pMaxButton)
646 m_pMaxButton->Move(rcMaxButton, TRUE, FALSE);
647 MovePosButton(FALSE);
648 }
649
GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)650 void CPWL_ScrollBar::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
651 CPDF_Rect rectWnd = GetWindowRect();
652
653 if (IsVisible() && !rectWnd.IsEmpty()) {
654 CFX_ByteTextBuf sButton;
655
656 sButton << "q\n";
657 sButton << "0 w\n"
658 << CPWL_Utils::GetColorAppStream(GetBackgroundColor(), TRUE);
659 sButton << rectWnd.left << " " << rectWnd.bottom << " "
660 << rectWnd.right - rectWnd.left << " "
661 << rectWnd.top - rectWnd.bottom << " re b Q\n";
662
663 sAppStream << sButton;
664 }
665 }
666
DrawThisAppearance(CFX_RenderDevice * pDevice,CFX_Matrix * pUser2Device)667 void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice,
668 CFX_Matrix* pUser2Device) {
669 CPDF_Rect rectWnd = GetWindowRect();
670
671 if (IsVisible() && !rectWnd.IsEmpty()) {
672 CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rectWnd,
673 GetBackgroundColor(), GetTransparency());
674
675 CPWL_Utils::DrawStrokeLine(
676 pDevice, pUser2Device,
677 CPDF_Point(rectWnd.left + 2.0f, rectWnd.top - 2.0f),
678 CPDF_Point(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f),
679 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
680
681 CPWL_Utils::DrawStrokeLine(
682 pDevice, pUser2Device,
683 CPDF_Point(rectWnd.right - 2.0f, rectWnd.top - 2.0f),
684 CPDF_Point(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f),
685 ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
686 }
687 }
688
OnLButtonDown(const CPDF_Point & point,FX_DWORD nFlag)689 FX_BOOL CPWL_ScrollBar::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
690 CPWL_Wnd::OnLButtonDown(point, nFlag);
691
692 if (HasFlag(PWS_AUTOTRANSPARENT)) {
693 if (GetTransparency() != 255) {
694 SetTransparency(255);
695 InvalidateRect();
696 }
697 }
698
699 CPDF_Rect rcMinArea, rcMaxArea;
700
701 if (m_pPosButton && m_pPosButton->IsVisible()) {
702 CPDF_Rect rcClient = GetClientRect();
703 CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect();
704
705 switch (m_sbType) {
706 case SBT_HSCROLL:
707 rcMinArea = CPDF_Rect(rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH,
708 rcClient.bottom, rcPosButton.left, rcClient.top);
709 rcMaxArea = CPDF_Rect(rcPosButton.right, rcClient.bottom,
710 rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
711 rcClient.top);
712
713 break;
714 case SBT_VSCROLL:
715 rcMinArea = CPDF_Rect(rcClient.left, rcPosButton.top, rcClient.right,
716 rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH);
717 rcMaxArea = CPDF_Rect(rcClient.left,
718 rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH,
719 rcClient.right, rcPosButton.bottom);
720 break;
721 }
722
723 rcMinArea.Normalize();
724 rcMaxArea.Normalize();
725
726 if (rcMinArea.Contains(point.x, point.y)) {
727 m_sData.SubBig();
728 MovePosButton(TRUE);
729 NotifyScrollWindow();
730 }
731
732 if (rcMaxArea.Contains(point.x, point.y)) {
733 m_sData.AddBig();
734 MovePosButton(TRUE);
735 NotifyScrollWindow();
736 }
737 }
738
739 return TRUE;
740 }
741
OnLButtonUp(const CPDF_Point & point,FX_DWORD nFlag)742 FX_BOOL CPWL_ScrollBar::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
743 CPWL_Wnd::OnLButtonUp(point, nFlag);
744
745 if (HasFlag(PWS_AUTOTRANSPARENT)) {
746 if (GetTransparency() != PWL_SCROLLBAR_TRANSPARANCY) {
747 SetTransparency(PWL_SCROLLBAR_TRANSPARANCY);
748 InvalidateRect();
749 }
750 }
751
752 EndTimer();
753 m_bMouseDown = FALSE;
754
755 return TRUE;
756 }
757
OnNotify(CPWL_Wnd * pWnd,FX_DWORD msg,intptr_t wParam,intptr_t lParam)758 void CPWL_ScrollBar::OnNotify(CPWL_Wnd* pWnd,
759 FX_DWORD msg,
760 intptr_t wParam,
761 intptr_t lParam) {
762 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);
763
764 switch (msg) {
765 case PNM_LBUTTONDOWN:
766 if (pWnd == m_pMinButton) {
767 OnMinButtonLBDown(*(CPDF_Point*)lParam);
768 }
769
770 if (pWnd == m_pMaxButton) {
771 OnMaxButtonLBDown(*(CPDF_Point*)lParam);
772 }
773
774 if (pWnd == m_pPosButton) {
775 OnPosButtonLBDown(*(CPDF_Point*)lParam);
776 }
777 break;
778 case PNM_LBUTTONUP:
779 if (pWnd == m_pMinButton) {
780 OnMinButtonLBUp(*(CPDF_Point*)lParam);
781 }
782
783 if (pWnd == m_pMaxButton) {
784 OnMaxButtonLBUp(*(CPDF_Point*)lParam);
785 }
786
787 if (pWnd == m_pPosButton) {
788 OnPosButtonLBUp(*(CPDF_Point*)lParam);
789 }
790 break;
791 case PNM_MOUSEMOVE:
792 if (pWnd == m_pMinButton) {
793 OnMinButtonMouseMove(*(CPDF_Point*)lParam);
794 }
795
796 if (pWnd == m_pMaxButton) {
797 OnMaxButtonMouseMove(*(CPDF_Point*)lParam);
798 }
799
800 if (pWnd == m_pPosButton) {
801 OnPosButtonMouseMove(*(CPDF_Point*)lParam);
802 }
803 break;
804 case PNM_SETSCROLLINFO: {
805 if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
806 if (FXSYS_memcmp(&m_OriginInfo, pInfo, sizeof(PWL_SCROLL_INFO)) != 0) {
807 m_OriginInfo = *pInfo;
808 FX_FLOAT fMax =
809 pInfo->fContentMax - pInfo->fContentMin - pInfo->fPlateWidth;
810 fMax = fMax > 0.0f ? fMax : 0.0f;
811 SetScrollRange(0, fMax, pInfo->fPlateWidth);
812 SetScrollStep(pInfo->fBigStep, pInfo->fSmallStep);
813 }
814 }
815 } break;
816 case PNM_SETSCROLLPOS: {
817 FX_FLOAT fPos = *(FX_FLOAT*)lParam;
818 switch (m_sbType) {
819 case SBT_HSCROLL:
820 fPos = fPos - m_OriginInfo.fContentMin;
821 break;
822 case SBT_VSCROLL:
823 fPos = m_OriginInfo.fContentMax - fPos;
824 break;
825 }
826 SetScrollPos(fPos);
827 } break;
828 }
829 }
830
CreateButtons(const PWL_CREATEPARAM & cp)831 void CPWL_ScrollBar::CreateButtons(const PWL_CREATEPARAM& cp) {
832 PWL_CREATEPARAM scp = cp;
833 scp.pParentWnd = this;
834 scp.dwBorderWidth = 2;
835 scp.nBorderStyle = PBS_BEVELED;
836
837 scp.dwFlags =
838 PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PWS_NOREFRESHCLIP;
839
840 if (!m_pMinButton) {
841 m_pMinButton = new CPWL_SBButton(m_sbType, PSBT_MIN);
842 m_pMinButton->Create(scp);
843 }
844
845 if (!m_pMaxButton) {
846 m_pMaxButton = new CPWL_SBButton(m_sbType, PSBT_MAX);
847 m_pMaxButton->Create(scp);
848 }
849
850 if (!m_pPosButton) {
851 m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS);
852 m_pPosButton->SetVisible(FALSE);
853 m_pPosButton->Create(scp);
854 }
855 }
856
GetScrollBarWidth() const857 FX_FLOAT CPWL_ScrollBar::GetScrollBarWidth() const {
858 if (!IsVisible())
859 return 0;
860
861 return PWL_SCROLLBAR_WIDTH;
862 }
863
SetScrollRange(FX_FLOAT fMin,FX_FLOAT fMax,FX_FLOAT fClientWidth)864 void CPWL_ScrollBar::SetScrollRange(FX_FLOAT fMin,
865 FX_FLOAT fMax,
866 FX_FLOAT fClientWidth) {
867 if (m_pPosButton) {
868 m_sData.SetScrollRange(fMin, fMax);
869 m_sData.SetClientWidth(fClientWidth);
870
871 if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
872 m_pPosButton->SetVisible(FALSE);
873 } else {
874 m_pPosButton->SetVisible(TRUE);
875 MovePosButton(TRUE);
876 }
877 }
878 }
879
SetScrollPos(FX_FLOAT fPos)880 void CPWL_ScrollBar::SetScrollPos(FX_FLOAT fPos) {
881 FX_FLOAT fOldPos = m_sData.fScrollPos;
882
883 m_sData.SetPos(fPos);
884
885 if (!IsFloatEqual(m_sData.fScrollPos, fOldPos))
886 MovePosButton(TRUE);
887 }
888
SetScrollStep(FX_FLOAT fBigStep,FX_FLOAT fSmallStep)889 void CPWL_ScrollBar::SetScrollStep(FX_FLOAT fBigStep, FX_FLOAT fSmallStep) {
890 m_sData.SetBigStep(fBigStep);
891 m_sData.SetSmallStep(fSmallStep);
892 }
893
MovePosButton(FX_BOOL bRefresh)894 void CPWL_ScrollBar::MovePosButton(FX_BOOL bRefresh) {
895 ASSERT(m_pMinButton);
896 ASSERT(m_pMaxButton);
897
898 if (m_pPosButton->IsVisible()) {
899 CPDF_Rect rcClient;
900 CPDF_Rect rcPosArea, rcPosButton;
901
902 rcClient = GetClientRect();
903 rcPosArea = GetScrollArea();
904
905 FX_FLOAT fLeft, fRight, fTop, fBottom;
906
907 switch (m_sbType) {
908 case SBT_HSCROLL:
909 fLeft = TrueToFace(m_sData.fScrollPos);
910 fRight = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
911
912 if (fRight - fLeft < PWL_SCROLLBAR_POSBUTTON_MINWIDTH)
913 fRight = fLeft + PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
914
915 if (fRight > rcPosArea.right) {
916 fRight = rcPosArea.right;
917 fLeft = fRight - PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
918 }
919
920 rcPosButton = CPDF_Rect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top);
921
922 break;
923 case SBT_VSCROLL:
924 fBottom = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
925 fTop = TrueToFace(m_sData.fScrollPos);
926
927 if (IsFloatSmaller(fTop - fBottom, PWL_SCROLLBAR_POSBUTTON_MINWIDTH))
928 fBottom = fTop - PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
929
930 if (IsFloatSmaller(fBottom, rcPosArea.bottom)) {
931 fBottom = rcPosArea.bottom;
932 fTop = fBottom + PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
933 }
934
935 rcPosButton = CPDF_Rect(rcPosArea.left, fBottom, rcPosArea.right, fTop);
936
937 break;
938 }
939
940 m_pPosButton->Move(rcPosButton, TRUE, bRefresh);
941 }
942 }
943
OnMinButtonLBDown(const CPDF_Point & point)944 void CPWL_ScrollBar::OnMinButtonLBDown(const CPDF_Point& point) {
945 m_sData.SubSmall();
946 MovePosButton(TRUE);
947 NotifyScrollWindow();
948
949 m_bMinOrMax = TRUE;
950
951 EndTimer();
952 BeginTimer(100);
953 }
954
OnMinButtonLBUp(const CPDF_Point & point)955 void CPWL_ScrollBar::OnMinButtonLBUp(const CPDF_Point& point) {}
956
OnMinButtonMouseMove(const CPDF_Point & point)957 void CPWL_ScrollBar::OnMinButtonMouseMove(const CPDF_Point& point) {}
958
OnMaxButtonLBDown(const CPDF_Point & point)959 void CPWL_ScrollBar::OnMaxButtonLBDown(const CPDF_Point& point) {
960 m_sData.AddSmall();
961 MovePosButton(TRUE);
962 NotifyScrollWindow();
963
964 m_bMinOrMax = FALSE;
965
966 EndTimer();
967 BeginTimer(100);
968 }
969
OnMaxButtonLBUp(const CPDF_Point & point)970 void CPWL_ScrollBar::OnMaxButtonLBUp(const CPDF_Point& point) {}
971
OnMaxButtonMouseMove(const CPDF_Point & point)972 void CPWL_ScrollBar::OnMaxButtonMouseMove(const CPDF_Point& point) {}
973
OnPosButtonLBDown(const CPDF_Point & point)974 void CPWL_ScrollBar::OnPosButtonLBDown(const CPDF_Point& point) {
975 m_bMouseDown = TRUE;
976
977 if (m_pPosButton) {
978 CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect();
979
980 switch (m_sbType) {
981 case SBT_HSCROLL:
982 m_nOldPos = point.x;
983 m_fOldPosButton = rcPosButton.left;
984 break;
985 case SBT_VSCROLL:
986 m_nOldPos = point.y;
987 m_fOldPosButton = rcPosButton.top;
988 break;
989 }
990 }
991 }
992
OnPosButtonLBUp(const CPDF_Point & point)993 void CPWL_ScrollBar::OnPosButtonLBUp(const CPDF_Point& point) {
994 if (m_bMouseDown) {
995 if (!m_bNotifyForever)
996 NotifyScrollWindow();
997 }
998 m_bMouseDown = FALSE;
999 }
1000
OnPosButtonMouseMove(const CPDF_Point & point)1001 void CPWL_ScrollBar::OnPosButtonMouseMove(const CPDF_Point& point) {
1002 FX_FLOAT fOldScrollPos = m_sData.fScrollPos;
1003
1004 FX_FLOAT fNewPos = 0;
1005
1006 switch (m_sbType) {
1007 case SBT_HSCROLL:
1008 if (FXSYS_fabs(point.x - m_nOldPos) < 1)
1009 return;
1010 fNewPos = FaceToTrue(m_fOldPosButton + point.x - m_nOldPos);
1011 break;
1012 case SBT_VSCROLL:
1013 if (FXSYS_fabs(point.y - m_nOldPos) < 1)
1014 return;
1015 fNewPos = FaceToTrue(m_fOldPosButton + point.y - m_nOldPos);
1016 break;
1017 }
1018
1019 if (m_bMouseDown) {
1020 switch (m_sbType) {
1021 case SBT_HSCROLL:
1022
1023 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
1024 fNewPos = m_sData.ScrollRange.fMin;
1025 }
1026
1027 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
1028 fNewPos = m_sData.ScrollRange.fMax;
1029 }
1030
1031 m_sData.SetPos(fNewPos);
1032
1033 break;
1034 case SBT_VSCROLL:
1035
1036 if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
1037 fNewPos = m_sData.ScrollRange.fMin;
1038 }
1039
1040 if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
1041 fNewPos = m_sData.ScrollRange.fMax;
1042 }
1043
1044 m_sData.SetPos(fNewPos);
1045
1046 break;
1047 }
1048
1049 if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) {
1050 MovePosButton(TRUE);
1051
1052 if (m_bNotifyForever)
1053 NotifyScrollWindow();
1054 }
1055 }
1056 }
1057
NotifyScrollWindow()1058 void CPWL_ScrollBar::NotifyScrollWindow() {
1059 if (CPWL_Wnd* pParent = GetParentWindow()) {
1060 FX_FLOAT fPos;
1061 switch (m_sbType) {
1062 case SBT_HSCROLL:
1063 fPos = m_OriginInfo.fContentMin + m_sData.fScrollPos;
1064 break;
1065 case SBT_VSCROLL:
1066 fPos = m_OriginInfo.fContentMax - m_sData.fScrollPos;
1067 break;
1068 }
1069 pParent->OnNotify(this, PNM_SCROLLWINDOW, (intptr_t)m_sbType,
1070 (intptr_t)&fPos);
1071 }
1072 }
1073
GetScrollArea() const1074 CPDF_Rect CPWL_ScrollBar::GetScrollArea() const {
1075 CPDF_Rect rcClient = GetClientRect();
1076 CPDF_Rect rcArea;
1077
1078 if (!m_pMinButton || !m_pMaxButton)
1079 return rcClient;
1080
1081 CPDF_Rect rcMin = m_pMinButton->GetWindowRect();
1082 CPDF_Rect rcMax = m_pMaxButton->GetWindowRect();
1083
1084 FX_FLOAT fMinWidth = rcMin.right - rcMin.left;
1085 FX_FLOAT fMinHeight = rcMin.top - rcMin.bottom;
1086 FX_FLOAT fMaxWidth = rcMax.right - rcMax.left;
1087 FX_FLOAT fMaxHeight = rcMax.top - rcMax.bottom;
1088
1089 switch (m_sbType) {
1090 case SBT_HSCROLL:
1091 if (rcClient.right - rcClient.left > fMinWidth + fMaxWidth + 2) {
1092 rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom,
1093 rcClient.right - fMaxWidth - 1, rcClient.top);
1094 } else {
1095 rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom,
1096 rcClient.left + fMinWidth + 1, rcClient.top);
1097 }
1098 break;
1099 case SBT_VSCROLL:
1100 if (rcClient.top - rcClient.bottom > fMinHeight + fMaxHeight + 2) {
1101 rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1,
1102 rcClient.right, rcClient.top - fMaxHeight - 1);
1103 } else {
1104 rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1,
1105 rcClient.right, rcClient.bottom + fMinHeight + 1);
1106 }
1107 break;
1108 }
1109
1110 rcArea.Normalize();
1111
1112 return rcArea;
1113 }
1114
TrueToFace(FX_FLOAT fTrue)1115 FX_FLOAT CPWL_ScrollBar::TrueToFace(FX_FLOAT fTrue) {
1116 CPDF_Rect rcPosArea;
1117 rcPosArea = GetScrollArea();
1118
1119 FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
1120 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;
1121
1122 FX_FLOAT fFace = 0;
1123
1124 switch (m_sbType) {
1125 case SBT_HSCROLL:
1126 fFace = rcPosArea.left +
1127 fTrue * (rcPosArea.right - rcPosArea.left) / fFactWidth;
1128 break;
1129 case SBT_VSCROLL:
1130 fFace = rcPosArea.top -
1131 fTrue * (rcPosArea.top - rcPosArea.bottom) / fFactWidth;
1132 break;
1133 }
1134
1135 return fFace;
1136 }
1137
FaceToTrue(FX_FLOAT fFace)1138 FX_FLOAT CPWL_ScrollBar::FaceToTrue(FX_FLOAT fFace) {
1139 CPDF_Rect rcPosArea;
1140 rcPosArea = GetScrollArea();
1141
1142 FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
1143 fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;
1144
1145 FX_FLOAT fTrue = 0;
1146
1147 switch (m_sbType) {
1148 case SBT_HSCROLL:
1149 fTrue = (fFace - rcPosArea.left) * fFactWidth /
1150 (rcPosArea.right - rcPosArea.left);
1151 break;
1152 case SBT_VSCROLL:
1153 fTrue = (rcPosArea.top - fFace) * fFactWidth /
1154 (rcPosArea.top - rcPosArea.bottom);
1155 break;
1156 }
1157
1158 return fTrue;
1159 }
1160
CreateChildWnd(const PWL_CREATEPARAM & cp)1161 void CPWL_ScrollBar::CreateChildWnd(const PWL_CREATEPARAM& cp) {
1162 CreateButtons(cp);
1163 }
1164
TimerProc()1165 void CPWL_ScrollBar::TimerProc() {
1166 PWL_SCROLL_PRIVATEDATA sTemp = m_sData;
1167
1168 if (m_bMinOrMax)
1169 m_sData.SubSmall();
1170 else
1171 m_sData.AddSmall();
1172
1173 if (FXSYS_memcmp(&m_sData, &sTemp, sizeof(PWL_SCROLL_PRIVATEDATA)) != 0) {
1174 MovePosButton(TRUE);
1175 NotifyScrollWindow();
1176 }
1177 }
1178