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
20PWL_FLOATRANGE::PWL_FLOATRANGE()
21{
22	Default();
23}
24
25PWL_FLOATRANGE::PWL_FLOATRANGE(FX_FLOAT min,FX_FLOAT max)
26{
27	Set(min,max);
28}
29
30void PWL_FLOATRANGE::Default()
31{
32	fMin = 0;
33	fMax = 0;
34}
35
36void 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
50FX_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
56FX_FLOAT PWL_FLOATRANGE::GetWidth() const
57{
58	return fMax - fMin;
59}
60
61/* ------------------------------- PWL_SCROLL_PRIVATEDATA ------------------------------- */
62
63PWL_SCROLL_PRIVATEDATA::PWL_SCROLL_PRIVATEDATA()
64{
65	Default();
66}
67
68void PWL_SCROLL_PRIVATEDATA::Default()
69{
70	ScrollRange.Default();
71	fScrollPos = ScrollRange.fMin;
72	fClientWidth = 0;
73	fBigStep = 10;
74	fSmallStep = 1;
75}
76
77void 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
87void PWL_SCROLL_PRIVATEDATA::SetClientWidth(FX_FLOAT width)
88{
89	fClientWidth = width;
90}
91
92void PWL_SCROLL_PRIVATEDATA::SetSmallStep(FX_FLOAT step)
93{
94	fSmallStep = step;
95}
96
97void PWL_SCROLL_PRIVATEDATA::SetBigStep(FX_FLOAT step)
98{
99	fBigStep = step;
100}
101
102FX_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
112void PWL_SCROLL_PRIVATEDATA::AddSmall()
113{
114	if (!SetPos(fScrollPos + fSmallStep))
115		SetPos(ScrollRange.fMax);
116}
117
118void PWL_SCROLL_PRIVATEDATA::SubSmall()
119{
120	if (!SetPos(fScrollPos - fSmallStep))
121		SetPos(ScrollRange.fMin);
122}
123
124void PWL_SCROLL_PRIVATEDATA::AddBig()
125{
126	if (!SetPos(fScrollPos + fBigStep))
127		SetPos(ScrollRange.fMax);
128}
129
130void PWL_SCROLL_PRIVATEDATA::SubBig()
131{
132	if (!SetPos(fScrollPos - fBigStep))
133		SetPos(ScrollRange.fMin);
134}
135
136/* ------------------------------- CPWL_SBButton ------------------------------- */
137
138CPWL_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
146CPWL_SBButton::~CPWL_SBButton()
147{
148
149}
150
151CFX_ByteString CPWL_SBButton::GetClassName() const
152{
153	return "CPWL_SBButton";
154}
155
156void CPWL_SBButton::OnCreate(PWL_CREATEPARAM & cp)
157{
158	cp.eCursorType = FXCT_ARROW;
159}
160
161void 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
276void 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	FX_INT32 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
568FX_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,(FX_INTPTR)&point);
574
575	m_bMouseDown = TRUE;
576	SetCapture();
577
578	return TRUE;
579}
580
581FX_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,(FX_INTPTR)&point);
587
588	m_bMouseDown = FALSE;
589	ReleaseCapture();
590
591	return TRUE;
592}
593
594FX_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,(FX_INTPTR)&point);
601
602		/*
603		if (m_bMouseDown && (m_eSBButtonType == PSBT_MIN || m_eSBButtonType == PSBT_MAX))
604		{
605			if (!pParent->OnNotify(this,PNM_LBUTTONDOWN,nFlags,(FX_INTPTR)&point))
606				return FALSE;
607		}
608		*/
609	}
610
611	return TRUE;
612}
613
614/* ------------------------------- CPWL_ScrollBar ---------------------------------- */
615
616CPWL_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
627CPWL_ScrollBar::~CPWL_ScrollBar()
628{
629}
630
631CFX_ByteString CPWL_ScrollBar::GetClassName() const
632{
633	return "CPWL_ScrollBar";
634}
635
636void CPWL_ScrollBar::OnCreate(PWL_CREATEPARAM & cp)
637{
638	cp.eCursorType = FXCT_ARROW;
639}
640
641void 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
728void 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
745void 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
764FX_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
824FX_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
843void CPWL_ScrollBar::OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam, FX_INTPTR 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
930void 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
959FX_FLOAT CPWL_ScrollBar::GetScrollBarWidth() const
960{
961	if (!IsVisible()) return 0;
962
963	return PWL_SCROLLBAR_WIDTH;
964}
965
966void 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
985void 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
995void CPWL_ScrollBar::SetScrollStep(FX_FLOAT fBigStep,FX_FLOAT fSmallStep)
996{
997	m_sData.SetBigStep(fBigStep);
998	m_sData.SetSmallStep(fSmallStep);
999}
1000
1001void 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
1067void 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
1079void CPWL_ScrollBar::OnMinButtonLBUp(const CPDF_Point & point)
1080{
1081}
1082
1083void CPWL_ScrollBar::OnMinButtonMouseMove(const CPDF_Point & point)
1084{
1085}
1086
1087void 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
1099void CPWL_ScrollBar::OnMaxButtonLBUp(const CPDF_Point & point)
1100{
1101}
1102
1103void CPWL_ScrollBar::OnMaxButtonMouseMove(const CPDF_Point & point)
1104{
1105}
1106
1107void 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
1129void 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
1139void 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
1203void 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,(FX_INTPTR)m_sbType,(FX_INTPTR)&fPos);
1218	}
1219}
1220
1221CPDF_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
1269FX_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
1292FX_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
1315void CPWL_ScrollBar::CreateChildWnd(const PWL_CREATEPARAM & cp)
1316{
1317	CreateButtons(cp);
1318}
1319
1320void 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/*
1335void CPWL_ScrollBar::OnSetFocus()
1336{
1337	if (GetTransparency() != 255)
1338	{
1339		SetTransparency(255);
1340		InvalidateRect();
1341	}
1342}
1343
1344void CPWL_ScrollBar::OnKillFocus()
1345{
1346	if (GetTransparency() != PWL_SCROLLBAR_TRANSPARANCY)
1347	{
1348		SetTransparency(PWL_SCROLLBAR_TRANSPARANCY);
1349		InvalidateRect();
1350	}
1351}
1352*/
1353
1354