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