opdragbx.cpp

Go to the documentation of this file.
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 }

Generated on Sat Nov 10 03:46:13 2007 for Camelot by  doxygen 1.4.4