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