Home | History | Annotate | Download | only in pdfwindow
      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 	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 
    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,(FX_INTPTR)&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,(FX_INTPTR)&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,(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 
    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, 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 
    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,(FX_INTPTR)m_sbType,(FX_INTPTR)&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 
   1354