00001 // $Id: scroller.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // 00099 // This defines the CScroller class, which implement RISCOS-style 00100 // proportional scroll bars under Windows. 00101 // 00102 00103 00104 #include "camtypes.h" 00105 00106 //#include "ccmaths.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "camdoc.h" 00108 //#include "ops.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 //#include "scrcamvw.h" 00110 #include "scroller.h" 00111 //#include "scrlbutn.h" 00112 //#include "scrlthmb.h" 00113 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 #include "csrstack.h" 00115 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 #include "camdoc.h" 00117 #include "camframe.h" 00118 #include "vstate.h" 00119 #include "product.h" 00120 00121 //#include <limits.h> 00122 #if 0 00123 #ifdef _DEBUG 00124 #undef THIS_FILE 00125 static char BASED_CODE THIS_FILE[] = __FILE__; 00126 #endif 00127 #endif 00128 00129 DECLARE_SOURCE("$Revision: 1282 $"); 00130 00131 #define new CAM_DEBUG_NEW 00132 00134 // CScrollerCorner window - fills in between a horizontal and vertical scroll 00135 // bar. 00136 00137 BEGIN_EVENT_TABLE(CScrollerCorner, wxWindow) 00138 EVT_PAINT(CScrollerCorner::OnPaint) 00139 EVT_LEFT_DOWN(CScrollerCorner::OnLButtonDown) 00140 END_EVENT_TABLE() 00141 00142 00143 /********************************************************************************************* 00144 > CScrollerCorner::CScrollerCorner() 00145 00146 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00147 Created: 7th Sept 1993 00148 Purpose: Constructs a scroller object. 00149 Scope: Protected 00150 00151 **********************************************************************************************/ 00152 00153 CScrollerCorner::CScrollerCorner() 00154 { 00155 //SizeBitmap.LoadOEMBitmap(OBM_SIZE); 00156 } 00157 00158 00159 00160 /********************************************************************************************* 00161 > virtual BOOL CScrollerCorner::Create(LPCTSTR, LPCTSTR, DWORD style, const RECT& rect, 00162 CWnd* parent, UINT32 id) 00163 00164 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00165 Created: ages ago 00166 Inputs: Two dummy long pointers to constant TCHARs, the window-instance flags, a 00167 rectangle describing the position of the "corner", a pointer to the parent 00168 window, the numeric child window identifier, a pointer to a creation context. 00169 Outputs: - 00170 Returns: TRUE if the window is successfully created. 00171 Purpose: Creates (attaches) the Windows interface element which corresponds to the 00172 C++ CScrollerCorner object. The CScrollerCorner's background brush is 00173 set to the one used to colour scroll bars. 00174 Errors: - 00175 Scope: Public 00176 SeeAlso: CCamView::OnCreate() 00177 00178 **********************************************************************************************/ 00179 00180 BOOL CScrollerCorner::Create(LPCTSTR, LPCTSTR, DWORD style, const wxRect& rect, 00181 wxWindow* pParent, UINT32 id) 00182 { 00183 return wxWindow::Create( pParent, id, rect.GetTopLeft(), rect.GetSize(), style ); 00184 /* 00185 return CWnd::Create(AfxRegisterWndClass( 00186 CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, 00187 0, 00188 HBRUSH(COLOR_SCROLLBAR + 1), 00189 0), 00190 "", 00191 style | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 00192 rect, 00193 parent, 00194 id, 00195 ctxt); 00196 */ 00197 } 00198 00199 00200 00202 // CScrollerCorner message response functions. 00203 00204 /********************************************************************************************* 00205 > afx_msg void CScrollerCorner::OnPaint(wxPaintEvent& event) 00206 00207 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 00208 Created: 8/10/95 00209 Purpose: Paints the client area of the CScrollerCorner. 00210 Scope: Protected 00211 SeeAlso: CScrollerCorner::Create() 00212 00213 **********************************************************************************************/ 00214 00215 void CScrollerCorner::OnPaint(wxPaintEvent& event) 00216 { 00217 #ifdef GERRYXXX 00218 CPaintDC dc(this); 00219 00220 // Draw the resizing gadget. 00221 CPen nullpen(PS_NULL, 0, RGB(0, 0, 0)); 00222 CPen* oldpen = dc.SelectObject(&nullpen); 00223 dc.SetROP2(R2_COPYPEN); 00224 00225 // Create an appropriately coloured brush to fill the scroller's background. 00226 CBrush brush(::GetSysColor(COLOR_BTNFACE)); 00227 CBrush* oldbrush = dc.SelectObject(&brush); 00228 00229 // Draw the body of the scroller corner. 00230 CRect rClient; 00231 GetClientRect(&rClient); 00232 dc.Rectangle(&rClient); 00233 00234 // Draw the size gadget on top if not maximised. 00235 BOOL fIsMaxed; 00236 GetMainFrame()->MDIGetActive(&fIsMaxed); 00237 if (!fIsMaxed) 00238 { 00239 CDC scrDC; 00240 scrDC.CreateCompatibleDC(&dc); 00241 CBitmap* pOldSrcBitmap = (CBitmap*) scrDC.SelectObject(&SizeBitmap); 00242 dc.BitBlt(0, 0, rClient.Width(), rClient.Height(), &scrDC, 0, 0, SRCCOPY); 00243 scrDC.SelectObject(pOldSrcBitmap); 00244 } 00245 00246 // Deselect the drawing tools before destroying the DC. 00247 dc.SelectObject(oldbrush); 00248 dc.SelectObject(oldpen); 00249 #endif 00250 } 00251 00252 00253 00254 /********************************************************************************************* 00255 > afx_msg BOOL CScrollerCorner::OnSetCursor(CWnd* pWnd, UINT32 nHitTest, UINT32 nMessage) 00256 00257 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00258 Created: 14 Oct 93 00259 Inputs: "event" The standard SetCursor event, which contains all the info to handle 00260 the request 00261 Outputs: - 00262 Returns: TRUE, ie. the cursor has been set, and no further processing is necessary. 00263 FALSE if the cursor has not been set, e.g. this view is not active. 00264 Purpose: Fakes the sizing gadget for our custom scrollbars. 00265 Errors: - 00266 Scope: Protected 00267 SeeAlso: DocView::OnSetCursor 00268 00269 **********************************************************************************************/ 00270 00271 void CScrollerCorner::OnSetCursor( wxSetCursorEvent& event ) 00272 { 00273 #ifdef GERRYXXX 00274 // Child windows assume responsibility for setting their own cursor. 00275 if (pWnd != this) return FALSE; 00276 00277 BOOL fIsMaxed; 00278 GetMainFrame()->MDIGetActive(&fIsMaxed); 00279 Cursor* pc = /*fIsMaxed ?*/ Cursor::Arrow; /*: Cursor::SizeNWSE;*/ 00280 00281 pc->SetActive(); 00282 return TRUE; 00283 #endif 00284 } 00285 00286 00287 /********************************************************************************************* 00288 > afx_msg void CScrollerCorner::OnLButtonDown(wxMouseEvent &event) 00289 00290 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00291 Created: 5/10/95 00292 Purpose: Send a fake non-client msg to our parent to allow sizing via this window. 00293 **********************************************************************************************/ 00294 00295 void CScrollerCorner::OnLButtonDown(wxMouseEvent &event) 00296 { 00297 #ifdef GERRYXXX 00298 CWnd::OnLButtonDown(nFlags, pt); 00299 00300 CWnd* pParent = GetParent(); 00301 CRect rWin; 00302 pParent->GetWindowRect(&rWin); 00303 00304 // calc screen coords of bottom-right frame corner 00305 pt.x = rWin.Width() - 1; 00306 pt.y = rWin.Height() - 1; 00307 pParent->ClientToScreen(&pt); 00308 00309 pParent->SendMessage(WM_NCLBUTTONDOWN, WPARAM(HTSIZE), 00310 MAKELPARAM(WORD(pt.x), WORD(pt.y))); 00311 #endif 00312 } 00313 00314 00315 00317 // 00318 // 00319 // CWinScroller 00320 // 00321 // 00323 00324 INT32 CWinScroller::ScrollerSize = 0; // UIC 00325 00326 /********************************************************************************************* 00327 > CWinScroller::CWinScroller() 00328 00329 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00330 Created: 6/10/04 00331 Purpose: Default constructor for the CWinScroller class. 00332 Initialises various flags and variables with some reasonable- 00333 looking values. 00334 00335 **********************************************************************************************/ 00336 00337 CWinScroller::CWinScroller(BOOL IsHorizontal) 00338 { 00339 Horizontal = IsHorizontal; 00340 #ifdef GERRYXXX 00341 Enabled = TRUE; 00342 Proportional = TRUE; 00343 // Set some default values for the range etc. If we don't do that then 00344 // the scroll bars are invisible when first created! 00345 ThumbVal = MinVal = 0; 00346 Range = MaxVal = 100; 00347 LineSize = Delta = Granularity = 1; 00348 PageSize = 10; 00349 ScrollerSize = GetSystemMetrics(SM_CYHSCROLL); // UIC 00350 #endif 00351 } 00352 00353 00354 00355 /********************************************************************************************* 00356 > virtual CWinScroller::~CWinScroller() 00357 00358 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00359 Created: 6/10/04 00360 Purpose: Destroys a CWinScroller - deletes its child windows. 00361 00362 **********************************************************************************************/ 00363 00364 CWinScroller::~CWinScroller() 00365 { 00366 } 00367 00368 00369 00370 /********************************************************************************************* 00371 > BOOL CWinScroller::Create(wxWindow* pParent, UINT32 nID, const wxPoint& pos, const wxSize& size) 00372 00373 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00374 Created: 6/10/04 00375 Inputs: Same as CScrollBar::Create 00376 Returns: TRUE if the scroller is successfully created. 00377 Purpose: Calls CScrollBar::Create with appropriate horizontal or vertical style 00378 00379 **********************************************************************************************/ 00380 00381 BOOL CWinScroller::Create(wxWindow* pParent, UINT32 nID, const wxPoint& pos, const wxSize& size) 00382 { 00383 ENSURE(pParent != NULL, "CWinScroller objects must have a parent window!\n"); 00384 INT32 style = IsHorizontal() ? wxSB_HORIZONTAL : wxSB_VERTICAL; 00385 return wxScrollBar::Create(pParent, nID, pos, size, style); 00386 } 00387 00388 #ifdef GERRYXXX 00389 00390 /********************************************************************************************* 00391 > void CWinScroller::GetScrollPos(XLONG* pxl) const 00392 00393 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00394 Created: 6/10/04 00395 Outputs: Changes the passed XLONG to the current position of the scroller thumb. 00396 Purpose: Gets the thumb offset of the scroller. 00397 SeeAlso: CScroller::SetScrollPos() 00398 00399 **********************************************************************************************/ 00400 00401 void CWinScroller::GetScrollPos(XLONG* pxl) const 00402 { 00403 *pxl = ThumbVal; 00404 } 00405 00406 /********************************************************************************************* 00407 > void CWinScroller::SetProportional(BOOL bProp) 00408 00409 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00410 Created: 6/10/04 00411 Inputs: A boolean which if TRUE means that the scroller should become "proportional" 00412 SeeAlso: CScroller::SetProportional 00413 00414 **********************************************************************************************/ 00415 00416 void CWinScroller::SetProportional(BOOL bProp) 00417 { 00418 Proportional = bProp; 00419 } 00420 00421 /********************************************************************************************* 00422 > void CWinScroller::MoveThumb(BOOL redraw) 00423 00424 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00425 Created: 6/10/04 00426 Inputs: A boolean which if TRUE means that CCamView is told to redraw its client 00427 area to reflect the new position of the scroller thumbs. 00428 00429 Purpose: This function begins by posting a WM_SCROLLEREVENT message to the parent 00430 CCamView, indicating that the scroll offset has changed (possibly by some 00431 prior action by the CCamView) and that its client area needs repainting. 00432 00433 Note: In the custom scroller code on which this class is based, this really did 00434 redraw the thumb. With the OS scrollbars the only thing still needed from 00435 it however is to inform our parent of the change. 00436 00437 SeeAlso: CScroller::MoveThumb(BOOL redraw) 00438 00439 **********************************************************************************************/ 00440 00441 void CWinScroller::MoveThumb(BOOL redraw) 00442 { 00443 // Inform owner that something is happening. Note that SendMessage() *must* be used 00444 // here, not PostMessage(). The internal values of the scroller must have 00445 // been updated before this call, as CCamView will try to read the scroller's 00446 // thumb position whilst processing the sent message. 00447 // GetParent()->SendMessage(WM_SCROLLEREVENT, WPARAM(redraw), LPARAM(this)); 00448 } 00449 00450 /********************************************************************************************* 00451 > void CWinScroller::ClipThumbPos(const XLONG& n) 00452 00453 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00454 Created: 6/10/04 00455 Inputs: An XLONG giving the proposed offset of the thumb within the scroller range. 00456 Purpose: Makes sure that the new scroller thumb position is within the set range of 00457 the scroller and does not result in "overscroll" (when the area beyond the 00458 document is visible within the scrolled window). Sets the scroller thumb 00459 position accordingly. 00460 00461 **********************************************************************************************/ 00462 00463 void CWinScroller::ClipThumbPos(const XLONG& n) 00464 { 00465 // find out last possible position (from CScrollBar) 00466 XLONG lastpos = GetScrollLimit(); 00467 00468 if (n < MinVal) 00469 ThumbVal = MinVal; 00470 else if (n > lastpos) 00471 ThumbVal = lastpos; 00472 else 00473 ThumbVal = n; 00474 SnapToGrain(&ThumbVal); // make sure the scroll position always 00475 } // coincides with a grain boundary. 00476 00477 /********************************************************************************************* 00478 > void CWinScroller::SetGranularity(const XLONG& unit) 00479 00480 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> (from Justin CScroller code) 00481 Created: 6/10/04 00482 Inputs: An XLONG giving the smallest possible change that can be made to a 00483 scroller value. All scroll positions stored within the scroller are 00484 integer multiples of this value. 00485 Outputs: - 00486 Returns: - 00487 Purpose: All scroll positions are adjusted to be multiples of this number. This 00488 ensures, for example, that scroll offsets coincide with pixels. It's 00489 easiest to think of this as the "units", in millipoints, that scroll 00490 offsets are measured in. 00491 Errors: - 00492 Scope: Public 00493 SeeAlso: CWinScroller::ClipThumbPos(); CWinScroller::SnapToGrain() 00494 00495 **********************************************************************************************/ 00496 00497 void CWinScroller::SetGranularity(const XLONG& unit) 00498 { 00499 Granularity = unit; 00500 } 00501 00502 00503 00504 /********************************************************************************************* 00505 > void CWinScroller::SnapToGrain(XLONG* pxl) const 00506 00507 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00508 Created: 13th Sept 1993 00509 Inputs: A pointer to an XLONG. 00510 Outputs: Adjusts the pointed to XLONG so that it is the largest multiple of the 00511 Granularity <= its original value. 00512 Returns: - 00513 Purpose: All scroll positions are adjusted to be multiples of this number. This 00514 ensures, for example, that scroll offsets coincide with pixels. It's 00515 easiest to think of this as the "units", in millipoints, that scroll 00516 offsets are measured in. 00517 Errors: - 00518 Scope: Public 00519 SeeAlso: CWinScroller::SetGranularity(); CWinScroller::ClipThumbPos() 00520 00521 **********************************************************************************************/ 00522 00523 void CWinScroller::SnapToGrain(XLONG* pxl) const 00524 { 00525 *pxl = (*pxl / Granularity) * Granularity; 00526 } 00527 00528 00529 00530 /********************************************************************************************* 00531 > void CWinScroller::SetScrollPos(const XLONG& n, BOOL redraw) 00532 00533 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00534 Created: 6/10/04 00535 Inputs: An XLONG giving the offset of the thumb within the scroller range, and a 00536 boolean which if TRUE will update the scrollable client area to reflect 00537 the new thumb position. 00538 Outputs: - 00539 Returns: - 00540 Purpose: Checks that the new offset is within the range (clipping it if it isn't) 00541 and moves the thumb. If the scroller is currently disabled the new 00542 scroll position is noted but the thumb is not redrawn in the new 00543 position. 00544 Errors: - 00545 Scope: Public 00546 SeeAlso: CWinScroller::GetScrollPos(); CWinScroller::MoveThumb(); CCamView::SetScrollOffsets() 00547 00548 **********************************************************************************************/ 00549 00550 void CWinScroller::SetScrollPos(const XLONG& n, BOOL redraw) 00551 { 00552 ClipThumbPos(n); 00553 MoveThumb(redraw && Enabled); 00554 00555 // Set the position of the scroll box. 00556 CScrollBar::SetScrollPos((INT32)ThumbVal ,true); 00557 } 00558 00559 00560 00561 /********************************************************************************************* 00562 > void CWinScroller::SetScrollRange(const XLONG& lo, const XLONG& hi, BOOL redraw) 00563 00564 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00565 Created: 6/10/04 00566 Inputs: The "low" and "high" points of the scroller's range; a boolean which if TRUE 00567 indicates that the client area should be redrawn immediately to reflect 00568 the change in the range (and possible change in scroll offset). 00569 Outputs: - 00570 Returns: - 00571 Purpose: Sets internal variables which hold the limits and the range of the scroller, 00572 according to the parameters. Makes sure that the thumb remains "in range". 00573 If the scroller range is less than a page in size, the scroller is disabled. 00574 The size of the thumb is recalculated and the scroller is redrawn. 00575 00576 Errors: Raise an ERROR2 if the input is not within range for 32 bit signed integers 00577 00578 Notes: Because windows scrollbar ranges are defined as INT32, we need to check for 00579 potential loss of data in our xlong input. Although it is not currently possible 00580 to create a camelot document large enought to break these INT32 boundaries, this 00581 check will be useful to pinpoint bugs if camelot is ever extended to allow larger 00582 documents (e.g. multiple spreads). 00583 00584 Note that we could have just downcast the parameters to ints and relied on xlong 00585 handling an overflow on performing the conversion, but according to the docs if 00586 XLONG is not in the integer range conversion will produce some unexpected results. 00587 00588 Scope: Public 00589 SeeAlso: CWinScroller::EnableScroller(); CWinScroller::CalcThumbSize(); 00590 CWinScroller::MoveThumb(); CWinScroller::GetScrollRange() 00591 00592 **********************************************************************************************/ 00593 00594 void CWinScroller::SetScrollRange(const XLONG& lo, const XLONG& hi, BOOL redraw) 00595 { 00596 const INT32 MIN= -2147483647 - 1; 00597 const INT32 MAX= 2147483647; 00598 if( lo < MIN || hi < MIN || lo > MAX || hi > MAX ) 00599 { 00600 ERROR2RAW( "SetScrollRange limits exceeded!"); 00601 } 00602 00603 // Calculate the "direction" (Delta) and the limits of the scroller. 00604 MinVal = lo; 00605 SnapToGrain(&MinVal); 00606 MaxVal = hi; 00607 SnapToGrain(&MaxVal); 00608 Range = Abs(MaxVal - MinVal); 00609 Delta = (MaxVal > MinVal ? 1 : (MaxVal < MinVal ? -1 : 0)); 00610 00611 // If necessary adjust the position of the thumb, so that it remains within 00612 // the new range. 00613 ClipThumbPos(ThumbVal); 00614 MoveThumb(redraw); 00615 00616 // Now pass minimum and maximum position values to the CScrollBar control. Also set the 00617 // nPage value because otherwise CScrollBar will miscalculate the thumbsize when we are 00618 // zooming back up from a view that is smaller than the render window (e.g 25% to 100%). 00619 00620 SCROLLINFO si; 00621 si.cbSize = sizeof(SCROLLINFO); 00622 si.fMask = SIF_PAGE|SIF_RANGE; 00623 si.nPage = (INT32)PageSize; 00624 si.nMin = MinVal; 00625 si.nMax = MaxVal; 00626 SetScrollInfo(&si, true); 00627 } 00628 00629 00630 00631 /********************************************************************************************* 00632 > void CWinScroller::SetLineSize(const XLONG& sz) 00633 00634 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00635 Created: ages ago 00636 Inputs: An XLONG holding the size of a "line", which is the amount scrolled when a 00637 CWinScroller button control is clicked once. 00638 Outputs: - 00639 Returns: - 00640 Purpose: Sets the line size. CCamView generally sets this to one tenth of the client 00641 area. 00642 Errors: - 00643 Scope: Public 00644 SeeAlso: CWinScroller::GetLineSize(); CWinScroller::LineUp(); CWinScroller::LineDown(); 00645 CCamView::OnSize() 00646 00647 **********************************************************************************************/ 00648 00649 void CWinScroller::SetLineSize(const XLONG& sz) 00650 { 00651 LineSize = sz; 00652 SnapToGrain(&LineSize); 00653 } 00654 00655 00656 00657 /********************************************************************************************* 00658 > void CWinScroller::SetPageSize(const XLONG& sz) 00659 00660 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00661 Created: 6/10/04 00662 Inputs: An XLONG which holds the size of a "page" - the amount scrolled in response 00663 to a click on the scroller which misses the buttons and the thumb. 00664 Outputs: - 00665 Returns: - 00666 Purpose: Sets the page size. CCamView sets this to the size of the client area. 00667 Anything else will allow the scroller to scroll past the end of the document. 00668 Errors: - 00669 Scope: Public 00670 SeeAlso: CWinScroller::GetPageSize(); CWinScroller::PageUp(); CWinScroller::PageDown(); 00671 CCamView::OnSize() 00672 00673 **********************************************************************************************/ 00674 00675 void CWinScroller::SetPageSize(const XLONG& sz) 00676 { 00677 PageSize = sz; 00678 SnapToGrain(&PageSize); 00679 // CalcThumbSize(); 00680 MoveThumb(FALSE); 00681 00682 SCROLLINFO si; 00683 si.cbSize = sizeof(SCROLLINFO); 00684 si.fMask = SIF_PAGE; 00685 si.nPage = (INT32)PageSize; 00686 SetScrollInfo(&si, true); 00687 } 00688 00689 00690 00691 /********************************************************************************************* 00692 > void CWinScroller::LineUp() 00693 00694 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00695 Created: ages ago 00696 Inputs: - 00697 Outputs: - 00698 Returns: - 00699 Purpose: Scrolls "up" one line (ie. towards the low limit of the scroller range). 00700 Errors: - 00701 Scope: Public 00702 SeeAlso: CWinScroller::LineDown(); CWinScroller::SetLineSize(); CWinScroller::GetLineSize(); 00703 CWinScroller::OnDecBtnClick(); CWinScroller::OnIncBtnClick() 00704 00705 **********************************************************************************************/ 00706 00707 void CWinScroller::LineUp() 00708 { 00709 SetScrollPos(ThumbVal - Delta * LineSize); 00710 } 00711 00712 00713 00714 /********************************************************************************************* 00715 > void CWinScroller::LineDown() 00716 00717 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00718 Created: ages ago 00719 Inputs: 00720 Outputs: 00721 Returns: 00722 Purpose: Scrolls "down" one line (ie. towards the high limit of the scroller range). 00723 Errors: - 00724 Scope: Public 00725 SeeAlso: CWinScroller::LineUp(); CWinScroller::SetLineSize(); CWinScroller::GetLineSize(); 00726 CWinScroller::OnDecBtnClick(); CWinScroller::OnIncBtnClick() 00727 00728 **********************************************************************************************/ 00729 00730 void CWinScroller::LineDown() 00731 { 00732 SetScrollPos(ThumbVal + Delta * LineSize); 00733 } 00734 00735 00736 00737 /********************************************************************************************* 00738 > void CWinScroller::PageUp() 00739 00740 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00741 Created: ages ago 00742 Inputs: - 00743 Outputs: - 00744 Returns: - 00745 Purpose: Scrolls "up" one page (towards the low limit of the scroller range). 00746 Errors: - 00747 Scope: Public 00748 SeeAlso: CWinScroller::PageDown(); CWinScroller::SetPageSize(); CWinScroller::GetPageSize(); 00749 CWinScroller::OnLButtonDown(); CWinScroller::OnRButtonDown(); 00750 CWinScroller::HandleMouseDown(); CWinScroller::CalcPageUpDownRects() 00751 00752 **********************************************************************************************/ 00753 00754 void CWinScroller::PageUp() 00755 { 00756 SetScrollPos(ThumbVal - Delta * PageSize); 00757 } 00758 00759 00760 00761 /********************************************************************************************* 00762 > void CWinScroller::PageDown() 00763 00764 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00765 Created: ages ago 00766 Inputs: - 00767 Outputs: - 00768 Returns: - 00769 Purpose: Scrolls "down" one page (towards the low limit of the scroller range). 00770 Errors: - 00771 Scope: Public 00772 SeeAlso: CWinScroller::PageUp(); CWinScroller::SetPageSize(); CWinScroller::GetPageSize(); 00773 CWinScroller::OnLButtonDown(); CWinScroller::OnRButtonDown(); 00774 CWinScroller::HandleMouseDown(); CWinScroller::CalcPageUpDownRects() 00775 00776 **********************************************************************************************/ 00777 00778 void CWinScroller::PageDown() 00779 { 00780 SetScrollPos(ThumbVal + Delta * PageSize); 00781 } 00782 00783 00784 00785 /********************************************************************************************* 00786 > void CWinScroller::ShowScroller(BOOL show) 00787 00788 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00789 Created: ages ago 00790 Inputs: A boolean which is FALSE if the scroller is to be hidden, TRUE if to be made 00791 visible. 00792 Outputs: - 00793 Returns: - 00794 Purpose: Shows or hides this scroller. Note that hiding a scroller and leaving an 00795 empty "hole" looks really ugly, so you probably won't be calling this very 00796 much. 00797 Errors: - 00798 Scope: Public 00799 SeeAlso: CWinScroller::EnableScroller() 00800 00801 **********************************************************************************************/ 00802 00803 void CWinScroller::ShowScroller(BOOL show) 00804 { 00805 ShowWindow(show ? SW_SHOWNA : SW_HIDE); 00806 } 00807 00808 /********************************************************************************************* 00809 00810 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>, modified by Marc 00811 Inputs: A long pointer to a rectangle which describes the dimensions of the client 00812 area of the window containing the scroller. 00813 Outputs: Changes *lpRect to the position a the scroll bar would occupy normally, ie. 00814 along the bottom or side of the owning window. 00815 Returns: - 00816 Purpose: Called by CCamView when its size changes, so it knows where to reposition 00817 the CHorzScroller. 00818 Errors: - 00819 Scope: Public 00820 SeeAlso: CCamView::OnSize() 00821 00822 **********************************************************************************************/ 00823 void CWinScroller::CalcPosFromParentClient(LPRECT lpRect) 00824 { 00825 if(Horizontal) 00826 { 00827 CRect parentRect; 00828 GetParent()->GetClientRect(&parentRect); 00829 lpRect->left = parentRect.left+1; 00830 lpRect->top = parentRect.bottom - ::GetSystemMetrics(SM_CYHSCROLL) + 1; 00831 lpRect->right = parentRect.right - ::GetSystemMetrics(SM_CXVSCROLL) + 1; 00832 lpRect->bottom = parentRect.bottom + 1; 00833 } 00834 else 00835 { 00836 CRect parentRect; 00837 GetParent()->GetClientRect(&parentRect); 00838 lpRect->left = parentRect.right - ::GetSystemMetrics(SM_CXVSCROLL) + 1; 00839 lpRect->top = parentRect.top + 1; 00840 lpRect->right = parentRect.right + 1; 00841 lpRect->bottom = parentRect.bottom - ::GetSystemMetrics(SM_CYHSCROLL) + 1; 00842 } 00843 } 00844 00845 /********************************************************************************************* 00846 > void CWinScroller::HandleScrollMessage(UINT32 nSBCode, UINT32 nPos) 00847 00848 Author: Marc_Power (Xara Group Ltd) <camelotdev@xara.com> 00849 Created: 6/10/04 00850 Purpose: Process a windows scroller event 00851 00852 **********************************************************************************************/ 00853 void CWinScroller::HandleScrollMessage(UINT32 nSBCode, UINT32 nPos) 00854 { 00855 switch(nSBCode) 00856 { 00857 case SB_PAGEDOWN: 00858 PageDown() ; 00859 break ; 00860 case SB_PAGEUP: 00861 PageUp() ; 00862 break ; 00863 case SB_LINEDOWN: 00864 LineDown() ; 00865 break ; 00866 case SB_LINEUP: 00867 LineUp(); 00868 break ; 00869 case SB_THUMBTRACK: 00870 case SB_THUMBPOSITION: 00871 // See KB article Q166473 - nPos is a legacy 16 bit coordinate. 00872 // Replace it with true 32-bit scroll position 00873 SCROLLINFO si; 00874 si.cbSize = sizeof(SCROLLINFO); 00875 si.fMask = SIF_TRACKPOS; 00876 GetScrollInfo(&si); 00877 nPos = si.nTrackPos; 00878 00879 XLONG pos = 0; 00880 pos +=nPos; 00881 SetScrollPos(pos , true); 00882 break; 00883 } 00884 } 00885 00886 #endif