00001 // $Id: scrlthmb.cpp 751 2006-03-31 15:43: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 The proportional scroller thumb window. 00100 00101 00102 */ 00103 00104 00105 #include "camtypes.h" 00106 00107 #include "scroller.h" 00108 #include "scrlthmb.h" 00109 #include "csrstack.h" 00110 //#include "colordlg.h" // For cursor resources, 'cos I don't like changing camelot.h! 00111 00112 #include "brushmsg.h" // for the screenchange message 00113 00114 #ifdef _DEBUG 00115 #undef THIS_FILE 00116 static char BASED_CODE THIS_FILE[] = __FILE__; 00117 #endif 00118 00119 // Version information. 00120 DECLARE_SOURCE("$Revision: 751 $"); 00121 00122 00123 00124 /******************************************************************************************** 00125 > void PatB(CDC* hDC, INT32 x, INT32 y, INT32 dx, INT32 dy, COLORREF rgb) 00126 00127 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Some MFC dude, actually) 00128 Created: 14/3/94 00129 Inputs: hDC - destination DC 00130 x,y,dx,dy - rectangle to fill 00131 rgb - colour to fill with 00132 Purpose: Paints a rectangle in the given (dithered) colour 00133 It looks pretty hideous, but this is how the MFC buttonbar does it... 00134 The conclusions that this leads to are left as an exercise for the reader. 00135 (OK, so they're not. It suggest that either MFC sux, or plotting text is 00136 easier/faster than creating a brush, in which case Windoze sux) 00137 ********************************************************************************************/ 00138 00139 static void NEAR PASCAL PatB(CDC* cDC, INT32 x, INT32 y, INT32 dx, INT32 dy, COLORREF rgb) 00140 { 00141 RECT rect; 00142 rect.left = x; 00143 rect.top = y; 00144 rect.right = x + dx; 00145 rect.bottom = y + dy; 00146 00147 cDC->SetBkColor(rgb); 00148 cDC->ExtTextOut(0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL); 00149 } 00150 00151 static Cursor *AdjustDragCursor = NULL; 00152 static INT32 DragCursorID = 0; 00153 00154 /********************************************************************************************* 00155 > CScrollerThumb::CScrollerThumb() 00156 00157 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00158 Created: ages ago 00159 Inputs: - 00160 Outputs: - 00161 Returns: - 00162 Purpose: Constructs a CScrollerThumb C++ object. Sets an internal variable to 00163 indicate that the thumb is currently NOT in dragging mode. 00164 Errors: - 00165 Scope: Public 00166 SeeAlso: CScrollerThumb::Create(); CScroller::ConstructThumb() 00167 00168 **********************************************************************************************/ 00169 00170 CScrollerThumb::CScrollerThumb() : Dragging(FALSE) 00171 { 00172 // Nothing to do. 00173 } 00174 00175 00176 00177 00178 /******************************************************************************************** 00179 00180 > CScrollerThumb::~CScrollerThumb() 00181 00182 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00183 Created: 17/11/93 00184 Inputs: - 00185 Outputs: - 00186 Returns: - 00187 Purpose: Destructor for class CScrollerThumb. Doesn't precisely nothing. 00188 Errors: - 00189 SeeAlso: - 00190 00191 ********************************************************************************************/ 00192 00193 CScrollerThumb::~CScrollerThumb() 00194 { 00195 // Nothing to do. 00196 // if (Dragging) ::ReleaseCapture(); 00197 } 00198 00199 00200 00201 00202 00203 /********************************************************************************************* 00204 > virtual BOOL CScrollerThumb::Create(LPCTSTR, LPCTSTR, DWORD style, const RECT& rect, 00205 CWnd* parent, UINT32 id, CCreateContext* ctxt = 0) 00206 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00207 Created: ages ago 00208 Inputs: Two dummy long pointers, not used; the window-instance style flags; the size 00209 and position of the window; the parent; the numeric ID, the creation context. 00210 Outputs: - 00211 Returns: TRUE if the CScrollerThumb is successfully created (attached to a Windows 00212 interface element). 00213 Purpose: Sets the class cursor used for the thumb window. 00214 Errors: - 00215 Scope: Public 00216 SeeAlso: CScrollerThumb::CScrollerThumb(); CScroller::OnCreate() 00217 **********************************************************************************************/ 00218 00219 BOOL CScrollerThumb::Create(LPCTSTR, LPCTSTR, DWORD style, const RECT& rect, 00220 CWnd* parent, UINT32 id, CCreateContext* ctxt) 00221 { 00222 return CWnd::Create(AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNCLIENT, 00223 Cursor::Arrow->Handle(), 00224 0, 00225 0), 00226 "", 00227 style | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 00228 rect, 00229 parent, 00230 id, 00231 ctxt); 00232 } 00233 00234 00235 00237 // CScrollerThumb implementation. 00238 // 00239 00240 /********************************************************************************************* 00241 > void CScrollerThumb::PostMsgToScroller(UINT32 msg, CPoint pt) const 00242 00243 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00244 Created: ages ago 00245 Inputs: The message ID to posted; the (mouse) coordinates, relative to the thumb's 00246 client area, to be posted along with the message. 00247 Outputs: - 00248 Returns: - 00249 Purpose: Posts a private message to the parent CScroller window. Converts the 00250 coordinates passed in so that they are relative to the CScroller's client 00251 area. 00252 Errors: - 00253 Scope: Private 00254 SeeAlso: CScrollerThumb::OnLButtonDown(); CScrollerThumb::OnMouseMove(); 00255 CScrollerThumb::OnLButtonUp() 00256 **********************************************************************************************/ 00257 00258 void CScrollerThumb::PostMsgToScroller(UINT32 msg, CPoint pt) const 00259 { 00260 ClientToScreen(&pt); 00261 GetParent()->ScreenToClient(&pt); 00262 GetParent()->PostMessage(msg, pt.x, pt.y); 00263 } 00264 00265 00266 00267 00269 // CScrollerThumb message handlers 00270 00271 00272 /********************************************************************************************* 00273 > afx_msg void CScrollerThumb::OnWin95Paint() 00274 00275 Author: Chris_Parks (Xara Group Ltd) <camelotdev@xara.com> 00276 Created: 4/10/95 00277 Inputs: - 00278 Outputs: - 00279 Returns: - 00280 Purpose: Responds to a WM_PAINT message sent by Windows. Paints the light and dark 00281 shading around the edge of the thumb, so it looks like the genuine Windows 00282 95 article. 00283 Errors: - 00284 Scope: Protected 00285 SeeAlso: - 00286 **********************************************************************************************/ 00287 void CScrollerThumb::OnWin95Paint() 00288 { 00289 // Create a device context to paint on, and find out the extent of this window. 00290 CPaintDC dc(this); 00291 dc.SetROP2(R2_COPYPEN); 00292 CRect rect; 00293 GetClientRect(&rect); 00294 00295 // Fill the inside of the thumb, drawing a thin black border around it. 00296 CBrush interior(::GetSysColor(COLOR_BTNFACE)); 00297 CBrush* oldbrush = dc.SelectObject(&interior); 00298 00299 // Draw the shade inside the bottom and right edges. 00300 CPen shade(PS_SOLID, 1,RGB(255,0,0));// ::GetSysColor(COLOR_BTNSHADOW)); 00301 CPen* oldpen = dc.SelectObject(&shade); 00302 00303 dc.Rectangle(&rect); 00304 00305 COLORREF TopLeft = GetSysColor(COLOR_BTNFACE); 00306 COLORREF BotRight = GetSysColor(COLOR_WINDOWFRAME); 00307 COLORREF TopLeftInside = GetSysColor(COLOR_BTNHIGHLIGHT); 00308 COLORREF BotRightInside = GetSysColor(COLOR_BTNSHADOW); 00309 00310 INT32 x = rect.left; 00311 INT32 y = rect.top; 00312 INT32 dx = rect.Width(); 00313 INT32 dy = rect.Height(); 00314 00315 // The plinth is always made up of 4 right-angle elements 00316 // When indented, the colours are swapped, but the elements retain position 00317 PatB(&dc, x, y, 1, dy-1, TopLeft); 00318 PatB(&dc, x, y, dx-1, 1, TopLeft); 00319 00320 PatB(&dc, x+dx-1, y, 1, dy, BotRight); 00321 PatB(&dc, x, y+dy-1, dx, 1, BotRight); 00322 00323 PatB(&dc, x+1, y+1, 1, dy-2, TopLeftInside); 00324 PatB(&dc, x+1, y+1, dx-2, 1, TopLeftInside); 00325 00326 PatB(&dc, x+dx-2, y+1, 1, dy-2, BotRightInside); 00327 PatB(&dc, x+1, y+dy-2, dx-2, 1, BotRightInside); 00328 00329 dc.SelectObject(oldbrush); 00330 dc.SelectObject(oldpen); 00331 } 00332 00333 /********************************************************************************************* 00334 > afx_msg void CScrollerThumb::OnPaint() 00335 00336 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00337 Created: ages ago 00338 Inputs: - 00339 Outputs: - 00340 Returns: - 00341 Purpose: Responds to a WM_PAINT message sent by Windows. Paints the light and dark 00342 shading around the edge of the thumb, so it looks like the genuine Windows 00343 article. 00344 Errors: - 00345 Scope: Protected 00346 SeeAlso: - 00347 **********************************************************************************************/ 00348 00349 void CScrollerThumb::OnPaint() 00350 { 00351 if(CScroller::IsChicago()) 00352 { 00353 OnWin95Paint(); 00354 return; 00355 } 00356 // Create a device context to paint on, and find out the extent of this window. 00357 CPaintDC dc(this); 00358 dc.SetROP2(R2_COPYPEN); 00359 CRect rect; 00360 GetClientRect(&rect); 00361 00362 // Fill the inside of the thumb, drawing a thin black border around it. 00363 CBrush interior(::GetSysColor(COLOR_BTNFACE)); 00364 CBrush* oldbrush = dc.SelectObject(&interior); 00365 dc.Rectangle(&rect); 00366 00367 // Draw the shade inside the bottom and right edges. 00368 CPen shade(PS_SOLID, 2, ::GetSysColor(COLOR_BTNSHADOW)); 00369 CPen* oldpen = dc.SelectObject(&shade); 00370 00371 dc.MoveTo(rect.left + 2, rect.bottom - 2); 00372 dc.LineTo(rect.right - 2, rect.bottom - 2); 00373 dc.LineTo(rect.right - 2, rect.top + 2); 00374 00375 // Draw the highlight, half as wide, inside the left and top edges. 00376 CPen highlight(PS_SOLID, 1, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 00377 dc.SelectObject(&highlight); 00378 dc.MoveTo(rect.left + 1, rect.bottom - 3); 00379 dc.LineTo(rect.left + 1, rect.top + 1); 00380 dc.LineTo(rect.right - 2, rect.top + 1); 00381 00382 // For some reason Windows sometimes refuses to draw the first pixel of the highlight, 00383 // so draw that one ourselves. I'm not wasting any more time debugging the display 00384 // driver!! 00385 dc.SetPixel(rect.left + 1, rect.bottom - 3, ::GetSysColor(COLOR_BTNHIGHLIGHT)); 00386 00387 // Deselect our drawing tools before they are destroyed. 00388 dc.SelectObject(oldbrush); 00389 dc.SelectObject(oldpen); 00390 } 00391 00392 00393 00394 /********************************************************************************************* 00395 > afx_msg void CScrollerThumb::OnLButtonDown(UINT32 nFlags, CPoint point) 00396 00397 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00398 Created: ages ago 00399 Inputs: Some flags detailing which buttons and keys were down when the mouse message 00400 was generated; the coordinates of the mouse cursor. 00401 Outputs: - 00402 Returns: - 00403 Purpose: Captures the mouse and sends a WM_GRABTHUMB message to the parent CScroller. 00404 Errors: - 00405 Scope: Protected 00406 SeeAlso: CScrollerThumb::PostMsgToScroller(); CScroller::OnGrabThumb(); 00407 CScrollerThumb::OnMouseMove(); CScrollerThumb::OnLButtonUp() 00408 **********************************************************************************************/ 00409 00410 void CScrollerThumb::OnLButtonDown(UINT32 nFlags, CPoint point) 00411 { 00412 CWnd::OnLButtonDown(nFlags, point); 00413 if (!Dragging) 00414 { 00415 Dragging = TRUE; 00416 DragIsAdjust = FALSE; 00417 SetCapture(); 00418 PostMsgToScroller(WM_GRABTHUMB, point); 00419 } 00420 } 00421 00422 00423 00424 /********************************************************************************************* 00425 > afx_msg void CScrollerThumb::OnRButtonDown(UINT32 nFlags, CPoint point) 00426 00427 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00428 Created: 16/11/94 00429 Inputs: Some flags detailing which buttons and keys were down when the mouse message 00430 was generated; the coordinates of the mouse cursor. 00431 Outputs: - 00432 Returns: - 00433 Purpose: Captures the mouse and sends a WM_GRABTHUMBADJ message to the parent CScroller 00434 Errors: - 00435 Scope: Protected 00436 SeeAlso: CScrollerThumb::PostMsgToScroller(); CScroller::OnGrabThumb(); 00437 CScrollerThumb::OnMouseMove(); CScrollerThumb::OnLButtonUp() 00438 **********************************************************************************************/ 00439 00440 void CScrollerThumb::OnRButtonDown(UINT32 nFlags, CPoint point) 00441 { 00442 CWnd::OnRButtonDown(nFlags, point); 00443 if (!Dragging) 00444 { 00445 Dragging = TRUE; 00446 DragIsAdjust = TRUE; 00447 SetCapture(); 00448 00449 if (((CScroller *)GetParent())->LinkedScroller != NULL) // If adjust-drag is enabled... 00450 { 00451 // Try to set new pointer shape for the drag 00452 if (AdjustDragCursor == NULL) 00453 AdjustDragCursor = new Cursor(_R(IDC_ADJUSTSCROLL)); 00454 if (AdjustDragCursor != NULL) 00455 DragCursorID = CursorStack::GPush(AdjustDragCursor); 00456 } 00457 00458 PostMsgToScroller(WM_GRABTHUMBADJ, point); 00459 } 00460 } 00461 00462 00463 00464 /********************************************************************************************* 00465 > afx_msg void CScrollerThumb::OnMouseMove(UINT32 nFlags, CPoint point) 00466 00467 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00468 Created: ages ago 00469 Inputs: Some flags detailing which buttons and keys were down when the mouse message 00470 was generated; the coordinates of the mouse cursor. 00471 Outputs: - 00472 Returns: - 00473 Purpose: Sends a WM_DRAGTHUMB message to the parent CScroller. 00474 Errors: - 00475 Scope: Protected 00476 SeeAlso: CScrollerThumb::PostMsgToScroller(); CScroller::OnDragThumb(); 00477 CScrollerThumb::OnLButtonDown(); CScrollerThumb::OnLButtonUp() 00478 **********************************************************************************************/ 00479 00480 void CScrollerThumb::OnMouseMove(UINT32 nFlags, CPoint point) 00481 { 00482 CWnd::OnMouseMove(nFlags, point); 00483 if (Dragging) PostMsgToScroller((DragIsAdjust) ? WM_DRAGTHUMBADJ : WM_DRAGTHUMB, point); 00484 } 00485 00486 00487 00488 /********************************************************************************************* 00489 > afx_msg void CScrollerThumb::OnLButtonUp(UINT32 nFlags, CPoint point) 00490 00491 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00492 Created: ages ago 00493 Inputs: Some flags detailing which buttons and keys were down when the mouse message 00494 was generated; the coordinates of the mouse cursor. 00495 Outputs: - 00496 Returns: - 00497 Purpose: Releases the captured mouse and sends a WM_RELEASETHUMB message to the parent 00498 CScroller. 00499 Errors: - 00500 Scope: Protected 00501 SeeAlso: CScrollerThumb::PostMsgToScroller(); CScroller::OnDragThumb(); 00502 CScrollerThumb::OnLButtonDown(); CScrollerThumb::OnMouseMove() 00503 **********************************************************************************************/ 00504 00505 void CScrollerThumb::OnLButtonUp(UINT32 nFlags, CPoint point) 00506 { 00507 CWnd::OnLButtonUp(nFlags, point); 00508 if (Dragging) 00509 { 00510 Dragging = FALSE; 00511 ::ReleaseCapture(); 00512 PostMsgToScroller((DragIsAdjust) ? WM_RELEASETHUMBADJ : WM_RELEASETHUMB, point); 00513 } 00514 // tell people the screen has changed 00515 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 00516 } 00517 00518 00519 00520 /********************************************************************************************* 00521 > afx_msg void CScrollerThumb::OnRButtonUp(UINT32 nFlags, CPoint point) 00522 00523 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> (Jason copied OnLButtonUp, 16/11/94) 00524 Created: ages ago 00525 Inputs: Some flags detailing which buttons and keys were down when the mouse message 00526 was generated; the coordinates of the mouse cursor. 00527 Outputs: - 00528 Returns: - 00529 Purpose: Releases the captured mouse and sends a WM_RELEASETHUMB message to the parent 00530 CScroller. 00531 Errors: - 00532 Scope: Protected 00533 SeeAlso: CScrollerThumb::PostMsgToScroller(); CScroller::OnDragThumb(); 00534 CScrollerThumb::OnLButtonDown(); CScrollerThumb::OnMouseMove() 00535 **********************************************************************************************/ 00536 00537 void CScrollerThumb::OnRButtonUp(UINT32 nFlags, CPoint point) 00538 { 00539 CWnd::OnRButtonUp(nFlags, point); 00540 if (Dragging) 00541 { 00542 Dragging = FALSE; 00543 ::ReleaseCapture(); 00544 00545 // Restore old pointer shape after the drag 00546 if (AdjustDragCursor != NULL) 00547 { 00548 CursorStack::GPop(DragCursorID); 00549 delete AdjustDragCursor; 00550 AdjustDragCursor = NULL; 00551 DragCursorID = 0; 00552 } 00553 00554 PostMsgToScroller((DragIsAdjust) ? WM_RELEASETHUMBADJ : WM_RELEASETHUMB, point); 00555 } 00556 // tell people things have changed on screen 00557 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 00558 } 00559 00560 00561 00563 // CScrollThumb message map. 00564 00565 BEGIN_MESSAGE_MAP(CScrollerThumb, CWnd) 00566 //{{AFX_MSG_MAP(CScrollerThumb) 00567 ON_WM_PAINT() 00568 ON_WM_LBUTTONDOWN() 00569 ON_WM_RBUTTONDOWN() 00570 ON_WM_MOUSEMOVE() 00571 ON_WM_LBUTTONUP() 00572 ON_WM_RBUTTONUP() 00573 //}}AFX_MSG_MAP 00574 END_MESSAGE_MAP()