oprotate.cpp

Go to the documentation of this file.
00001 // $Id: oprotate.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 // The Rotate transform Operation
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 #include "oprotate.h"
00105 
00106 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 //#include "trans2d.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00110 //#include "rik.h"
00111 #include "selector.h"
00112 //#include "clikdrag.h"
00113 
00114 
00115 DECLARE_SOURCE("$Revision: 1282 $");
00116 
00117 // An implement to match the Declare in the .h file.
00118 CC_IMPLEMENT_DYNCREATE(OpRotateTrans, TransOperation)
00119 
00120 // This will get Camelot to display the filename and linenumber of any memory allocations
00121 // that are not released at program exit
00122 #define new CAM_DEBUG_NEW
00123 
00124 
00125 
00126 
00127 /********************************************************************************************
00128 
00129 >   OpRotateTrans::OpRotateTrans()
00130 
00131     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00132     Created:    20/7/93
00133     Purpose:    Constructor. Does nothing.
00134 
00135 ********************************************************************************************/
00136 
00137 OpRotateTrans::OpRotateTrans(): TransOperation()
00138 {
00139     // Set status help text
00140     StatusHelpID = _R(IDS_ROTATETRANS_STATUS1);
00141     StatusHelpID2 = _R(IDS_ROTATETRANS_STATUS2);
00142     CanScaleLines = FALSE;
00143 }
00144 
00145 
00146 
00147 
00148 
00149 /********************************************************************************************
00150 
00151 >   void OpRotateTrans::InitTransformImmediate(OpParam* pOpParam)
00152 
00153     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00154     Created:    27/7/94
00155     Inputs:     pOpParam - The parameters that were passed into the operation
00156     Purpose:    Sets up the transform ready for an immediate rotation. This is called from
00157                 DoWithParam()
00158     SeeAlso:    TransOperation::DoWithParam()
00159 
00160 ********************************************************************************************/
00161 
00162 void OpRotateTrans::InitTransformImmediate(OpParam* pOpParam)
00163 {
00164     // Do a rotation right now
00165     StartAngle = (ANGLE)0;
00166     
00167     // Rotate by the number of degrees pointed to by Param2
00168     CurrentAngle = * ((ANGLE*)( PVOID(pOpParam->Param2) ) );
00169     IsConstrained = FALSE;
00170 }
00171 
00172 
00173 
00174 
00175 /********************************************************************************************
00176 
00177 >   ANGLE OpRotateTrans::AngleFromCoord(DocCoord Pos)
00178 
00179     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00180     Created:    20/01/94
00181     Inputs:     Pos - The coord to find the angle to
00182     Returns:    the angle to the coord
00183     Scope:      Private
00184     Purpose:    Finds the angle from the centre of rotation that the coord is
00185 
00186 ********************************************************************************************/
00187 
00188 ANGLE OpRotateTrans::AngleFromCoord(DocCoord Pos)
00189 {
00190     // find the difference between the centre of rotation and the point
00191     INT32 dx = Pos.x - CentreOfTrans.x;
00192     INT32 dy = Pos.y - CentreOfTrans.y;
00193 
00194     if ((dx==0) && (dy==0))
00195     {
00196         // Oh no, the mouse is directly over the centre of rotation
00197         return StartAngle;
00198     }
00199 
00200     // go find the angle to the cursor position from the centre of rotation
00201     double Angle = atan2((double)dy, (double)dx);
00202 
00203     // convert it to degrees and return it
00204     Angle = (Angle/(2*PI)) * 360.0;
00205 
00206     return (ANGLE)(Angle);
00207 }
00208 
00209 
00210 
00211 /********************************************************************************************
00212 
00213 >   virtual BOOL OpRotateTrans::ShouldPointerBeOffset()
00214 
00215     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00216     Created:    13/9/94
00217     Returns:    FALSE
00218     Purpose:    Tells the base class of the operation that we want our mouse coords to be
00219                 left alone
00220 
00221 ********************************************************************************************/
00222 
00223 BOOL OpRotateTrans::ShouldPointerBeOffset()
00224 {
00225     return FALSE;
00226 }
00227 
00228 
00229 /********************************************************************************************
00230 
00231 >   virtual void OpRotateTrans::InitTransformOnDrag(DocCoord PointerPos, ClickModifiers ClickMods)
00232 
00233     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00234     Created:    19/7/94
00235     Inputs:     PointerPos - The position of the mouse at the start of the drag
00236                 ClickMods - the keyboard modifiers that were active at the start of the drag
00237     Purpose:    Sets up the parameters needed to build the transform matrix at the start
00238                 of the drag. This base class version of this function does nothing.
00239 
00240 ********************************************************************************************/
00241 
00242 void OpRotateTrans::InitTransformOnDrag(DocCoord PointerPos, ClickModifiers ClickMods)
00243 {
00244     // Make sure that the angle is correctly set taking into account that the
00245     // start position may be in the same place as the Centre of Rotation (or along
00246     // one of its axis
00247     StartAngle = AngleFromCoord(PointerPos);
00248 
00249     // Work out the constrained start angle as well (just in case we need it)
00250     DocCoord ConstrainedCoord = PointerPos;
00251     DocView::ConstrainToAngle(CentreOfTrans, &ConstrainedCoord);
00252     ConstrainedStartAngle = AngleFromCoord(ConstrainedCoord);
00253 
00254     // Constrain the mouse position if required (45 degrees until we get a better system)
00255     if (ClickMods.Constrain)
00256     {
00257         CurrentAngle = ConstrainedStartAngle;
00258         IsConstrained = TRUE;
00259     }
00260     else
00261     {   
00262         CurrentAngle = StartAngle;
00263         IsConstrained = FALSE;
00264     }
00265 }
00266 
00267 
00268 
00269 
00270 /********************************************************************************************
00271 
00272 >   virtual void OpRotateTrans::UpdateTransformOnDrag(DocCoord PointerPos, Spread*,
00273                                 ClickModifiers&)
00274 
00275     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00276     Created:    19/7/94
00277     Inputs:     PointerPos - The latest position of the mouse
00278                 Spread - The spread the that mouse is over
00279                 ClickModifiers - The click modifiers that were in place at
00280                 this point on the drag
00281     Purpose:    Does the calculations needed when the mouse moves to keep all the params
00282                 needed to build the rotation matrix up to date.
00283 
00284 ********************************************************************************************/
00285 
00286 void OpRotateTrans::UpdateTransformOnDrag(DocCoord PointerPos, Spread* pClickSpread,
00287                                           ClickModifiers& ClickMods)
00288 {
00289     // Make sure that the cursor does not wrap around at the edge of spreads
00290     if (pClickSpread != StartSpread)
00291         PointerPos = MakeRelativeToSpread(StartSpread, pClickSpread, PointerPos);
00292 
00293     // Calc the new angle, based on the new mouse position
00294     CurrentAngle = AngleFromCoord(PointerPos);
00295 
00296     // See if the constrain key is in use
00297     if (ClickMods.Constrain)
00298     {
00299         IsConstrained = TRUE;
00300         BoundingData.Rotation = CurrentAngle - ConstrainedStartAngle;
00301     }
00302     else
00303     {
00304         BoundingData.Rotation = CurrentAngle - StartAngle;
00305         IsConstrained = FALSE;
00306     }
00307 
00308     BoundingData.RotateChanged = TRUE;
00309     // See also UpdateTransformBoundingData function in this file.
00310 }
00311 
00312 
00313 
00314 /********************************************************************************************
00315 
00316 >   void OpRotateTrans::BuildMatrix()
00317 
00318     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00319     Created:    19/7/94
00320     Purpose:    Builds the transform matrix required to rotate the selection about the
00321                 point CentreOfRot by the required number of degrees
00322 
00323 ********************************************************************************************/
00324 
00325 void OpRotateTrans::BuildMatrix()
00326 {
00327     // Build a matrix to transform the objects at render time by the required offsets
00328     // First off, work out the angle to rotate by
00329     ANGLE  RotateBy;
00330     if (IsConstrained)
00331         RotateBy = CurrentAngle - ConstrainedStartAngle;
00332     else
00333         RotateBy = CurrentAngle - StartAngle;
00334 
00335     // Translate to the origin
00336     Transform = Matrix(-CentreOfTrans.x, -CentreOfTrans.y);
00337 
00338     // Rotate by the angle
00339     Matrix RotateIt(RotateBy);
00340 
00341     // translate back again
00342     Matrix TransFromOrigin(CentreOfTrans.x, CentreOfTrans.y);
00343 
00344     // Combine the 3 of them into a single matrix
00345     Transform *= RotateIt;
00346     Transform *= TransFromOrigin;
00347 }
00348 
00349 
00350 
00351 
00352 
00353 /********************************************************************************************
00354 
00355 >   virtual void OpRotateTrans::ConstrainDrag(DocCoord* PointerPos)
00356 
00357     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00358     Created:    19/7/94
00359     Inputs:     PointerPos - The current position of the mouse that needs to be constrained
00360     Outputs:    PointerPos - The position of the mouse after it has been constrained
00361     Purpose:    Will constrain the mouse position to lie along rays from the centre of
00362                 rotation at the constrain angle apart (45 degrees by default)
00363 
00364 ********************************************************************************************/
00365 
00366 void OpRotateTrans::ConstrainDrag(DocCoord* PointerPos)
00367 {
00368     // Rotate want to use the constrain to angle variation of the constrain system
00369     DocView::ConstrainToAngle(CentreOfTrans, PointerPos);
00370 }
00371 
00372 
00373 /********************************************************************************************
00374 
00375 >   BOOL OpRotateTrans::Declare()
00376 
00377     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00378     Created:    5/7/93
00379     Returns:    TRUE if all went OK, False otherwise
00380     Purpose:    Adds the operation to the list of all known operations
00381 
00382 ********************************************************************************************/
00383 
00384 BOOL OpRotateTrans::Declare()
00385 {
00386     return (RegisterOpDescriptor(
00387                                 0, 
00388                                 _R(IDS_ROTATESPIN),
00389                                 CC_RUNTIME_CLASS(OpRotateTrans),
00390                                 OPTOKEN_ROTATE,
00391                                 TransOperation::GetState)); 
00392 }
00393 
00394 
00395 
00396 /********************************************************************************************
00397 
00398 >   void OpRotateTrans::UpdateTransformBoundingData()
00399 
00400     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00401     Created:    04/9/94
00402     Purpose:    Override the base class version of this fn to ensure that new bounds
00403                 are calculated and placed in the BoundingData structure.
00404 
00405 ********************************************************************************************/
00406 
00407 void OpRotateTrans::UpdateTransformBoundingData()
00408 {
00409 #ifndef STANDALONE
00410     ComputeNewBounds();
00411 
00412     // Tell the tool about the current transform bounding data
00413     pSelTool->DragMove(&BoundingData);
00414 #endif
00415 }
00416 
00417 
00418 
00419 

Generated on Sat Nov 10 03:47:49 2007 for Camelot by  doxygen 1.4.4