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