00001 // $Id: opdragbx.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 00100 opdragbx.cpp 00101 00102 Base-class for easy drag box operations. 00103 00104 */ 00105 00106 #include "camtypes.h" 00107 #include "opdragbx.h" 00108 //#include "app.h" 00109 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "stockcol.h" 00112 00113 00114 // Revision information. 00115 DECLARE_SOURCE("$Revision: 1282 $"); 00116 00117 // Standard preliminaries. We don't use new anywhere but if we ever do this will help us 00118 // use it properly (hee hee). 00119 CC_IMPLEMENT_DYNCREATE(OpDragBox, Operation) 00120 CC_IMPLEMENT_DYNCREATE(OpCentredDragBox, OpDragBox) 00121 #define new CAM_DEBUG_NEW 00122 00123 00124 00125 /************************************************************************************** 00126 Preference: DoSolidDragBoxes 00127 Section: Dragging 00128 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00129 Range: FALSE or TRUE 00130 Purpose: Determines how the drag operation base-class draws a drag box. If 00131 FALSE then the "tranditional" unfilled xor rectangle with a certain 00132 line colour is drawn. If FALSE a filled ("solid") xor rectangle of a 00133 certain line and fill colour will be drawn. The default is FALSE. 00134 ***************************************************************************************/ 00135 00136 BOOL OpDragBox::m_fDoSolidDragBoxes = FALSE; 00137 00138 00139 00140 /******************************************************************************************** 00141 > static BOOL OpDragBox::Init() 00142 00143 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00144 Created: 24/4/95 00145 Returns: TRUE if successful, FALSE if otherwise. 00146 Purpose: Initialises the OpDragBox base-class drag operation. Loads preferences. 00147 ********************************************************************************************/ 00148 00149 BOOL OpDragBox::Init() 00150 { 00151 return GetApplication()->DeclareSection(TEXT("Dragging"), 5) && 00152 GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("DoSolidDragBoxes"), 00153 &m_fDoSolidDragBoxes, FALSE, TRUE); 00154 } 00155 00156 00157 00158 /******************************************************************************************** 00159 > OpDragBox::OpDragBox() 00160 00161 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00162 Created: 20/7/93 00163 Purpose: Default constructor. Only accessible to derived classes. 00164 SeeAlso: class OpCentredDragBox 00165 ********************************************************************************************/ 00166 00167 OpDragBox::OpDragBox() 00168 : m_pStartSpread(NULL) // no drag has been started yet 00169 { 00170 // Empty. 00171 } 00172 00173 00174 00175 /******************************************************************************************** 00176 > BOOL OpDragBox::DoDrag(DragType dt, 00177 Spread* pStartSpread, 00178 const DocCoord& dcStartPos, 00179 ClickModifiers cmods) 00180 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00181 Created: 22/4/95 00182 Inputs: dt what kind of drag to start, eg. DRAGTYPE_AUTOSCROLL 00183 pSpread the spread containing the anchor (start) point of the drag 00184 dcStartPos the anchor (start) point of the drag within the spread 00185 cmods the mouse click modifier state 00186 Returns: TRUE if a drag is successfully started 00187 Purpose: This is called to start a drag box operation. 00188 SeeAlso: OpDragBox::OnDragStarted 00189 ********************************************************************************************/ 00190 00191 BOOL OpDragBox::DoDrag(DragType dt, Spread* pStartSpread, 00192 const DocCoord& dcStartPos, ClickModifiers cmods) 00193 { 00194 // We use a null spread to indicate that a drag hasn't started yet, so check for this 00195 // when we reckon we should have a valid spread. 00196 ERROR3IF(pStartSpread == NULL, "Null StartSpread* passed to OpDragBox::DoDrag"); 00197 00198 // Initialise the drag box record to an empty rectangle. 00199 m_drLastDragBox.lo = m_drLastDragBox.hi = dcStartPos; 00200 00201 // Try to start the drag. Note that we don't touch m_pStartSpread if start drag fails, 00202 // so GetDragStartPos will correctly return "no drag started" if the StartDrag call 00203 // below fails. 00204 return StartDrag(dt) && OnDragStarted(m_pStartSpread = pStartSpread, 00205 m_dcStartPos = dcStartPos, 00206 cmods); 00207 } 00208 00209 00210 00211 /******************************************************************************************** 00212 > BOOL OpDragBox::GetDragStartPos(Spread** ppStartSpread, DocCoord* pdcStartPos) const 00213 00214 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00215 Created: 23/4/95 00216 Outputs: ppStartSpread where to store the spread that the drag started on 00217 pdcStartPos where to store the position that the drag started 00218 Returns: TRUE if a drag has been started, FALSE if one hasn't been started yet 00219 Purpose: Gets the the start position of the drag operation, if one has been started. 00220 Note that either of the output paramters may be NULL, which means that the 00221 caller doesn't require that particular output. 00222 ********************************************************************************************/ 00223 00224 BOOL OpDragBox::GetDragStartPos(Spread** ppStartSpread, DocCoord* pdcStartPos) const 00225 { 00226 // If a drag hasn't started yet then return fail code. 00227 if (m_pStartSpread == NULL) return FALSE; 00228 00229 // Copy the required information to the output parameters and return that a drga has 00230 // been started. 00231 if (ppStartSpread != NULL) *ppStartSpread = m_pStartSpread; 00232 if (pdcStartPos != NULL) *pdcStartPos = m_dcStartPos; 00233 return TRUE; 00234 } 00235 00236 00237 00238 /******************************************************************************************** 00239 > static inline MILLIPOINT OpDragBox::Min(MILLIPOINT a, MILLIPOINT b) 00240 00241 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00242 Created: 22/4/95 00243 Purpose: Helper function to return the smallest of two ordinates. 00244 ********************************************************************************************/ 00245 00246 inline MILLIPOINT OpDragBox::Min(MILLIPOINT a, MILLIPOINT b) 00247 { 00248 return (a < b) ? a : b; 00249 } 00250 00251 00252 00253 /******************************************************************************************** 00254 > static inline MILLIPOINT OpDragBox::Max(MILLIPOINT a, MILLIPOINT b) 00255 00256 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00257 Created: 22/4/95 00258 Purpose: Helper function to return the largest of two ordinates. 00259 ********************************************************************************************/ 00260 00261 inline MILLIPOINT OpDragBox::Max(MILLIPOINT a, MILLIPOINT b) 00262 { 00263 return (a > b) ? a : b; 00264 } 00265 00266 00267 00268 /******************************************************************************************** 00269 > void OpDragBox::DragPointerMove(DocCoord dcMousePos, ClickModifiers cmods, Spread* pSpread, BOOL bSolidDrag) 00270 00271 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00272 Created: 5/7/93 00273 Inputs: dcMousePos the current position of the mouse 00274 cmods the state of the mouse modifiers 00275 pSpread the spread containing the mouse 00276 Purpose: This is called every time the mouse moves, during a drag. It updates the 00277 xored drag box and calls the OnPointerMoved function so a derived class can 00278 do something useful. 00279 SeeAlso: OpDragBox::OnPointerMoved; OpDragBox::UpdateSolidDragBox; 00280 OpDragBox::UpdateUnfilledDragBox 00281 ********************************************************************************************/ 00282 00283 void OpDragBox::DragPointerMove(DocCoord dcMousePos, ClickModifiers cmods, Spread* pSpread, BOOL bSolidDrag) 00284 { 00285 // If the mouse has moved to another spread than translate its position into the 00286 // new spread's coordinate system. 00287 if (pSpread != m_pStartSpread && pSpread != NULL) 00288 { 00289 dcMousePos = MakeRelativeToSpread(m_pStartSpread, pSpread, dcMousePos); 00290 } 00291 00292 // Calculate the new drag rectangle. 00293 DocRect drNewDragBox = CalcDragBox(m_dcStartPos, dcMousePos); 00294 ERROR3IF(!drNewDragBox.IsValid(), "Invalid drag box in OpDragBox::DragPointerMove"); 00295 00296 // Call the appropriate update function, according to whether we are drawing solid 00297 // drag boxes or unfilled drag boxes. 00298 if (m_fDoSolidDragBoxes) 00299 { 00300 UpdateSolidDragBox(drNewDragBox); 00301 } 00302 else 00303 { 00304 UpdateUnfilledDragBox(drNewDragBox); 00305 } 00306 00307 // Update our record of the last drag box and call the derived class. 00308 if (!OnPointerMoved(m_pStartSpread, m_drLastDragBox = drNewDragBox, cmods)) 00309 { 00310 // Cancel the drag and operation. 00311 EndDrag(); 00312 End(); 00313 } 00314 } 00315 00316 00317 00318 /******************************************************************************************** 00319 > void OpDragBox::UpdateSolidDragBox(const DocRect& drNewDragBox) 00320 00321 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00322 Created: 24/4/95 00323 Inputs: drNewDragBox the new extent of the drag box, in the spread 00324 coordinates of the spread where the drag started 00325 Purpose: Calculates which rectangles to xor to change the last drawn solid drag box 00326 into the new solid drag box. 00327 SeeAlso: OpDragBox::DragPointerMove; OpDragBox::UpdateUnfilledDragBox 00328 ********************************************************************************************/ 00329 00330 void OpDragBox::UpdateSolidDragBox(const DocRect& drNewDragBox) 00331 { 00332 // Set up four update rectangles. We will xor none, some, or all of these rectangles to 00333 // produce the new drag box. 00334 DocRect drUpdate[4]; 00335 INT32 nHowMany; 00336 00337 // Find the intersection of the last and new rectangles. We will exclude this from 00338 // any xoring as it is already xored. 00339 DocRect drCommonDragBox = drNewDragBox.Intersection(m_drLastDragBox); 00340 00341 // Calculate the rectangles that need to be xored to change the last into the new 00342 // drag box. This depends on how they overlap. 00343 if (drCommonDragBox.IsEmpty()) 00344 { 00345 // There's no intersection between the last drag box and the new drag box, even 00346 // though they share a common corner. So xor the full extent of both drag rects. 00347 drUpdate[0] = m_drLastDragBox; 00348 drUpdate[1] = drNewDragBox; 00349 nHowMany = 2; 00350 } 00351 else if (drNewDragBox.ContainsRect(m_drLastDragBox)) 00352 { 00353 // The new drag rect completely contains the last one, so clip out the last. 00354 nHowMany = ((DocRect&) drNewDragBox).SplitRect(m_drLastDragBox, drUpdate); 00355 } 00356 else if (m_drLastDragBox.ContainsRect(drNewDragBox)) 00357 { 00358 // The last drag rect completely contains the new one, so clip out the new. 00359 nHowMany = m_drLastDragBox.SplitRect(drNewDragBox, drUpdate); 00360 } 00361 else 00362 { 00363 // The drag rectangles overlap but neither completely contains the other, so set 00364 // the xor rectangles to be each drag rectangle less the common drag rectangle. 00365 nHowMany = m_drLastDragBox.SplitRect(drCommonDragBox, &drUpdate[0]); 00366 nHowMany += ((DocRect&) drNewDragBox).SplitRect(drCommonDragBox, &drUpdate[nHowMany]); 00367 } 00368 00369 // Sanity check. 00370 ERROR3IF(nHowMany < 0 || nHowMany > 4, 00371 "Wrong number of split rects in OpDragBox::UpdateSolidDragBox\n"); 00372 00373 // Draw the xor rects. 00374 for (INT32 i = 0; i < nHowMany; i++) 00375 { 00376 DrawXorRect(drUpdate[i], m_pStartSpread, drUpdate[i]); 00377 } 00378 } 00379 00380 00381 00382 /******************************************************************************************** 00383 > void OpDragBox::UpdateUnfilledDragBox(const DocRect& drNewDragBox) 00384 00385 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00386 Created: 24/4/95 00387 Inputs: drNewDragBox the new extent of the drag box, in the spread 00388 coordinates of the spread where the drag started 00389 Purpose: Calculates which rectangles to xor to change the last drawn solid drag box 00390 into the new solid drag box. 00391 SeeAlso: OpDragBox::DragPointerMove; OpDragBox::UpdateSolidDragBox 00392 ********************************************************************************************/ 00393 00394 void OpDragBox::UpdateUnfilledDragBox(const DocRect& drNewDragBox) 00395 { 00396 // Remove the old drag box. 00397 DrawXorRect(m_drLastDragBox, m_pStartSpread, m_drLastDragBox); 00398 00399 // Draw the new drag box. 00400 DrawXorRect(drNewDragBox, m_pStartSpread, drNewDragBox); 00401 } 00402 00403 00404 00405 /******************************************************************************************** 00406 > void OpDragBox::DragPointerIdle(DocCoord dcMousePos, ClickModifiers cmods, Spread* pSpread, BOOL bSolidDrag) 00407 00408 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00409 Created: 5/7/93 00410 Inputs: dcMousePos the current position of the mouse 00411 cmods the state of the mouse modifiers 00412 pSpread the spread containing the mouse 00413 Purpose: This is called every time the mouse hasn't moved for a while during a drag. 00414 It calls the OnPointerIdle function so a derived class can do something 00415 useful with this time, such as hit-testing etc. 00416 SeeAlso: OpDragBox::OnPointerIdle 00417 ********************************************************************************************/ 00418 00419 void OpDragBox::DragPointerIdle(DocCoord dcMousePos, ClickModifiers cmods, Spread* pSpread, BOOL bSolidDrag) 00420 { 00421 // If the mouse has moved to another spread than translate its position into the 00422 // new spread's coordinate system. 00423 if (pSpread != m_pStartSpread && pSpread != NULL) 00424 { 00425 dcMousePos = MakeRelativeToSpread(m_pStartSpread, pSpread, dcMousePos); 00426 } 00427 00428 // Calculate the new drag rectangle. Note that as the mouse is supposed to be 00429 // stationary we do NOT redraw the drag box or update our records of it. 00430 DocRect drNewDragBox = CalcDragBox(m_dcStartPos, dcMousePos); 00431 00432 // Call the derived class, optionally cancelling the drag. 00433 if (!OnPointerIdle(m_pStartSpread, drNewDragBox, cmods)) 00434 { 00435 // Cancel the drag and operation. 00436 EndDrag(); 00437 End(); 00438 } 00439 } 00440 00441 00442 00443 /******************************************************************************************** 00444 > void OpDragBox::DragFinished(DocCoord dcMousePos, ClickModifiers cmods, 00445 Spread* pSpread, BOOL fOK, BOOL bSolidDrag) 00446 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00447 Created: 22/4/95 00448 Inputs: dcMousePos the last position of the mouse 00449 cmods the mouse click modifier state at the end 00450 pSpread the spread containing the mouse 00451 fOK whether the drag was cancelled or not 00452 was ended with the escape key being pressed 00453 Purpose: This is called when a drag operation finishes. It removes the drag box and 00454 calls the OnEndDrag function in a derived class. 00455 SeeAlso: OpDragBox::OnDragEnded 00456 ********************************************************************************************/ 00457 00458 void OpDragBox::DragFinished(DocCoord dcMousePos, ClickModifiers cmods, 00459 Spread* pSpread, BOOL fOK, BOOL bSolidDrag) 00460 { 00461 // Remove the last drag box. 00462 RenderDragBlobs(m_drLastDragBox, m_pStartSpread, bSolidDrag); 00463 00464 // It's possible that the mouse is in a different position to where it was on the last 00465 // call to DragPointerMove, so recalculate the drag box (but don't draw it, of course). 00466 // Here, check for a change in the spread containing the mouse. 00467 if (pSpread != m_pStartSpread && pSpread != NULL) 00468 { 00469 dcMousePos = MakeRelativeToSpread(m_pStartSpread, pSpread, dcMousePos); 00470 } 00471 00472 // Recalculate the drag box. 00473 m_drLastDragBox = CalcDragBox(m_dcStartPos, dcMousePos); 00474 00475 // Call the derived class handler, passing the drag box and the success code. 00476 if (!OnDragEnded(m_pStartSpread, m_drLastDragBox, cmods, EndDrag() && fOK)) 00477 { 00478 FailAndExecute(); 00479 } 00480 00481 // Finally, end the operation. 00482 End(); 00483 } 00484 00485 00486 00487 /******************************************************************************************** 00488 > void OpDragBox::RenderDragBlobs(DocRect drClip, Spread* pSpread, BOOL bSolidDrag) 00489 00490 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00491 Created: 22/4/05 00492 Inputs: drClip the clip rectangle to draw against 00493 pSpread the spread containing the clip rectangle 00494 Purpose: Xors a rectangle onto the screen to mark out the size of the current 00495 drag box. 00496 SeeAlso: OpDragBox::DrawXorRect 00497 ********************************************************************************************/ 00498 00499 void OpDragBox::RenderDragBlobs(DocRect drClip, Spread* pSpread, BOOL bSolidDrag) 00500 { 00501 DrawXorRect(drClip, pSpread, m_drLastDragBox); 00502 } 00503 00504 00505 00506 /******************************************************************************************** 00507 > void OpDragBox::DrawXorRect(const DocRect& drClip, Spread* pspdXor, 00508 const DocRect& drXor) const 00509 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00510 Created: 22/4/95 00511 Inputs: drClip the clipping rectangle to draw against 00512 pspdXor pointer to the spread to draw the xor rect onto 00513 drXor the position of the xor rect within the spread 00514 Purpose: Xors the given rectangle, clipping against the clip rectangle. Works out 00515 how to fill the rectangle according to the DoSolidDragBoxes preference. 00516 SeeAlso: OpDragBox::DragPointerMove; OpDragBox::RenderDragBlobs 00517 ********************************************************************************************/ 00518 00519 void OpDragBox::DrawXorRect(const DocRect& drClip, Spread* pspdXor, const DocRect& drXor) const 00520 { 00521 // Check if we have nothing to do. 00522 if (drXor.IsEmpty()) return; 00523 00524 // Ask the derived class what colour its drag box is. If we are doing solid drags we 00525 // want to use the same colour to fill the box as well, otherwise we fill with no colour. 00526 StockColour scLineColour = GetBoxColour(); 00527 StockColour scFillColour = (m_fDoSolidDragBoxes) ? scLineColour : COLOUR_NONE; 00528 00529 // Xor the rect on all supplied render-regions. 00530 RenderRegion* pRegion = DocView::RenderOnTop(&((DocRect&) drClip), pspdXor, ClippedEOR); 00531 while (pRegion != NULL) 00532 { 00533 // Set the line and fill colours. 00534 pRegion->SetLineColour(scLineColour); 00535 pRegion->SetFillColour(scFillColour); 00536 00537 // Draw the xored drag box and go on to the next render-region. 00538 pRegion->DrawDragRect(&((DocRect&) drXor)); 00539 pRegion = DocView::GetNextOnTop(&((DocRect&) drClip)); 00540 } 00541 } 00542 00543 00544 00545 /******************************************************************************************** 00546 > virtual DocRect OpDragBox::CalcDragBox(const DocCoord& dcStartPos, 00547 const DocCoord& dcMousePos) const 00548 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00549 Created: 23/4/95 00550 Inputs: dcStartPos the start position of the drag 00551 dcMousePos the current position of the mouse 00552 Outputs: - 00553 Returns: The extent of the drag box, as a millipoint DocRect. 00554 Purpose: Calculates the current extent of the drag box. The default implementation 00555 takes the start point as one corner and the mouse point as another corner, 00556 but you could, for example, override this to take the start point as the 00557 centre of the drag box (useful for the zoom tool). 00558 Errors: - 00559 SeeAlso: OpDragBox::DragPointerMove; OpDragBox::DragFinished 00560 ********************************************************************************************/ 00561 00562 DocRect OpDragBox::CalcDragBox(const DocCoord& dcStartPos, const DocCoord& dcMousePos) const 00563 { 00564 return DocRect(Min(dcStartPos.x, dcMousePos.x), 00565 Min(dcStartPos.y, dcMousePos.y), 00566 Max(dcStartPos.x, dcMousePos.x), 00567 Max(dcStartPos.y, dcMousePos.y)); 00568 } 00569 00570 00571 00572 /******************************************************************************************** 00573 > virtual StockColour OpDragBox::GetBoxColour() const 00574 00575 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00576 Created: 22/4/95 00577 Returns: The stock colour of the drag box's line. By default this is 00578 COLOUR_XORSELECT. 00579 Purpose: Allows customisation of the colour of the drag box. 00580 SeeAlso: OpDragBox::DrawXorRect 00581 ********************************************************************************************/ 00582 00583 StockColour OpDragBox::GetBoxColour() const 00584 { 00585 return COLOUR_XORSELECT; 00586 } 00587 00588 00589 00590 /******************************************************************************************** 00591 > virtual BOOL OpDragBox::OnDragStarted(Spread* pStartSpread, 00592 const DocCoord& dcStartPos, 00593 ClickModifiers cmods) 00594 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00595 Created: 22/4/95 00596 Inputs: pStartSpread the spread where the drag was started 00597 dcStartPos the point within the spread where the drag was started 00598 cmods the state of the mouse click modifiers 00599 Returns: FALSE to cancel the drag, TRUE to continue. 00600 Purpose: By default does nothing. This function can be overriden to so something 00601 useful (eg. set the status bar text). Note that this function will NOT be 00602 called if Operation::StartDrag fails. If you return FALSE then the DoDrag() 00603 call will also return FALSE (generally notifying the op runner that the 00604 drag failed). 00605 SeeAlso: OpDragBox::DoDrag 00606 ********************************************************************************************/ 00607 00608 BOOL OpDragBox::OnDragStarted(Spread*, const DocCoord&, ClickModifiers) 00609 { 00610 return TRUE; 00611 } 00612 00613 00614 00615 /******************************************************************************************** 00616 > virtual BOOL OpDragBox::OnPointerMoved(Spread* pBoxSpread, 00617 const DocRect& drDragBox, 00618 ClickModifiers cmods) 00619 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00620 Created: 22/4/95 00621 Inputs: pBoxSpread the spread where the drag was started 00622 drDragBox the rectangle within the spread defining the drag box 00623 cmods the state of the mouse click modifiers 00624 Returns: FALSE to cancel the drag, TRUE to continue. 00625 Purpose: By default does nothing. This function can be overriden to so something 00626 useful (eg. set the status bar text). Note that if you return FALSE from 00627 this function EndDrag() and End() will be called. 00628 SeeAlso: OpDragBox::DragPointerMove 00629 ********************************************************************************************/ 00630 00631 BOOL OpDragBox::OnPointerMoved(Spread*, const DocRect&, ClickModifiers) 00632 { 00633 return TRUE; 00634 } 00635 00636 00637 00638 /******************************************************************************************** 00639 > virtual BOOL OpDragBox::OnPointerIdle(Spread* pBoxSpread, 00640 const DocRect& drDragBox, 00641 ClickModifiers cmods) 00642 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00643 Created: 22/4/95 00644 Inputs: pBoxSpread the spread where the drag was started 00645 drDragBox the rectangle within the spread defining the drag box 00646 cmods the state of the mouse click modifiers 00647 Returns: FALSE to cancel the drag, TRUE to continue. 00648 Purpose: By default does nothing. This function can be overriden to so something 00649 useful (eg. set the status bar text). Note that if you return FALSE from 00650 this function EndDrag() and End() will be called. 00651 SeeAlso: OpDragBox::DragPointerIdle 00652 ********************************************************************************************/ 00653 00654 BOOL OpDragBox::OnPointerIdle(Spread*, const DocRect&, ClickModifiers) 00655 { 00656 return TRUE; 00657 } 00658 00659 00660 00661 /******************************************************************************************** 00662 > virtual BOOL OpDragBox::OnDragEnded(Spread* pBoxSpread, 00663 const DocRect& drDragBox, 00664 ClickModifiers cmods, 00665 BOOL fDragOK); 00666 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00667 Created: 22/4/95 00668 Inputs: pBoxSpread the spread where the drag was started 00669 drDragBox the rectangle within the spread defining the drag box 00670 cmods the state of the mouse click modifiers 00671 fDragOK the drag has not failed or been cancelled, its a good 'un 00672 Returns: FALSE to cancel the op, TRUE for success. Note that FailAndExecute() will 00673 be called for this operation if you return FALSE from this function. If your 00674 operation requires different failure handling (or no failure handling at all) 00675 then you should perform the handling yourself and return TRUE. 00676 Purpose: You should override this function to do something useful (eg. set the status 00677 bar text, perform a selection operation). It would be nice to make this 00678 a pure virtual function, as it doesn't make any sense not to override this 00679 function - a drag op should do something as a result of a mouse drag, but 00680 unfortunately the MFC/CC run-time dynamic creation won't allow it. 00681 SeeAlso: OpDragBox::DragFinished 00682 ********************************************************************************************/ 00683 00684 BOOL OpDragBox::OnDragEnded(Spread*, const DocRect&, ClickModifiers, BOOL) 00685 { 00686 return TRUE; 00687 } 00688 00689 00690 00691 /******************************************************************************************** 00692 > OpCentredDragBox::OpCentredDragBox() 00693 00694 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00695 Created: 23/4/95 00696 Purpose: Default constructor for a centred drag-box operation. 00697 SeeAlso: class OpDragBox 00698 ********************************************************************************************/ 00699 00700 OpCentredDragBox::OpCentredDragBox() 00701 { 00702 // Empty. 00703 } 00704 00705 00706 00707 /******************************************************************************************** 00708 > virtual DocRect OpCentredDragBox::CalcDragBox(const DocCoord& dcStartPos, 00709 const DocCoord& dcMousePos) const 00710 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00711 Created: 23/4/95 00712 Inputs: dcStartPos the position where the drag was started 00713 dcMousePos the current position of the mouse 00714 Returns: A document (spread) rectangle the is the current bounds of the drag box. 00715 Purpose: Overrides the default OpDragBox method to allow the drag box to be drawn 00716 from the centre (start of drag) to the corner (current mouse position). 00717 SeeAlso: OpDragBox::CalcDragBox 00718 ********************************************************************************************/ 00719 00720 DocRect OpCentredDragBox::CalcDragBox(const DocCoord& dcStartPos, 00721 const DocCoord& dcMousePos) const 00722 { 00723 // Find the half of the absolute width and height of the drag box. 00724 MILLIPOINT nWidth2 = dcStartPos.x - dcMousePos.x; 00725 if (nWidth2 < 0) nWidth2 = -nWidth2; 00726 MILLIPOINT nHeight2 = dcStartPos.y - dcMousePos.y; 00727 if (nHeight2 < 0) nHeight2 = -nHeight2; 00728 00729 // Return a rectangle of this width and height centre on the click point. 00730 return DocRect(dcStartPos.x - nWidth2, dcStartPos.y - nHeight2, 00731 dcStartPos.x + nWidth2, dcStartPos.y + nHeight2); 00732 }