00001 // $Id: zoomops.cpp 1771 2007-06-17 20:14:43Z 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 zoomops.cpp 00101 00102 Zoom tool operations. 00103 00104 */ 00105 00106 #include "camtypes.h" 00107 #include "zoomops.h" 00108 #include "zoomtool.h" 00109 00110 //#include "xlong.h" 00111 //#include "wrkcoord.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "wrkrect.h" 00113 //#include "doccoord.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 00115 //#include "app.h" 00116 #include "csrstack.h" 00117 //#include "document.h" 00118 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00120 //#include "progress.h" 00121 #include "selector.h" // for static InflateByBlobBorder function 00122 00123 //#include "ngcore.h" 00124 //#include "ngitem.h" 00125 00126 //#include "zoomres.h" 00127 //#include "justin.h" 00128 //#include "justin3.h" 00129 //#include "mario.h" // for _R(IDE_NOMORE_MEMORY) 00130 #include "bubbleid.h" 00131 00132 #if !defined(EXCLUDE_FROM_RALPH) 00133 #include "rulers.h" 00134 #endif 00135 00136 #ifdef _BATCHING 00137 //#include "sglcart.h" 00138 //#include "camdoc.h" 00139 #endif 00140 00141 #include "brushmsg.h" 00142 //#include "ngscan.h" // For CreateDisplayScan() 00143 00144 00145 // Revision information. 00146 DECLARE_SOURCE("$Revision: 1771 $"); 00147 00148 // Standard preliminaries. 00149 CC_IMPLEMENT_DYNCREATE(OpZoom, OpCentredDragBox) 00150 CC_IMPLEMENT_DYNCREATE(OpZoomIn, OpZoom) 00151 CC_IMPLEMENT_DYNCREATE(OpZoomOut, OpZoom) 00152 CC_IMPLEMENT_DYNCREATE(OpZoomTo100, OpZoom) 00153 CC_IMPLEMENT_DYNCREATE(OpZoomTo200, OpZoom) 00154 CC_IMPLEMENT_DYNCREATE(OpZoomTo300, OpZoom) 00155 CC_IMPLEMENT_DYNCREATE(OpZoomTo400, OpZoom) 00156 00157 #if !defined(EXCLUDE_FROM_RALPH) 00158 CC_IMPLEMENT_DYNCREATE(ZoomInfoBarOp, InformationBarOp) 00159 #endif 00160 00161 #define new CAM_DEBUG_NEW 00162 00163 00164 // This makes the computer go "beep!". 00165 //extern void Beep(); 00166 00167 00169 // class OpZoom 00170 00171 /********************************************************************************************* 00172 Preference: FixZoomClickPoint 00173 Section: Zoom Tool 00174 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00175 Range: FALSE or TRUE 00176 Purpose: When zooming in or out with a mouse click, this determines whether to fix 00177 the clicked point in the resulting zoomed view at the same screen-relative 00178 position, or to centre the zoomed view on the clicked point. By default 00179 this is FALSE (don't fix, do centre). 00180 **********************************************************************************************/ 00181 00182 BOOL OpZoom::m_fFixZoomClickPoint = FALSE; 00183 00184 00185 00186 /************************************************************************************** 00187 Preference: RadialZoomDragBox 00188 Section: Zoom Tool 00189 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00190 Range: FALSE or TRUE 00191 Purpose: Determines how the zoom drag operation invokes by the zoom tool will 00192 draw its drag box. If FALSE (the default) then the tool will draw the 00193 box from one corner to its opposite. This is similar to the selector's 00194 drag box. If TRUE then the tool will draw its centre box centred on 00195 the point where the drag started and extending to the current mouse 00196 position. The effect is to centre the zoom on the first clicked point. 00197 ***************************************************************************************/ 00198 00199 BOOL OpZoom::m_fRadialZoomDragBox = FALSE; 00200 00201 00202 00203 /************************************************************************************** 00204 Preference: ShowZoomInOutCursors 00205 Section: Zoom Tool 00206 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00207 Range: 0 ... 1 00208 Purpose: Determines whether to flash a "zooming-in" or "zooming-out" cursor 00209 when a zoom is being calculated, and a special drag cursor when dragging 00210 in the zoom tool. 00211 00212 Some people think this adds a groovy, polished feel to the program. 00213 Others don't, which is why this preference is 0 by default (ie. no 00214 special zoom cursors). 00215 ***************************************************************************************/ 00216 00217 UINT32 OpZoom::m_nfShowZoomCursors = 0; 00218 00219 00220 // The zoom array holds the 'prefered' scale factors. As we zoom in and out we will 00221 // try and zoom to one of these values first and then step along the table. 00222 INT32 OpZoom::ZoomTable[cZoomTableSize] = 00223 { 00224 25601, // probably the highest zoom factor in the world . . . 00225 16000, 00226 8000, 00227 4000, // these are PERCENTAGES of a view's normal size. 00228 2000, 00229 1000, 00230 500, 00231 200, 00232 100, // the default, 100%, at position cDefaultZoomIndex 00233 75, 00234 50, 00235 25, 00236 10, 00237 }; 00238 00239 00240 00241 /******************************************************************************************** 00242 > OpZoom::OpZoom() 00243 00244 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00245 Created: 23/4/95 00246 Purpose: Default constructor. To run a zoom drag, call the DoDrag() function. 00247 ********************************************************************************************/ 00248 00249 OpZoom::OpZoom() 00250 : m_csrZoomIn((Tool_v1*)NULL, _R(IDCSR_ZOOM_IN)), // we only need these cursors when an OpZoom 00251 m_csrZoomOut((Tool_v1*)NULL, _R(IDCSR_ZOOM_OUT)), 00252 m_csrZoomDrag((Tool_v1*)NULL, _R(IDCSR_ZOOM_DRAG)) // is going to be run 00253 { 00254 // ERROR3IF(!m_csrZoomIn.IsValid() || !m_csrZoomOut.IsValid() || !m_csrZoomDrag.IsValid(), 00255 // "Failed to load cursor(s) in OpZoom::OpZoom"); 00256 } 00257 00258 /******************************************************************************************** 00259 00260 > virtual void OpZoom::Do(OpDescriptor* pZoomOpDesc) 00261 00262 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00263 Created: 20/9/95 00264 Inputs: pointer to the OpZoomDescriptor being invoked 00265 Purpose: Performs the zoom operation 00266 SeeAlso: OpZoomDescriptor::FakeInvoke; 00267 00268 ********************************************************************************************/ 00269 00270 void OpZoom::Do(OpDescriptor *pOpDesc) 00271 { 00272 // Do what FakeInvoke does but call the DoZoom function instead of HandleButtonMsg for 00273 // the zoom descriptor. 00274 OpZoomDescriptor* pZoomOpDesc = (OpZoomDescriptor*) pOpDesc; 00275 if (pZoomOpDesc != 0 && pZoomOpDesc->IsAvailable()) 00276 { 00277 // DoZoom function must End the operation. 00278 pZoomOpDesc->DoZoom(this); 00279 } 00280 } 00281 00282 00283 /******************************************************************************************** 00284 > static void OpZoom::SpreadToWork(Spread* pspdIn, const DocCoord& dcIn, 00285 WorkCoord* pwcOut) 00286 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00287 Created: 24/4/95 00288 Inputs: pspdIn the spread containing the document coordinate 00289 dcIn the position within the spread 00290 Outputs: pwcOut the equivalent work coordinate in the current view 00291 Returns: - 00292 Purpose: Converts a document spread coordinate into a work coordinate in the 00293 current view. 00294 SeeAlso: OpZoom::WorkToSpread 00295 ********************************************************************************************/ 00296 00297 void OpZoom::SpreadToWork(Spread* pspdIn, const DocCoord& dcIn, WorkCoord* pwcOut) 00298 { 00299 // Caller must provide a location to store the converted coordinate. 00300 ERROR3IF(pwcOut == 0, "No output in OpZoom::SpreadToWork"); 00301 00302 // Find the current DocView. 00303 DocView* pDocView = DocView::GetCurrent(); 00304 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::SpreadToWork"); 00305 00306 // Convert. 00307 if (pDocView && pwcOut) 00308 *pwcOut = ((DocCoord&) dcIn).ToWork(pspdIn, pDocView); 00309 } 00310 00311 00312 00313 /******************************************************************************************** 00314 > static void OpZoom::SpreadToWork(Spread* pspdIn, const DocRect& drIn, 00315 WorkRect* pwrOut) 00316 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00317 Created: 24/4/95 00318 Inputs: pspdIn the spread containing the document rectangle 00319 dcIn the rectangle within the spread 00320 Outputs: pwcOut the equivalent work rectangle in the current view 00321 Returns: - 00322 Purpose: Converts a document spread rectangle into a work rectangle in the 00323 current view. 00324 SeeAlso: OpZoom::WorkToSpread 00325 ********************************************************************************************/ 00326 00327 void OpZoom::SpreadToWork(Spread* pspdIn, const DocRect& drIn, WorkRect* pwrOut) 00328 { 00329 // Convert low and high corners of the rectangle. 00330 SpreadToWork(pspdIn, drIn.lo, &pwrOut->lo); 00331 SpreadToWork(pspdIn, drIn.hi, &pwrOut->hi); 00332 } 00333 00334 00335 00336 /******************************************************************************************** 00337 > static INT32 OpZoom::GetPresetZoomPercent(INT32 nPreset) 00338 00339 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00340 Created: 24/4/95 00341 Inputs: nPreset which preset zoom factor, with 0 the highest and 00342 cZoomTableSize-1 the lowest. 00343 Returns: A standard preset zoom factor, as a percentage. 00344 Purpose: 00345 ********************************************************************************************/ 00346 00347 INT32 OpZoom::GetPresetZoomPercent(INT32 nPreset) 00348 { 00349 ERROR3IF(nPreset < 0 || nPreset >= cZoomTableSize, 00350 "Bad preset in OpZoom::GetPresetZoomPercent"); 00351 return ZoomTable[nPreset]; 00352 } 00353 00354 00355 00356 /******************************************************************************************** 00357 > static FIXED16 OpZoom::GetPresetZoomScale(INT32 nPreset) 00358 00359 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00360 Created: 24/4/95 00361 Inputs: nPreset which preset zoom factor, with 0 the highest and 00362 cZoomTableSize-1 the lowest. 00363 Returns: A standard preset zoom factor, as a scale factor. 00364 Purpose: 00365 ********************************************************************************************/ 00366 00367 FIXED16 OpZoom::GetPresetZoomScale(INT32 nPreset) 00368 { 00369 ERROR3IF(nPreset < 0 || nPreset >= cZoomTableSize, 00370 "Bad preset in OpZoom::GetPresetZoomScale"); 00371 return ((FIXED16) ZoomTable[nPreset]) / 100; 00372 } 00373 00374 00375 00376 /******************************************************************************************** 00377 > BOOL OpZoom::DoDrag(Spread* pStartSpread, 00378 const DocCoord& dcStartPos, 00379 ClickModifiers cmods) 00380 00381 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00382 Created: 23/4/95 00383 Inputs: pStartSpread the spread containing the initial mouse postion 00384 dcStartPos the initial mosue position, ie, where the drag started 00385 cmods the state of the mouse modifier keys 00386 Purpose: Starts an auto-scroll drag operation at the given mouse position. Note that 00387 this function hides the base-class DoDrag() function. 00388 SeeAlso: OpDragBox::DoDrag 00389 ********************************************************************************************/ 00390 00391 BOOL OpZoom::DoDrag(Spread* pStartSpread, const DocCoord& dcStartPos, ClickModifiers cmods) 00392 { 00393 return OpDragBox::DoDrag(DRAGTYPE_AUTOSCROLL, pStartSpread, dcStartPos, cmods); 00394 } 00395 00396 00397 00398 /******************************************************************************************** 00399 > BOOL OpZoom::OnDragStarted(Spread*, const Doccoord&, ClickModifiers) 00400 00401 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00402 Created: 23/4/95 00403 Inputs: (not used) 00404 Returns: TRUE (always) 00405 Purpose: Called by OpZoom's base class, OpDragBox, when a drag has been started. 00406 Sets the status line text to a helpful comment. 00407 ********************************************************************************************/ 00408 00409 BOOL OpZoom::OnDragStarted(Spread*, const DocCoord&, ClickModifiers) 00410 { 00411 // Remember where the drag started. We have to "bodge" this as it is apparently too 00412 // difficult to translate document coordinates to work coordinates during a drag, so 00413 // we can't use the mouse position info passed to us by the OpDragBox base-class. 00414 DocView* pDocView = DocView::GetCurrent(); 00415 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::OnDragStarted"); 00416 m_wcStartPos = pDocView->GetClickWorkCoord(); 00417 00418 // Reset this flag. 00419 m_fStatusTextShown = FALSE; 00420 00421 // Possibly set the zoom-cursor, saving the old one, and return success. 00422 if (m_nfShowZoomCursors) m_ncsrSaveDrag = CursorStack::GPush(&m_csrZoomDrag); 00423 return TRUE; 00424 } 00425 00426 00427 00428 /******************************************************************************************** 00429 > BOOL OpZoom::OnPointerMoved(Spread*, const DocRect&, ClickModifiers) 00430 00431 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00432 Created: 24/6/95 00433 Inputs: (not used) 00434 Returns: TRUE, meaning continue dragging. 00435 Purpose: If this function is called then a drag has definitely started, so update 00436 the status bar. We don't do this on a button-down event. 00437 ********************************************************************************************/ 00438 00439 BOOL OpZoom::OnPointerMoved(Spread*, const DocRect&, ClickModifiers) 00440 { 00441 #if !defined(EXCLUDE_FROM_RALPH) 00442 // The first time through this function set the status-line text. We don't really 00443 // want to do this on a button-down event as not all such events lead to drags. 00444 if (!m_fStatusTextShown) 00445 { 00446 // Set the status line text. If we manage to do it then don't bother doing it 00447 // again until another drag really begins. 00448 String_256 str(_R(IDS_ZOOMOP_STATUSHELP)); 00449 m_fStatusTextShown = GetApplication()->UpdateStatusBarText(&str); 00450 } 00451 #endif 00452 00453 // All fine, continue dragging. 00454 return TRUE; 00455 } 00456 00457 00458 00459 /******************************************************************************************** 00460 > BOOL OpZoom::OnDragEnded(Spread* pBoxSpread, 00461 const DocRect& drDragBox, 00462 ClickModifiers cmods, 00463 BOOL fDragOK) 00464 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00465 Created: 23/4/95 00466 Inputs: pBoxSpread the spread where the drag was started 00467 drDragBox the last extent of the drag box drawn by the user 00468 cmods the state of the mouse click modifiers (not used) 00469 fDragOK the FALSE the drag failed or was cancelled 00470 Returns: TRUE (always) 00471 Purpose: Called when the drag is successfully finished. We check to see if the 00472 mouse actually moved noticably during the drag. If it did not, then a 00473 simple click operation is performed. If it did though, the area of the 00474 drag box will be zoomed in on. 00475 ********************************************************************************************/ 00476 00477 BOOL OpZoom::OnDragEnded(Spread*, const DocRect&, ClickModifiers, BOOL fDragOK) 00478 { 00479 // Pop the cursor we possibly pushed in OnStartDrag. 00480 if (m_nfShowZoomCursors) CursorStack::GPop(m_ncsrSaveDrag); 00481 00482 // If the drag didn't happen we do nothing. We don't want FailAndExecute() called 00483 // though, so return TRUE. 00484 if (!fDragOK) return TRUE; 00485 00486 // This could take a while . . . 00487 // BeginSlowJob(); 00488 00489 // Get the current view. 00490 DocView* pDocView = DocView::GetCurrent(); 00491 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::OnDragEnded"); 00492 00493 // Find the half of the absolute width and height of the drag box. 00494 WorkCoord wcLast = pDocView->GetClickWorkCoord(); 00495 WorkRect wrZoom; 00496 00497 if (m_fRadialZoomDragBox) 00498 { 00499 XLONG nWidth2 = m_wcStartPos.x - wcLast.x; 00500 if (nWidth2 < 0) nWidth2 = -nWidth2; 00501 XLONG nHeight2 = m_wcStartPos.y - wcLast.y; 00502 if (nHeight2 < 0) nHeight2 = -nHeight2; 00503 00504 // Make a rectangle of this width and height, centred on the click point. 00505 wrZoom = WorkRect(m_wcStartPos.x - nWidth2, m_wcStartPos.y - nHeight2, 00506 m_wcStartPos.x + nWidth2, m_wcStartPos.y + nHeight2); 00507 } 00508 else 00509 { 00510 #undef MIN 00511 #undef MAX 00512 #define MIN(a,b) (((a)<(b))?(a):(b)) 00513 #define MAX(a,b) (((a)>(b))?(a):(b)) 00514 00515 wrZoom = WorkRect(MIN(m_wcStartPos.x, wcLast.x), 00516 MIN(m_wcStartPos.y, wcLast.y), 00517 MAX(m_wcStartPos.x, wcLast.x), 00518 MAX(m_wcStartPos.y, wcLast.y)); 00519 } 00520 00521 // We must first check if we have a significant drag box. If the size of the box 00522 // is less than the Camelot "click radius" we will ignore the drag and treat the 00523 // operation as a single-click "zoom in" action by the user. 00524 00525 // Graeme (11/11/99): The comparison is now done against a constant value 00526 // (ZOOM_MIN_DRAG), which is defined in zoomops.h. dDragDistance gives an absolute 00527 // value, rather than testing against separate x and y values. 00528 00529 // Zoom in bug fixed by Chris Snook/Graeme (14/12/99) .... 00530 00531 double dDragDistance = sqrt ( ( (double) wrZoom.Width () * (double) wrZoom.Width () ) + 00532 ( (double) wrZoom.Height () * (double) wrZoom.Height () ) ); 00533 00534 if ( dDragDistance < ZOOM_MIN_DRAG || wrZoom.Width() <= 0 || wrZoom.Height() <= 0 ) 00535 { 00536 // Drag is insignificant so zoom in instead. 00537 ZoomIn(m_wcStartPos, FALSE); // OpDragBox will end this op 00538 } 00539 else 00540 { 00541 // Do a proper mouse-drag zoom. 00542 ZoomInOnRect(wrZoom, FALSE); // OpDragBox will end this op 00543 } 00544 00545 // tell people things have changed on screen 00546 TRACEUSER( "Diccon", _T("OnDragEnded\n")); 00547 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 00548 00549 // Remove the hour-glass and return the success code. 00550 // EndSlowJob(); 00551 return TRUE; 00552 } 00553 00554 00555 00556 /******************************************************************************************** 00557 > DocRect OpZoom::CalcDragBox(const DocCoord& dcStartPos, const DocCoord& dcMousePos) const 00558 00559 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00560 Created: 23/4/95 00561 Inputs: dcStartPos the position where the drag was started 00562 dcMousePos the current position of the mouse 00563 Returns: A document (spread) rectangle the is the current bounds of the drag box. 00564 Purpose: Overrides the default OpDragBox method to allow the drag box to be drawn 00565 from the centre (start of drag) to the corner (current mouse position), if 00566 the 'ZoomDragOnCentre' preference allows. If it doesn't the default method 00567 is called instead. 00568 SeeAlso: OpDragBox::CalcDragBox 00569 ********************************************************************************************/ 00570 00571 DocRect OpZoom::CalcDragBox(const DocCoord& dcStartPos, const DocCoord& dcMousePos) const 00572 { 00573 // Do what the preferences say. 00574 return (m_fRadialZoomDragBox) ? OpCentredDragBox::CalcDragBox(dcStartPos, dcMousePos) 00575 : OpDragBox::CalcDragBox(dcStartPos, dcMousePos); 00576 } 00577 00578 00579 00580 /******************************************************************************************** 00581 > void OpZoom::ZoomOut(const WorkCoord& wcZoom, BOOL fEndOp = TRUE) 00582 00583 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00584 Created: 23/4/95 00585 Inputs: wcZoom the point to zoom out at 00586 fEndOp whether to end this operation after this zoom 00587 Purpose: Zooms out of the current DocView by one step. By default this function 00588 will call the End() function for this operation afterwards. 00589 ********************************************************************************************/ 00590 00591 void OpZoom::ZoomOut(const WorkCoord& wcZoom, BOOL fEndOp) 00592 { 00593 // Find out the current view. 00594 DocView* pDocView = DocView::GetCurrent(); 00595 ERROR3IF(pDocView == 0, "No selected DocView in OpZoom::ZoomOut"); 00596 00597 if (pDocView) 00598 { 00599 // Get the current view's scaling factor as a rounded precentage. 00600 INT32 nOldScalePercent = ((pDocView->GetViewScale() * 100) + FIXED16_DBL(0.5)).MakeInt(); 00601 00602 // Search forwards through the zoom table until we find a lower zoom factor, or 00603 // until we hit the end of the table, meaning no lower zoom factor exists. 00604 for (INT32 i = 0; i < cZoomTableSize; i++) 00605 { 00606 // Found a lower zoom? If so, set it, remember it's position in the zoom table 00607 // and return. 00608 if (nOldScalePercent > GetPresetZoomPercent(i)) 00609 { 00610 // Do the zoom. We will (optionally) end the operation. 00611 pDocView->SetZoomTableIndex(i); 00612 ZoomAtPoint(wcZoom, GetPresetZoomScale(i), FALSE); 00613 break; 00614 } 00615 } 00616 } 00617 00618 // We must correctly end the operation. 00619 if (fEndOp) End(); 00620 00621 // tell people things have changed on screen 00622 TRACEUSER( "Diccon", _T("ZoomOut\n")); 00623 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 00624 } 00625 00626 00627 00628 /******************************************************************************************** 00629 > void OpZoom::ZoomOut(Spread* pZoomSpread, const DocCoord& dcZoomPos, BOOL fEndOp = TRUE) 00630 00631 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00632 Created: 23/4/95 00633 Inputs: pZoomSpread the spread containing the point to zoom out at 00634 dcZoomPos the point to zoom out at 00635 fEndOp whether to end this operation after this zoom 00636 Purpose: Zooms out of the current DocView by one step. By default this function 00637 will call the End() function for this operation afterwards. 00638 ********************************************************************************************/ 00639 00640 void OpZoom::ZoomOut(Spread* pZoomSpread, const DocCoord& dcZoomPos, BOOL fEndOp) 00641 { 00642 WorkCoord wcZoom; 00643 SpreadToWork(pZoomSpread, dcZoomPos, &wcZoom); 00644 ZoomOut(wcZoom, fEndOp); 00645 } 00646 00647 00648 /******************************************************************************************** 00649 > void OpZoom::ZoomTo(const WorkCoord& wcZoom, INT32 nPercent, BOOL fEndOp = TRUE) 00650 00651 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00652 Created: 23/4/95 00653 Inputs: wcZoom the point to zoom in at 00654 fEndOp whether to end this operation after this zoom 00655 Purpose: Zooms into the current DocView by one step. By default this function 00656 will call the End() function for this operation afterwards. 00657 ********************************************************************************************/ 00658 00659 void OpZoom::ZoomTo(const WorkCoord& wcZoom, INT32 nPercent, BOOL fEndOp) 00660 { 00661 // Find out the current view. 00662 DocView* pDocView = DocView::GetCurrent(); 00663 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::ZoomIn"); 00664 00665 if (pDocView) 00666 { 00667 // Do the zoom. We will (optionally) end the operation. 00668 FIXED16 f16Scale = FIXED16(nPercent) / 100; 00669 ZoomAtPoint(wcZoom, f16Scale, FALSE); 00670 } 00671 00672 // End the operation if the caller wants us to. 00673 if (fEndOp) End(); 00674 } 00675 00676 00677 /******************************************************************************************** 00678 > void OpZoom::ZoomIn(const WorkCoord& wcZoom, BOOL fEndOp = TRUE) 00679 00680 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00681 Created: 23/4/95 00682 Inputs: wcZoom the point to zoom in at 00683 fEndOp whether to end this operation after this zoom 00684 Purpose: Zooms into the current DocView by one step. By default this function 00685 will call the End() function for this operation afterwards. 00686 ********************************************************************************************/ 00687 00688 void OpZoom::ZoomIn(const WorkCoord& wcZoom, BOOL fEndOp) 00689 { 00690 // Find out the current view. 00691 DocView* pDocView = DocView::GetCurrent(); 00692 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::ZoomIn"); 00693 00694 if (pDocView) 00695 { 00696 // Find the current view's scaling factor. By converting this to a percentage 00697 // and rounding we improve the accuracy of the comparison below. 00698 INT32 nOldScalePercent = ((pDocView->GetViewScale() * 100) + FIXED16_DBL(0.5)).MakeInt(); 00699 00700 // Search backwards until we find a higher zoom, or the end of the table (meaning that 00701 // there is no higher zoom). 00702 for (INT32 i = cZoomTableSize - 1; i >= 0; i--) 00703 { 00704 // Found a higher zoom? If so, set it, remember it's position and return. 00705 if (nOldScalePercent < GetPresetZoomPercent(i)) 00706 { 00707 // Do the zoom. We will (optionally) end the operation. 00708 pDocView->SetZoomTableIndex(i); 00709 ZoomAtPoint(wcZoom, GetPresetZoomScale(i), FALSE); 00710 break; 00711 } 00712 } 00713 } 00714 00715 // End the operation if the caller wants us to. 00716 if (fEndOp) End(); 00717 } 00718 00719 00720 00721 /******************************************************************************************** 00722 > void OpZoom::ZoomIn(Spread* pZoomSpread, const DocCoord& dcZoomPos, BOOL fEndOp = TRUE) 00723 00724 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00725 Created: 23/4/95 00726 Inputs: pZoomSpread the spread containing the point to zoom in at 00727 dcZoomPos the point to zoom in at 00728 fEndOp whether to end this operation after this zoom 00729 Purpose: Zooms in on the current DocView by one step. By default this function 00730 will call the End() function for this operation afterwards. 00731 ********************************************************************************************/ 00732 00733 void OpZoom::ZoomIn(Spread* pZoomSpread, const DocCoord& dcZoomPos, BOOL fEndOp) 00734 { 00735 WorkCoord wcZoom; 00736 SpreadToWork(pZoomSpread, dcZoomPos, &wcZoom); 00737 ZoomIn(wcZoom, fEndOp); 00738 } 00739 00740 00741 00742 /******************************************************************************************** 00743 > void OpZoom::ZoomInOnRect(const WorkRect& wrZoom, BOOL fEndOp = TRUE) 00744 00745 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00746 Created: 23/4/95 00747 Inputs: wrZoom the rectangle to zoom in on. 00748 fEndOp whether to end this operation after this zoom 00749 Purpose: Zooms so that the given work rectangle completely fills the current 00750 DocView view extents. By default this function will call the End() 00751 function for this operation afterwards. 00752 ********************************************************************************************/ 00753 00754 void OpZoom::ZoomInOnRect(const WorkRect& wrZoom, BOOL fEndOp) 00755 { 00756 // Make sure the zoom rectangle isn't empty, or we'll divide by zero later on. 00757 if (wrZoom.IsEmpty()) 00758 { 00759 ERROR3("Empty zoom rectangle passed to OpZoom::ZoomInOnRect"); 00760 return; 00761 } 00762 00763 // Find out the current view and save its scale factor and scroll offsets. 00764 DocView* pDocView = DocView::GetCurrent(); 00765 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::ZoomInOnRect"); 00766 // Get out now if view 0 otherwise we will access violate later on 00767 if (pDocView == 0) 00768 return; 00769 00770 OpZoomPrevZoomDescriptor::SaveZoom(pDocView); 00771 00772 // Find out the size of the window and the given zoom rectangle in work coordinates. 00773 WorkRect wrView = pDocView->GetViewRect(); 00774 00775 // Get the current scale factor. 00776 double fpOldScaleFactor = pDocView->GetViewScale().MakeDouble(); 00777 00778 // Find out the ratios of the width and height (zoom rect to view rect). We know 00779 // that the divisors are not zero, or we would not have entered this function. 00780 double fpWidthFactor = (double)wrView.Width ()/wrZoom.Width (); 00781 double fpHeightFactor = (double)wrView.Height()/wrZoom.Height(); 00782 double fpMinFactor = (fpWidthFactor < fpHeightFactor) ? fpWidthFactor : fpHeightFactor; 00783 00784 // The new zoom factor is proportional to the above 00785 double fpNewScaleFactor = fpOldScaleFactor * fpMinFactor; 00786 00787 // Push the zoom-in or zoom-out cursor, depending on whether we are zooming in or 00788 // out and the state of the preference. 00789 INT32 ncsrOldID=0; 00790 if (ZoomTool::IsSelectedTool() && m_nfShowZoomCursors) 00791 { 00792 ncsrOldID = CursorStack::GPush((fpNewScaleFactor > fpOldScaleFactor) 00793 ? &m_csrZoomIn 00794 : &m_csrZoomOut); 00795 } 00796 00797 // Convert the new scale factor to a percentage and check that it's in bounds. If it 00798 // isn't adjust it to the lowest/highest zoom factors. 00799 INT32 nZoomPercent = (INT32) (fpNewScaleFactor * 100); 00800 if (nZoomPercent < GetPresetZoomPercent(cZoomTableSize - 1)) 00801 { 00802 fpNewScaleFactor = GetPresetZoomScale(cZoomTableSize - 1).MakeDouble(); 00803 } 00804 else if (nZoomPercent > GetPresetZoomPercent(0)) 00805 { 00806 fpNewScaleFactor = GetPresetZoomScale(0).MakeDouble(); 00807 } 00808 00809 // Set the scroll offsets to the middle of the box. 00810 WorkCoord wcScrollOffset; 00811 wcScrollOffset.x = (wrZoom.lo.x + wrZoom.hi.x) / 2; 00812 wcScrollOffset.y = (wrZoom.lo.y + wrZoom.hi.y) / 2; 00813 00814 // Scale the value to the correct number of pixels. 00815 double fpRatio = fpNewScaleFactor / fpOldScaleFactor; 00816 wcScrollOffset.x = XLONG(wcScrollOffset.x*fpRatio); 00817 wcScrollOffset.y = XLONG(wcScrollOffset.y*fpRatio); 00818 00819 // Offset it by half the size of the window. WHY? AND WHY THE MakeLong() CALL? 00820 wcScrollOffset.x = wcScrollOffset.x - (wrView.Width() / 2); 00821 wcScrollOffset.y += wrView.Height() / 2; 00822 00823 // Check the scroll offsets bounds as we can't have scroll offsets anywhere. 00824 if (wcScrollOffset.x < 0) wcScrollOffset.x = 0; 00825 if (wcScrollOffset.y > 0) wcScrollOffset.y = 0; 00826 00827 // Set the scale. This must be done before the scroll offset is set or 00828 // strangeness will follow . . . 00829 pDocView->SetViewScale((FIXED16) fpNewScaleFactor); 00830 pDocView->SetScrollOffsets(wcScrollOffset, FALSE); 00831 00832 // Update the combo-box containing scale factors. 00833 pDocView->SetZoomTableIndex(cFractionalZoomIndex); 00834 #ifndef RALPH 00835 OpZoomComboDescriptor::Update(); 00836 #endif 00837 00838 // We have to force a redraw as the zoom has changed, reset the cursor, and end the 00839 // operation. 00840 pDocView->ForceRedraw(TRUE); 00841 if (ZoomTool::IsSelectedTool() && m_nfShowZoomCursors) CursorStack::GPop(ncsrOldID); 00842 if (fEndOp) End(); 00843 00844 00845 // tell people things have changed on screen 00846 TRACEUSER( "Diccon", _T("ZoomInOnRect\n")); 00847 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 00848 } 00849 00850 00851 00852 /******************************************************************************************** 00853 > void OpZoom::ZoomInOnRect(Spread* pZoomSpread, 00854 const DocRect& drZoomRect, 00855 BOOL fEndOp = TRUE) 00856 00857 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00858 Created: 23/4/95 00859 Inputs: pZoomSpread the spread containing the rectangle to zoom in on 00860 drZoomRect the rectangle to zoom in on. 00861 fEndOp whether to end this operation after this zoom 00862 Purpose: Zooms so that the given spread rectangle completely fills the current 00863 DocView view extents. By default this function will call the End() 00864 function for this operation afterwards. 00865 ********************************************************************************************/ 00866 00867 void OpZoom::ZoomInOnRect(Spread* pZoomSpread, const DocRect& drZoomRect, BOOL fEndOp) 00868 { 00869 // Call the WorkRect version of this function to do the zoom. 00870 WorkRect wrZoom; 00871 SpreadToWork(pZoomSpread, drZoomRect, &wrZoom); 00872 ZoomInOnRect(wrZoom, fEndOp); 00873 } 00874 00875 00876 00877 /******************************************************************************************** 00878 > void OpZoom::ZoomAtPoint(const WorkCoord& wcZoom, FIXED16 fxNewScaleFactor, 00879 BOOL fEndOp = TRUE) 00880 00881 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00882 Created: 23/4/95 00883 Inputs: wcZoom the point within the current view to zoom at, 00884 in work coordinates. 00885 fxNewScaleFactor the required scale factor 00886 fEndOp whether to end this operation after this zoom 00887 Purpose: Sets the current DocView to show the given point at the given scale factor. 00888 By default this function will call the End() function for this operation 00889 afterwards. 00890 ********************************************************************************************/ 00891 /******************************************************************************************** 00892 Technical notes: 00893 What the zoom does. This routine finds out the current scroll offsets and makes 00894 a vector from the clicked point to the top corner of the window (ie the scroll 00895 offsets). It knows the ratio of the old scale factor and the new scale factor 00896 and uses this to calculate a new point from the click point along the vector. 00897 00898 For example, if the ratio of the old and new zooms is one half then the new top 00899 corner of the window will be a point on the vector, half way between the click 00900 point and the old top corner of the window. 00901 00902 Since the document will be changing size and since the scroll offsets are 00903 measured in pixels, these will be changing after the zoom has happened, so we 00904 have to compensate for that as well. All that remains to do after that is check 00905 that the offsets are valid and then set them. 00906 ********************************************************************************************/ 00907 00908 void OpZoom::ZoomAtPoint(const WorkCoord& wcZoom, FIXED16 fxNewScaleFactor, BOOL fEndOp) 00909 { 00910 // Get the current view. 00911 DocView* pDocView = DocView::GetCurrent(); 00912 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::ZoomAtPoint"); 00913 00914 // Save the view's current zoom and find out current scaling factor. 00915 OpZoomPrevZoomDescriptor::SaveZoom(pDocView); 00916 FIXED16 fxOldScaleFactor = pDocView->GetViewScale(); 00917 00918 // Push the zoom-in or zoom-out cursor, depending on whether we are zooming in or 00919 // out. 00920 INT32 ncsrOldID=0; 00921 if (ZoomTool::IsSelectedTool() && m_nfShowZoomCursors) 00922 { 00923 ncsrOldID = CursorStack::GPush((fxNewScaleFactor > fxOldScaleFactor) 00924 ? &m_csrZoomIn 00925 : &m_csrZoomOut); 00926 } 00927 00928 // Find the current view size in 64-bit work coordinates. 00929 WorkRect wrView = pDocView->GetViewRect(); 00930 00931 // Work out the ratio of the new and old scale factors. 00932 double fpLineRatio = fxOldScaleFactor.MakeDouble() / fxNewScaleFactor.MakeDouble(); 00933 00934 // We either centre the clicked point or keep it fixed, depending on the preferences. 00935 // Calculate the new position of the top-left of the view accordingly. 00936 WorkCoord wcNewTopCorner = wcZoom; 00937 if (m_fFixZoomClickPoint) 00938 { 00939 // Find the vector from the click point to the top corner of the window, and 00940 // from this work out the new position of the top-left corner of the view. 00941 wcNewTopCorner.x += XLONG(fpLineRatio * (wrView.lo.x - wcZoom.x)); 00942 wcNewTopCorner.y += XLONG(fpLineRatio * (wrView.hi.y - wcZoom.y)); 00943 } 00944 else 00945 { 00946 // Find the vector from the centre of the view to the top-left corner, scaled by 00947 // the line-ratio. Add this vector to the click point to work out the new position 00948 // of the top-left corner of the view. 00949 wcNewTopCorner.x -= XLONG(fpLineRatio * wrView.Width ()/2); 00950 wcNewTopCorner.y += XLONG(fpLineRatio * wrView.Height()/2); 00951 } 00952 00953 // Scale the value to the correct number of pixels. We convert to doubles as the 00954 // fixed-point numbers can lose precision at high zooms. 00955 double fpPixRatio = fxNewScaleFactor.MakeDouble() / fxOldScaleFactor.MakeDouble(); 00956 wcNewTopCorner.x = XLONG(fpPixRatio * wcNewTopCorner.x); 00957 wcNewTopCorner.y = XLONG(fpPixRatio * wcNewTopCorner.y); 00958 00959 // Set the new scale factor in the view. 00960 pDocView->SetViewScale(fxNewScaleFactor); 00961 00962 // Make sure that the new scroll offset is within workspace bounds and set it. 00963 if (wcNewTopCorner.x < 0) wcNewTopCorner.x = 0; 00964 if (wcNewTopCorner.y > 0) wcNewTopCorner.y = 0; 00965 pDocView->SetScrollOffsets(wcNewTopCorner, FALSE); 00966 00967 #ifndef RALPH 00968 // Update the combo-box containing scale factors. 00969 OpZoomComboDescriptor::Update(); 00970 #endif 00971 00972 // Finally redraw the whole window, reset the cursor, and end the operation. 00973 pDocView->ForceRedraw(TRUE); 00974 if (ZoomTool::IsSelectedTool() && m_nfShowZoomCursors) CursorStack::GPop(ncsrOldID); 00975 if (fEndOp) End(); 00976 00977 // tell people things have changed on screen 00978 TRACEUSER( "Diccon", _T("ZoomAtPoint\n")); 00979 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 00980 } 00981 00982 00983 00984 /******************************************************************************************** 00985 > void OpZoom::ZoomAtPoint(Spread* pZoomSpread, const DocCoord& dcZoomPos, 00986 FIXED16 fxNewScaleFactor, BOOL fEndOp = TRUE) 00987 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00988 Created: 23/4/95 00989 Inputs: pZoomSpread the spread containing the point to zoom at 00990 dcZoomPos the point to at. If the CentreOnZoomClick preference 00991 is TRUE then this point will remain fixed on-screen, 00992 otherwise this point will be centred on-screen. 00993 fxNewScaleFactor the required scale factor 00994 fEndOp whether to end this operation after this zoom 00995 Purpose: Sets the current DocView to show the given point with the spread at the 00996 given scale factor. By default this function will call the End() function 00997 for this operation afterwards. 00998 ********************************************************************************************/ 00999 01000 void OpZoom::ZoomAtPoint(Spread* pZoomSpread, const DocCoord& dcZoomPos, 01001 FIXED16 fxNewScaleFactor, BOOL fEndOp) 01002 { 01003 // Now we can just pass to the WorkCoord version of this function. 01004 WorkCoord wcZoom; 01005 SpreadToWork(pZoomSpread, dcZoomPos, &wcZoom); 01006 ZoomAtPoint(wcZoom, fxNewScaleFactor, fEndOp); 01007 } 01008 01009 01010 01011 /****************************************************************************************** 01012 > BOOL OpZoom::GetStatusLineText(String_256* pText, Spread*, DocCoord, ClickModifiers) 01013 01014 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 01015 Created: 26/1/95 01016 Inputs: Spread*, DocCoord, ClickModifiers - not used 01017 Outputs: pText - 01018 Returns: TRUE if returning valid text 01019 Purpose: get status line help for zoom drag op 01020 Errors: this==0 01021 ******************************************************************************************/ 01022 01023 BOOL OpZoom::GetStatusLineText(String_256* pText, Spread*, DocCoord, ClickModifiers) 01024 { 01025 ERROR2IF(this == 0, FALSE, "OpZoom::GetStatusLineText() - this == 0"); 01026 ERROR2IF(pText == 0, FALSE, "OpZoom::GetStatusLineText() - pText == 0"); 01027 return pText->Load(_R(IDS_ZOOMOP_STATUSHELP)); 01028 } 01029 01030 01031 01032 /******************************************************************************************** 01033 > static BOOL OpZoom::Declare() 01034 01035 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01036 Created: 23/4/95 01037 Returns: TRUE if everything went OK, FALSE otherwise 01038 Purpose: "Registers" the zoom operation's OpDescriptors, loads preferences, and 01039 makes sure the zoom-in and zoom-out cursors are valid. 01040 SeeAlso: class OpZoomComboDescriptor; class OpZoomPrevZoomDescriptor; 01041 class OpZoomFitSpreadDescriptor; class OpZoomFitDrawingDescriptor 01042 ********************************************************************************************/ 01043 01044 BOOL OpZoom::Declare() 01045 { 01046 // Try to create OpDescriptors for each zoom gadget. 01047 ERRORIF(!new OpZoomComboDescriptor || 01048 !new OpZoomPrevZoomDescriptor || 01049 !new OpZoomFitSpreadDescriptor || 01050 !new OpZoomFitDrawingDescriptor || 01051 !new OpZoomFitSelectedDescriptor || 01052 !new OpZoomFitRectDescriptor || 01053 !OpZoomTo100::Init() || 01054 !OpZoomTo200::Init() || 01055 !OpZoomTo300::Init() || 01056 !OpZoomTo400::Init(), 01057 _R(IDE_NOMORE_MEMORY), 01058 FALSE); 01059 01060 #if !defined(EXCLUDE_FROM_RALPH) 01061 // Try to load preferences. 01062 ERRORIF(!GetApplication()->DeclareSection(TEXT("Zoom Tool"), 5) || 01063 !GetApplication()->DeclarePref(TEXT("Zoom Tool"), TEXT("FixZoomClickPoint"), 01064 &m_fFixZoomClickPoint, FALSE, TRUE) || 01065 !GetApplication()->DeclarePref(TEXT("Zoom Tool"), TEXT("RadialZoomDragBox"), 01066 &m_fRadialZoomDragBox, FALSE, TRUE) || 01067 !GetApplication()->DeclarePref(TEXT("Zoom Tool"), TEXT("ShowZoomCursors"), 01068 &m_nfShowZoomCursors, 0, 1), 01069 _R(IDE_BAD_INI_FILE), 01070 FALSE); 01071 #endif 01072 01073 // Success. 01074 return TRUE; 01075 } 01076 01077 01078 01079 /******************************************************************************************** 01080 > void OpZoom::MouseWheelZoomAtPoint(const WorkCoord& wcZoom, INT32 nNewScalePercent, 01081 BOOL fEndOp = TRUE) 01082 01083 Author: Priestley (Xara Group Ltd) <camelotdev@xara.com> (BLATANTLY ripped from JustinF & Rik) 01084 Created: 17/11/2000 01085 Inputs: wcZoom the point within the current view to zoom at, 01086 in work coordinates. 01087 fxNewScaleFactor the required scale factor 01088 fEndOp whether to end this operation after this zoom 01089 Purpose: Sets the current DocView to show the given point at the given scale factor. 01090 By default this function will call the End() function for this operation 01091 afterwards. 01092 ********************************************************************************************/ 01093 01094 void OpZoom::MouseWheelZoomAtPoint(const WorkCoord& wcZoom, FIXED16 fxNewScaleFactor, BOOL fEndOp) 01095 { 01096 // Get the current view. 01097 DocView* pDocView = DocView::GetCurrent(); 01098 ERROR3IF(pDocView == 0, "No current DocView in OpZoom::ZoomAtPoint"); 01099 01100 // Save the view's current zoom and find out current scaling factor. 01101 OpZoomPrevZoomDescriptor::SaveZoom(pDocView); 01102 FIXED16 fxOldScaleFactor = pDocView->GetViewScale(); 01103 01104 // Push the zoom-in or zoom-out cursor, depending on whether we are zooming in or 01105 // out. 01106 INT32 ncsrOldID=0; 01107 if (ZoomTool::IsSelectedTool() && m_nfShowZoomCursors) 01108 { 01109 ncsrOldID = CursorStack::GPush((fxNewScaleFactor > fxOldScaleFactor) 01110 ? &m_csrZoomIn 01111 : &m_csrZoomOut); 01112 } 01113 01114 // Find the current view size in 64-bit work coordinates. 01115 WorkRect wrView = pDocView->GetViewRect(); 01116 01117 // Work out the ratio of the new and old scale factors. 01118 double fpLineRatio = fxOldScaleFactor.MakeDouble() / fxNewScaleFactor.MakeDouble(); 01119 01120 // We either centre the clicked point or keep it fixed, depending on the preferences. 01121 // Calculate the new position of the top-left of the view accordingly. 01122 WorkCoord wcNewTopCorner = wcZoom; 01123 01124 // if (!m_fFixZoomClickPoint) 01125 // { 01126 // Find the vector from the click point to the top corner of the window, and 01127 // from this work out the new position of the top-left corner of the view. 01128 wcNewTopCorner.x += XLONG(fpLineRatio * (wrView.lo.x - wcZoom.x)); 01129 wcNewTopCorner.y += XLONG(fpLineRatio * (wrView.hi.y - wcZoom.y)); 01130 // } 01131 // else 01132 // { 01133 // // Find the vector from the centre of the view to the top-left corner, scaled by 01134 // // the line-ratio. Add this vector to the click point to work out the new position 01135 // // of the top-left corner of the view. 01136 // wcNewTopCorner.x -= MakeXLong(fpLineRatio * (wrView.Width().MakeDouble() / 2)); 01137 // wcNewTopCorner.y += MakeXLong(fpLineRatio * (wrView.Height().MakeDouble() / 2)); 01138 // } 01139 01140 // Scale the value to the correct number of pixels. We convert to doubles as the 01141 // fixed-point numbers can lose precision at high zooms. 01142 double fpPixRatio = fxNewScaleFactor.MakeDouble() / fxOldScaleFactor.MakeDouble(); 01143 wcNewTopCorner.x = XLONG(fpPixRatio * wcNewTopCorner.x); 01144 wcNewTopCorner.y = XLONG(fpPixRatio * wcNewTopCorner.y); 01145 01146 // Set the new scale factor in the view. 01147 pDocView->SetViewScale(fxNewScaleFactor); 01148 01149 // Make sure that the new scroll offset is within workspace bounds and set it. 01150 if (wcNewTopCorner.x < 0) wcNewTopCorner.x = 0; 01151 if (wcNewTopCorner.y > 0) wcNewTopCorner.y = 0; 01152 pDocView->SetScrollOffsets(wcNewTopCorner, FALSE); 01153 01154 #ifndef RALPH 01155 // Update the combo-box containing scale factors. 01156 OpZoomComboDescriptor::Update(); 01157 #endif 01158 01159 // Finally redraw the whole window, reset the cursor, and end the operation. 01160 pDocView->ForceRedraw(TRUE); 01161 if (ZoomTool::IsSelectedTool() && m_nfShowZoomCursors) CursorStack::GPop(ncsrOldID); 01162 if (fEndOp) End(); 01163 01164 // tell people things have changed on screen 01165 TRACEUSER( "Diccon", _T("ZoomAtPoint\n")); 01166 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 01167 } 01168 01169 01171 // class OpZoomTo100 01172 OpZoomTo100::OpZoomTo100() 01173 { 01174 } 01175 01176 BOOL OpZoomTo100::Init() 01177 { 01178 BOOL ok = RegisterOpDescriptor( 01179 0, 01180 _R(IDS_ZOOMTO100), 01181 CC_RUNTIME_CLASS(OpZoomTo100), 01182 OPTOKEN_ZOOMTO100, 01183 OpZoomTo100::GetState, 01184 0, /* help ID */ 01185 _R(IDBBL_ZOOMTO100),/* bubble ID */ 01186 0 /* bitmap ID */ 01187 ); 01188 return ok; 01189 } 01190 01191 /*********************************************************************************************** 01192 01193 > static OpState OpZoomToo100::GetState(String_256* Description, OpDescriptor*) 01194 01195 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01196 Created: 18/09/06 01197 Inputs: Description = ptr to place description of why this op can't happen 01198 pOpDesc = ptr to the Op Desc associated with this op 01199 Outputs: - 01200 Returns: An OpState object 01201 Purpose: Func for determining the usability of this op 01202 SeeAlso: - 01203 01204 ***********************************************************************************************/ 01205 OpState OpZoomTo100::GetState(String_256* Description, OpDescriptor*) 01206 { 01207 OpState State; 01208 return State; 01209 } 01210 01211 /******************************************************************************************** 01212 01213 > virtual void OpZoomToo100::Do(OpDescriptor* pOpDesc) 01214 01215 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01216 Created: 18/09/06 01217 Inputs: pointer to the OpZoomDescriptor being invoked 01218 Purpose: Calls the base class function to zoom to 100%! 01219 01220 ********************************************************************************************/ 01221 void OpZoomTo100::Do(OpDescriptor *pOpDesc) 01222 { 01223 // Ok! lets zoom in! 01224 DocView* pDocView = DocView::GetCurrent(); 01225 01226 if(pDocView) 01227 { 01228 const WorkRect ZoomRect = pDocView->GetViewRect(); 01229 ZoomTo( ZoomRect.Centre(), 100 ); 01230 } 01231 else 01232 { 01233 ERROR3IF(pDocView == 0, "No current DocView found!"); 01234 } 01235 } 01236 01238 // class OpZoomTo200 01239 OpZoomTo200::OpZoomTo200() 01240 { 01241 } 01242 01243 BOOL OpZoomTo200::Init() 01244 { 01245 BOOL ok = RegisterOpDescriptor( 01246 0, 01247 _R(IDS_ZOOMTO200), 01248 CC_RUNTIME_CLASS(OpZoomTo200), 01249 OPTOKEN_ZOOMTO200, 01250 OpZoomTo200::GetState, 01251 0, /* help ID */ 01252 _R(IDBBL_ZOOMTO200),/* bubble ID */ 01253 0 /* bitmap ID */ 01254 ); 01255 return ok; 01256 } 01257 01258 /*********************************************************************************************** 01259 01260 > static OpState OpZoomTo200::GetState(String_256* Description, OpDescriptor*) 01261 01262 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01263 Created: 18/09/06 01264 Inputs: Description = ptr to place description of why this op can't happen 01265 pOpDesc = ptr to the Op Desc associated with this op 01266 Outputs: - 01267 Returns: An OpState object 01268 Purpose: Func for determining the usability of this op 01269 SeeAlso: - 01270 01271 ***********************************************************************************************/ 01272 OpState OpZoomTo200::GetState(String_256* Description, OpDescriptor*) 01273 { 01274 OpState State; 01275 return State; 01276 } 01277 01278 /******************************************************************************************** 01279 01280 > virtual void OpZoomTo200::Do(OpDescriptor* pOpDesc) 01281 01282 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01283 Created: 18/09/06 01284 Inputs: pointer to the OpZoomDescriptor being invoked 01285 Purpose: Calls the base class function to zoom to 200%! 01286 01287 ********************************************************************************************/ 01288 void OpZoomTo200::Do(OpDescriptor *pOpDesc) 01289 { 01290 // Ok! lets zoom in! 01291 DocView* pDocView = DocView::GetCurrent(); 01292 01293 if(pDocView) 01294 { 01295 const WorkRect ZoomRect = pDocView->GetViewRect(); 01296 ZoomTo( ZoomRect.Centre(), 200 ); 01297 } 01298 else 01299 { 01300 ERROR3IF(pDocView == 0, "No current DocView found!"); 01301 } 01302 } 01303 01305 // class OpZoomTo400 01306 OpZoomTo300::OpZoomTo300() 01307 { 01308 } 01309 01310 BOOL OpZoomTo300::Init() 01311 { 01312 BOOL ok = RegisterOpDescriptor( 01313 0, 01314 _R(IDS_ZOOMTO300), 01315 CC_RUNTIME_CLASS(OpZoomTo300), 01316 OPTOKEN_ZOOMTO300, 01317 OpZoomTo300::GetState, 01318 0, /* help ID */ 01319 _R(IDBBL_ZOOMTO300),/* bubble ID */ 01320 0 /* bitmap ID */ 01321 ); 01322 01323 return ok; 01324 } 01325 01326 /*********************************************************************************************** 01327 01328 > static OpState OpZoomToo100::GetState(String_256* Description, OpDescriptor*) 01329 01330 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01331 Created: 18/09/06 01332 Inputs: Description = ptr to place description of why this op can't happen 01333 pOpDesc = ptr to the Op Desc associated with this op 01334 Outputs: - 01335 Returns: An OpState object 01336 Purpose: Func for determining the usability of this op 01337 SeeAlso: - 01338 01339 ***********************************************************************************************/ 01340 OpState OpZoomTo300::GetState(String_256* Description, OpDescriptor*) 01341 { 01342 OpState State; 01343 return State; 01344 } 01345 01346 /******************************************************************************************** 01347 01348 > virtual void OpZoomTo300::Do(OpDescriptor* pOpDesc) 01349 01350 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01351 Created: 18/09/06 01352 Inputs: pointer to the OpZoomDescriptor being invoked 01353 Purpose: Calls the base class function to zoom to 300%! 01354 01355 ********************************************************************************************/ 01356 void OpZoomTo300::Do(OpDescriptor *pOpDesc) 01357 { 01358 // Ok! lets zoom in! 01359 DocView* pDocView = DocView::GetCurrent(); 01360 01361 if(pDocView) 01362 { 01363 const WorkRect ZoomRect = pDocView->GetViewRect(); 01364 ZoomTo( ZoomRect.Centre(), 300 ); 01365 } 01366 else 01367 { 01368 ERROR3IF(pDocView == 0, "No current DocView found!"); 01369 } 01370 } 01371 01373 // class OpZoomTo400 01374 OpZoomTo400::OpZoomTo400() 01375 { 01376 } 01377 01378 BOOL OpZoomTo400::Init() 01379 { 01380 BOOL ok = RegisterOpDescriptor( 01381 0, 01382 _R(IDS_ZOOMTO400), 01383 CC_RUNTIME_CLASS(OpZoomTo400), 01384 OPTOKEN_ZOOMTO400, 01385 OpZoomTo400::GetState, 01386 0, /* help ID */ 01387 _R(IDBBL_ZOOMTO400),/* bubble ID */ 01388 0 /* bitmap ID */ 01389 ); 01390 01391 return ok; 01392 } 01393 01394 /*********************************************************************************************** 01395 01396 > static OpState OpZoomToo100::GetState(String_256* Description, OpDescriptor*) 01397 01398 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01399 Created: 18/09/06 01400 Inputs: Description = ptr to place description of why this op can't happen 01401 pOpDesc = ptr to the Op Desc associated with this op 01402 Outputs: - 01403 Returns: An OpState object 01404 Purpose: Func for determining the usability of this op 01405 SeeAlso: - 01406 01407 ***********************************************************************************************/ 01408 OpState OpZoomTo400::GetState(String_256* Description, OpDescriptor*) 01409 { 01410 OpState State; 01411 return State; 01412 } 01413 01414 /******************************************************************************************** 01415 01416 > virtual void OpZoomToo100::Do(OpDescriptor* pOpDesc) 01417 01418 Author: Luke_Hart (Xara Group Ltd) <camelotdev@xara.com> 01419 Created: 18/09/06 01420 Inputs: pointer to the OpZoomDescriptor being invoked 01421 Purpose: Calls the base class function to zoom to 400%! 01422 01423 ********************************************************************************************/ 01424 void OpZoomTo400::Do(OpDescriptor *pOpDesc) 01425 { 01426 // Ok! lets zoom in! 01427 DocView* pDocView = DocView::GetCurrent(); 01428 01429 if(pDocView) 01430 { 01431 const WorkRect ZoomRect = pDocView->GetViewRect(); 01432 ZoomTo( ZoomRect.Centre(), 400 ); 01433 } 01434 else 01435 { 01436 ERROR3IF(pDocView == 0, "No current DocView found!"); 01437 } 01438 } 01439 01440 01442 // class OpZoomIn 01443 OpZoomIn::OpZoomIn() 01444 { 01445 } 01446 01447 BOOL OpZoomIn::Init() 01448 { 01449 BOOL ok = RegisterOpDescriptor( 01450 0, 01451 _R(IDS_ZOOMIN), 01452 CC_RUNTIME_CLASS(OpZoomIn), 01453 OPTOKEN_ZOOMIN, 01454 OpZoomIn::GetState, 01455 0, /* help ID */ 01456 0, /* bubble ID */ 01457 0 /* bitmap ID */ 01458 ); 01459 return ok; 01460 } 01461 01462 /*********************************************************************************************** 01463 01464 > static OpState OpZoomIn::GetState(String_256* Description, OpDescriptor*) 01465 01466 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01467 Created: 26/3/97 01468 Inputs: Description = ptr to place description of why this op can't happen 01469 pOpDesc = ptr to the Op Desc associated with this op 01470 Outputs: - 01471 Returns: An OpState object 01472 Purpose: Func for determining the usability of this op 01473 SeeAlso: - 01474 01475 ***********************************************************************************************/ 01476 OpState OpZoomIn::GetState(String_256* Description, OpDescriptor*) 01477 { 01478 OpState State; 01479 return State; 01480 } 01481 01482 /******************************************************************************************** 01483 01484 > virtual void OpZoomIn::Do(OpDescriptor* pOpDesc) 01485 01486 Author: Mark_Howitt (Xara Group Ltd) <camelotdev@xara.com> 01487 Created: 19/11/00 01488 Inputs: pointer to the OpZoomDescriptor being invoked 01489 Purpose: Calls the base class function to zoom in! 01490 01491 ********************************************************************************************/ 01492 void OpZoomIn::Do(OpDescriptor *pOpDesc) 01493 { 01494 // Ok! lets zoom in! 01495 DocView* pDocView = DocView::GetCurrent(); 01496 01497 if(pDocView) 01498 { 01499 const WorkRect ZoomRect = pDocView->GetViewRect(); 01500 ZoomIn(ZoomRect.Centre()); 01501 } 01502 else 01503 { 01504 ERROR3IF(pDocView == 0, "No current DocView found!"); 01505 } 01506 } 01507 01509 // class OpZoomOut 01510 OpZoomOut::OpZoomOut() 01511 { 01512 } 01513 01514 BOOL OpZoomOut::Init() 01515 { 01516 BOOL ok = RegisterOpDescriptor( 01517 0, 01518 _R(IDS_ZOOMOUT), 01519 CC_RUNTIME_CLASS(OpZoomOut), 01520 OPTOKEN_ZOOMOUT, 01521 OpZoomOut::GetState, 01522 0, /* help ID */ 01523 0, /* bubble ID */ 01524 0 /* bitmap ID */ 01525 ); 01526 return ok; 01527 } 01528 01529 /*********************************************************************************************** 01530 01531 > static OpState OpZoomOut::GetState(String_256* Description, OpDescriptor*) 01532 01533 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01534 Created: 26/3/97 01535 Inputs: Description = ptr to place description of why this op can't happen 01536 pOpDesc = ptr to the Op Desc associated with this op 01537 Outputs: - 01538 Returns: An OpState object 01539 Purpose: Func for determining the usability of this op 01540 SeeAlso: - 01541 01542 ***********************************************************************************************/ 01543 OpState OpZoomOut::GetState(String_256* Description, OpDescriptor*) 01544 { 01545 OpState State; 01546 return State; 01547 } 01548 01549 /******************************************************************************************** 01550 01551 > virtual void OpZoomOut::Do(OpDescriptor* pOpDesc) 01552 01553 Author: Mark_Howitt (Xara Group Ltd) <camelotdev@xara.com> 01554 Created: 19/11/00 01555 Inputs: pointer to the OpZoomDescriptor being invoked 01556 Purpose: Calls the base class function to zoom Out! 01557 01558 ********************************************************************************************/ 01559 void OpZoomOut::Do(OpDescriptor *pOpDesc) 01560 { 01561 // Ok! lets zoom Out! 01562 DocView* pDocView = DocView::GetCurrent(); 01563 01564 if(pDocView) 01565 { 01566 const WorkRect ZoomRect = pDocView->GetViewRect(); 01567 ZoomOut(ZoomRect.Centre()); 01568 } 01569 else 01570 { 01571 ERROR3IF(pDocView == 0, "No current DocView found!"); 01572 } 01573 } 01574 01576 // class OpZoomDescriptor 01577 01578 /******************************************************************************************** 01579 > OpZoomDescriptor::OpZoomDescriptor(const TCHAR* pcszToken, UINT32 wStatusID, 01580 UINT32 wHelpID, UINT32 wBubbleID, 01581 UINT32 resourceID=0, UINT32 controlID=0) 01582 01583 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01584 Created: 26/5/94 01585 Inputs: pcszToken the "token" (OLE verb?) of the associated Operation 01586 wStatusID string resource ID of status-bar text 01587 wHelpID string ID of help text/jump (?) 01588 wBubbleID string ID of bubble-help text 01589 Outputs: - 01590 Returns: - 01591 Purpose: Constructs the base class of the OpZoom's OpDescriptors 01592 Errors: - 01593 SeeAlso: class OpZoomFitSpreadDescriptor; class OpZoomFitDrawingDescriptor; 01594 class OpZoomFitSelectedDescriptor; class OpZoomPrevZoomDescriptor 01595 ********************************************************************************************/ 01596 01597 OpZoomDescriptor::OpZoomDescriptor(const TCHAR* pcszToken, UINT32 wStatusID, 01598 UINT32 wHelpID, UINT32 wBubbleID, UINT32 resourceID, UINT32 controlID) 01599 : OpDescriptor(0, // tool ID 01600 wStatusID, // string ID of text in status bar 01601 CC_RUNTIME_CLASS(OpZoom), 01602 (TCHAR*) pcszToken, 01603 GetState, 01604 wHelpID, // help link ID 01605 wBubbleID, // bubble help string ID 01606 resourceID, 01607 controlID, 01608 TRUE) // wants to receive messages 01609 { 01610 // Empty. 01611 } 01612 01613 01614 01615 /******************************************************************************************** 01616 > static OpState OpZoomDescriptor::GetState(String_256* pDesc, OpDescriptor* pOpDesc) 01617 01618 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01619 Created: 23/4/95 01620 Inputs: pDesc --- A pointer to a String. GetState fills this with the 01621 appropriate details for the conditions arising eg. why 01622 "Previous Zoom" is greyed out. 01623 pOpDesc --- A pointer to the OpDescriptor whose state is being 01624 queried. 01625 Returns: An OpState containing the flags that show what is valid. 01626 Purpose: Returns the state that this zoom operation should appear in the menus 01627 or as a buttom, for example - greyed out, or ticked. 01628 SeeAlso: OpZoomDescriptor::IsAvailable 01629 ********************************************************************************************/ 01630 01631 OpState OpZoomDescriptor::GetState(String_256*, OpDescriptor* pOpDesc) 01632 { 01633 BOOL fCanDo = ((OpZoomDescriptor*) pOpDesc)->IsAvailable(); 01634 /* TRACEUSER( "JustinF", _T("OpZoomDescriptor::GetState for %-12s (0x%lX) - %-8s at %lu ms\n"), 01635 (LPCTSTR) pOpDesc->Token, 01636 (UINT32) pOpDesc, 01637 (LPCTSTR) (fCanDo ? TEXT("OK") : TEXT("Greyed")), 01638 (UINT32) ::GetTickCount()); 01639 */ return OpState(FALSE, !fCanDo); 01640 } 01641 01642 01643 01644 /******************************************************************************************** 01645 > virtual BOOL OpZoomDescriptor::IsAvailable() 01646 01647 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01648 Created: 26/5/94 01649 Inputs: - 01650 Outputs: - 01651 Returns: TRUE if the Operation is available. By default this returns TRUE if there 01652 is a "selected" document, a spread, and a rectangle to zoom in on. 01653 Purpose: Default "GetState"-like function for OpZoomDescriptor derivatives. 01654 Errors: - 01655 SeeAlso: OpZoom::GetState; DocView::GetSelected; OpState::OpState; 01656 OpZoomDescriptor::GetSpread; OpZoomDescriptor::GetRect 01657 ********************************************************************************************/ 01658 01659 BOOL OpZoomDescriptor::IsAvailable() 01660 { 01661 // Try to get the "selected" view. 01662 DocView* pDocView = DocView::GetCurrent(); 01663 if (pDocView == 0) 01664 { 01665 // TRACEUSER( "JustinF", _T("\tNo current DocView in OpZoomDescriptor::IsAvailable\n")); 01666 return FALSE; 01667 } 01668 01669 // Find the relevant spread, if any. 01670 Spread* pSpread = GetSpread(pDocView); 01671 if (pSpread == 0) 01672 { 01673 // TRACEUSER( "JustinF", _T("\tNo relevant spread in OpZoomDescriptor::IsAvailable\n")); 01674 return FALSE; 01675 } 01676 01677 DocRect ZoomRect = GetRect(pSpread); 01678 BOOL Empty = ZoomRect.IsEmpty(); 01679 #ifdef _DEBUG 01680 // Is there actually no relevant rectangle within the spread to zoom on? 01681 if (Empty) 01682 { 01683 // TRACEUSER( "JustinF", _T("\tEmpty rectangle in OpZoomDescriptor::IsAvailable\n")); 01684 } 01685 #endif 01686 01687 // Find the relevant zoom rectangle, if any. 01688 return !Empty; 01689 } 01690 01691 01692 01693 /******************************************************************************************** 01694 > virtual MsgResult OpZoomDescriptor::Message(Msg* pMsg) 01695 01696 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01697 Created: 26/5/94 01698 Inputs: - 01699 Outputs: - 01700 Returns: - 01701 Purpose: Default message despatcher for OpZoomDescriptor derivatives. Passes 01702 button messages to HandleButtonMsg (virtual). 01703 Errors: - 01704 SeeAlso: OpZoomDescriptor::HandleButtonMsg 01705 ********************************************************************************************/ 01706 01707 MsgResult OpZoomDescriptor::Message(Msg* pMsg) 01708 { 01709 // Check if the message is an OpDesc message. 01710 if (!MESSAGE_IS_A(pMsg, OpDescMsg)) return OK; 01711 01712 // Cast it into the correct type etc. 01713 OpDescMsg* pOpDescMsg = (OpDescMsg*) pMsg; 01714 01715 // Process the message . . . 01716 if (pOpDescMsg->OpDesc == this && MESSAGE_IS_A(pOpDescMsg, OpDescControlMsg)) 01717 { 01718 // Cast to a control message, unpack, and despatch to the handler. 01719 OpDescControlMsg* pControlMsg = (OpDescControlMsg*) pOpDescMsg; 01720 if (pControlMsg->DlgMsg == DIM_LFT_BN_CLICKED) 01721 { 01722 if (IsAvailable()) 01723 return HandleButtonMsg(pControlMsg->pDlgOp, pOpDescMsg->SetGadgetID); 01724 #if !defined(EXCLUDE_FROM_RALPH) 01725 else 01726 // Beep(); 01727 wxBell(); 01728 #endif 01729 } 01730 } 01731 01732 // Let the base class do its stuff on the message. 01733 return OpDescriptor::Message(pMsg); 01734 } 01735 01736 01737 01738 /******************************************************************************************** 01739 > virtual BOOL OpZoomDescriptor::DoZoom(OpZoom * pOpZoom) 01740 01741 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01742 Created: 21/9/95 01743 Inputs: pZoomOp pointer to the OpZoom to be used 01744 Returns: True if operation has happened correctly 01745 Purpose: Is the base zoom descriptor class function for performing a zoom operation. 01746 It does this by calling (virtual) GetSpread to find the spread to zoom in on, 01747 then (virtual) GetRect to find the rectangle within the spread. The (virtual) 01748 function AdjustRect is called to modify the resultant rectangle. Derived 01749 classes can override these functions to customise the effects of particular 01750 zoom operation. 01751 Performs the zoom, after saving the current zoom settings, then updates 01752 the zoom combo box. 01753 Similar button to HandleButtonMsg but is designed to be called by the Do() 01754 operator in OpZoom and hence from keyboard short-cuts or menu operations. 01755 Errors: - 01756 SeeAlso: OpZoom::Do; 01757 OpZoomDescriptor::GetSpread; OpZoomDescriptor::GetRect; 01758 OpZoomDescriptor::AdjustRect 01759 ********************************************************************************************/ 01760 01761 BOOL OpZoomDescriptor::DoZoom(OpZoom* pZoomOp) 01762 { 01763 ERROR2IF(pZoomOp == 0, FALSE, "OpZoomDescriptor::DoZoom called with no operation"); 01764 01765 // Get the current view. 01766 DocView* pDocView = DocView::GetCurrent(); 01767 ERROR3IF(pDocView == 0, "No current DocView in OpZoomDescriptor::HandleButtonMsg"); 01768 if (pDocView == 0) 01769 return FAIL; 01770 01771 // Find the relevant spread, if any. 01772 Spread* pSpread = GetSpread(pDocView); 01773 ERROR3IF(pSpread == 0, "No relevant spread - can't do zoom\n"); 01774 if (pSpread == 0) 01775 return FAIL; 01776 01777 // Find the relevant zoom rectangle. 01778 DocRect drBounds = GetRect(pSpread); 01779 ERROR3IF(drBounds.IsEmpty(), "Relevant rectangle is empty - can't do zoom\n"); 01780 01781 // Allow derived class to adjust the document rectangle if it so desires. 01782 AdjustRect(&drBounds); 01783 01784 // Do the zoom, the scaling factor of which will not appear in the zoom op's table. 01785 pZoomOp->ZoomInOnRect(pSpread, drBounds); 01786 01787 return TRUE; 01788 } 01789 01790 01791 01792 /******************************************************************************************** 01793 > virtual MsgResult OpZoomDescriptor::HandleButtonMsg(DialogOp* pdlgop, CGadgetID gid) 01794 01795 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01796 Created: 26/5/94 01797 Inputs: pdlgop pointer to the dialog operation ("unpacked" from a message) 01798 gid the gadget ID associated with this OpDescriptor 01799 Outputs: - 01800 Returns: The message result code (either EAT_MSG or OK) 01801 Purpose: Handles a button click message, by calling (virtual) GetSpread to find the 01802 spread to zoom in on, then (virtual) GetRect to find the rectangle within 01803 the spread. The (virtual) function AdjustRect is called to modify the 01804 resultant rectangle. Derived classes can override these functions to 01805 customise the effects of particular buttons. Performs the zoom, after 01806 saving the current zoom settings, then updates the zoom combo box. 01807 Errors: - 01808 SeeAlso: OpZoomDescriptor::GetSpread; OpZoomDescriptor::GetRect; 01809 OpZoomDescriptor::AdjustRect 01810 ********************************************************************************************/ 01811 01812 MsgResult OpZoomDescriptor::HandleButtonMsg(DialogOp*, CGadgetID) 01813 { 01814 // Try to create an instance of the zoom operation. 01815 OpZoom* pZoomOp = new OpZoom; 01816 ERRORIF(pZoomOp == 0, _R(IDE_NOMORE_MEMORY), FAIL); 01817 01818 // Do the zoom, the scaling factor of which will not appear in the zoom op's table. 01819 // DoZoom will End the operation 01820 BOOL ok = DoZoom(pZoomOp); 01821 if (!ok) return FAIL; 01822 return OK; 01823 } 01824 01825 01826 01827 /******************************************************************************************** 01828 > virtual Spread* OpZoomDescriptor::GetSpread(DocView* pDocView) const 01829 01830 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01831 Created: 26/5/94 01832 Inputs: pDocView the DocView containing the spread. 01833 Outputs: - 01834 Returns: A pointer to the relevant spread to zoom in on. By default this is the 01835 document page, ie. the first spread in the document. 01836 Purpose: Gets a spread given a DocView. 01837 Errors: - 01838 SeeAlso: OpZoomDescriptor::HandleButtonMsg; View::GetDoc; Document::FindFirstSpread 01839 ********************************************************************************************/ 01840 01841 Spread* OpZoomDescriptor::GetSpread(DocView* pDocView) const 01842 { 01843 PORTNOTE("spread", "Multi-spread warning!") 01844 return pDocView->GetDoc()->FindFirstSpread(); 01845 } 01846 01847 01848 01849 /******************************************************************************************** 01850 > virtual DocRect OpZoomDescriptor::GetRect(Spread* pSpread) 01851 01852 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01853 Created: 26/5/94 01854 Inputs: pSpread the spread to zoom in on 01855 Outputs: - 01856 Returns: A rectangle within the spread to zoom in on. By default this is the 01857 "bounding rectangle" of the given spread. 01858 Purpose: Gets a rectangle given a spread. 01859 Errors: - 01860 SeeAlso: OpZoomDescriptor::HandleButtonMsg; Spread::GetBoundingRect 01861 ********************************************************************************************/ 01862 01863 DocRect OpZoomDescriptor::GetRect(Spread* pSpread) 01864 { 01865 return pSpread->GetBoundingRect(); 01866 } 01867 01868 01869 01870 /******************************************************************************************** 01871 > virtual void OpZoomDescriptor::AdjustRect(DocRect* pRect) const 01872 01873 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01874 Created: 31/5/94 01875 Inputs: pRect pointer to a DocRect to adjust 01876 Outputs: The adjusted DocRect. 01877 Returns: - 01878 Purpose: In the base class version inflates the given document rectangle by 01879 5% in each direction. 01880 Errors: - 01881 SeeAlso: OpZoomDescriptor::HandleButtonMsg; OpZoomDescriptor::GetRect 01882 ********************************************************************************************/ 01883 01884 void OpZoomDescriptor::AdjustRect(DocRect* pRect) const 01885 { 01886 INT32 xinc = pRect->Width() / 20; // find 5% of the width and height 01887 INT32 yinc = pRect->Height() / 20; 01888 if (xinc < 1) xinc = 1; // make sure we inflate by some amount 01889 if (yinc < 1) yinc = 1; 01890 pRect->lo.x -= xinc; // inflate the given rectangle 01891 pRect->lo.y -= yinc; 01892 pRect->hi.x += xinc; 01893 pRect->hi.y += yinc; 01894 } 01895 01896 01897 01898 /******************************************************************************************** 01899 > static void OpZoomDescriptor::FakeInvoke(TCHAR* pszToken) 01900 01901 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01902 Created: 18/7/94 01903 Inputs: pszToken --- pointer to the "invoked" OpDescriptor's token 01904 Outputs: - 01905 Returns: - 01906 Purpose: "Fakes" a button message for OpDescriptor classes derived from 01907 OpZoomDescriptor. Searches for the OpDescriptor associated with the 01908 specified token. If it finds it then casts it to an OpZoomDescriptor*, 01909 checks if the associated button isn't greyed, and if not, calls its 01910 HandleButtonMsg function. Finally it makes sure that the percentage 01911 scale factor of the selected DocView is updated in the zoom combo box. 01912 Errors: - 01913 SeeAlso: OpZoomComboDescriptor::OnSelectionChanged 01914 ********************************************************************************************/ 01915 01916 void OpZoomDescriptor::FakeInvoke(TCHAR* pszToken) 01917 { 01918 // Try to find the OpDescriptor. 01919 OpZoomDescriptor* pZoomOpDesc = (OpZoomDescriptor*) FindOpDescriptor(pszToken); 01920 01921 // If that worked then call its button handler. 01922 if (pZoomOpDesc != 0 && pZoomOpDesc->IsAvailable()) 01923 { 01924 pZoomOpDesc->HandleButtonMsg(0, 0); 01925 } 01926 #ifndef RALPH 01927 else 01928 { 01929 // If it didn't then refresh the zoom combo with some percentages. 01930 // Beep(); 01931 wxBell(); 01932 OpZoomComboDescriptor::Update(); 01933 } 01934 #endif 01935 } 01936 01937 /******************************************************************************************** 01938 01939 > static void OpZoomDescriptor::FakeZoomToRect(DocRect* pRect) 01940 01941 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01942 Created: 13/9/96 01943 Inputs: pRect, pointer to a rect to zoom to 01944 Outputs: - 01945 Returns: - 01946 Purpose: "Fakes" a button message for the ZoomRect OpDescriptor, using the specified, 01947 rectangle. 01948 Errors: - 01949 01950 ********************************************************************************************/ 01951 01952 void OpZoomDescriptor::FakeZoomToRect(const DocRect& rect) 01953 { 01954 // Try to find the OpDescriptor. 01955 OpZoomDescriptor* pZoomOpDesc = (OpZoomDescriptor*) FindOpDescriptor(OPTOKEN_ZOOMRECT); 01956 01957 // If that worked then call its button handler. 01958 if (pZoomOpDesc != 0) 01959 { 01960 ((OpZoomFitRectDescriptor*) pZoomOpDesc)->SetZoomRect(rect); 01961 pZoomOpDesc->HandleButtonMsg(0, 0); 01962 } 01963 } 01964 01966 // class OpZoomFitSpreadDescriptor 01967 01968 /******************************************************************************************** 01969 > OpZoomFitSpreadDescriptor::OpZoomFitSpreadDescriptor() 01970 01971 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01972 Created: 26/5/94 01973 Inputs: - 01974 Outputs: - 01975 Returns: - 01976 Purpose: Constructs an OpDescriptor for the "Zoom to spread" button. 01977 Errors: - 01978 SeeAlso: class OpZoomDescriptor 01979 ********************************************************************************************/ 01980 01981 OpZoomFitSpreadDescriptor::OpZoomFitSpreadDescriptor() 01982 : OpZoomDescriptor(OPTOKEN_ZOOMSPREAD, _R(IDS_ZOOMSPREADSTATUSTEXT), 01983 0, _R(IDBBL_FIT_TO_SPREAD)) 01984 { 01985 // default to always scaling in AdjustRect 01986 m_DontScale = TRUE; 01987 } 01988 01989 01990 01991 /******************************************************************************************** 01992 > virtual DocRect OpZoomFitSpreadDescriptor::GetRect(Spread* pSpread) 01993 01994 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01995 Created: 26/5/94 01996 Inputs: pSpread pointer to a spread 01997 Outputs: - 01998 Returns: The "page bounds" of the given spread. 01999 Purpose: Provides the rectangle that OpZoomDescriptor::HandleButtonMsg will 02000 zoom in on. 02001 Errors: - 02002 SeeAlso: OpZoomDescriptor::HandleButtonMsg; OpZoomFitSpreadDescriptor::AdjustRect; 02003 Spread::GetPageBounds 02004 ********************************************************************************************/ 02005 02006 DocRect OpZoomFitSpreadDescriptor::GetRect(Spread* pSpread) 02007 { 02008 /* 02009 #ifdef _DEBUG 02010 if (IsUserName("JustinF")) 02011 { 02012 static DocRect drOld = pSpread->GetPageBounds(); 02013 DocRect drNew = pSpread->GetPageBounds(); 02014 02015 if (drNew != drOld) 02016 { 02017 TRACE( _T("In OpZoomFitSpreadDesriptor - Spread::GetPageBounds has changed!\n") 02018 "\t- drOld is %ld x %ld\n\t- drNew is %ld x %ld\n", 02019 (INT32) drOld.Width(), (INT32) drOld.Height(), 02020 (INT32) drNew.Width(), (INT32) drNew.Height()); 02021 } 02022 02023 return drOld = drNew; 02024 } 02025 #endif 02026 */ 02027 // These are both in Document coords not spread coords! 02028 DocRect SpreadSize = pSpread->GetPageBounds(); 02029 DocRect PasteBoardSize = pSpread->GetPasteboardRect(FALSE); 02030 // If the two sizes are the same then this means we have a zero sized pasteboard 02031 // In this case, we should not try and scale up the resulting rectangle in AdjustRect 02032 // So note this state for later use. 02033 // Cannot do a straight equality check as we will have rounding errors. 02034 const MILLIPOINT delta = 1000; 02035 if ( 02036 (SpreadSize.lo.x > PasteBoardSize.lo.x - delta) && (SpreadSize.lo.x < PasteBoardSize.lo.x + delta) && 02037 (SpreadSize.hi.x > PasteBoardSize.hi.x - delta) && (SpreadSize.hi.x < PasteBoardSize.hi.x + delta) && 02038 (SpreadSize.lo.y > PasteBoardSize.lo.y - delta) && (SpreadSize.lo.y < PasteBoardSize.lo.y + delta) && 02039 (SpreadSize.hi.y > PasteBoardSize.hi.y - delta) && (SpreadSize.hi.y < PasteBoardSize.hi.y + delta) 02040 ) 02041 { 02042 m_DontScale = FALSE; 02043 } 02044 else 02045 { 02046 m_DontScale = TRUE; 02047 } 02048 02049 return SpreadSize; 02050 } 02051 02052 02053 02054 /******************************************************************************************** 02055 > virtual void OpZoomFitSpreadDescriptor::AdjustRect(DocRect* pRect) const 02056 02057 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02058 Created: 9/2/95 02059 Inputs: pRect pointer to a DocRect to adjust 02060 Outputs: The adjusted DocRect. 02061 Returns: - 02062 Purpose: Override the base class version of the fcuntion which inflates the given 02063 document rectangle by 5% in each direction for one which inflates it by 2%. 02064 Errors: - 02065 SeeAlso: OpZoomDescriptor::AdjustRect; OpZoomDescriptor::GetRect 02066 ********************************************************************************************/ 02067 02068 void OpZoomFitSpreadDescriptor::AdjustRect(DocRect* pRect) const 02069 { 02070 if (m_DontScale) 02071 { 02072 INT32 xinc = pRect->Width() / 50; // find 2% of the width and height 02073 INT32 yinc = pRect->Height() / 50; 02074 if (xinc < 1) xinc = 1; // make sure we inflate by some amount 02075 if (yinc < 1) yinc = 1; 02076 pRect->lo.x -= xinc; // inflate the given rectangle 02077 pRect->lo.y -= yinc; 02078 pRect->hi.x += xinc; 02079 pRect->hi.y += yinc; 02080 } 02081 } 02082 02083 02084 02086 // class OpZoomFitDrawingDescriptor 02087 02088 /******************************************************************************************** 02089 > OpZoomFitDrawingDescriptor::OpZoomFitDrawingDescriptor() 02090 02091 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02092 Created: 26/5/94 02093 Inputs: - 02094 Outputs: - 02095 Returns: - 02096 Purpose: Constructs an OpDescriptor for the "Zoom to drawing" button. 02097 Errors: - 02098 SeeAlso: class OpZoomDescriptor 02099 ********************************************************************************************/ 02100 02101 OpZoomFitDrawingDescriptor::OpZoomFitDrawingDescriptor() 02102 : OpZoomDescriptor(OPTOKEN_ZOOMDRAWING, _R(IDS_ZOOMDRAWINGSTATUSTEXT), 02103 0, _R(IDBBL_FIT_TO_DRAWING)) 02104 { 02105 // Empty. 02106 } 02107 02108 02109 02110 /******************************************************************************************** 02111 > virtual DocRect OpZoomFitDrawingDescriptor::GetRect(Spread* pSpread) 02112 02113 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02114 Created: 26/5/94 02115 Inputs: pSpread pointer to a spread 02116 Outputs: - 02117 Returns: The "bounds" of the drawing on the given spread, ignoring invisible 02118 layers. 02119 Purpose: Provides the rectangle that OpZoomDescriptor::HandleButtonMsg will 02120 zoom in on. 02121 Errors: - 02122 SeeAlso: OpZoomDescriptor::HandleButtonMsg; OpZoomFitSpreadDescriptor::AdjustRect; 02123 Spread::GetPageVisibleBounds 02124 ********************************************************************************************/ 02125 02126 DocRect OpZoomFitDrawingDescriptor::GetRect(Spread* pSpread) 02127 { 02128 return pSpread->GetPageVisibleBounds(); 02129 } 02130 02131 02132 02134 // class OpZoomFitSelectedDescriptor 02135 02136 /******************************************************************************************** 02137 > OpZoomFitSelectedDescriptor::OpZoomFitSelectedDescriptor() 02138 02139 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02140 Created: 26/5/94 02141 Inputs: - 02142 Outputs: - 02143 Returns: - 02144 Purpose: Constructs an OpDescriptor for the "Zoom to selected objects" button. 02145 Errors: - 02146 SeeAlso: class OpZoomDescriptor 02147 ********************************************************************************************/ 02148 02149 OpZoomFitSelectedDescriptor::OpZoomFitSelectedDescriptor() 02150 : OpZoomDescriptor(OPTOKEN_ZOOMSELECTED, _R(IDS_ZOOMSELECTEDSTATUSTEXT), 02151 0, _R(IDBBL_FIT_TO_SELECTED)) 02152 { 02153 // Empty. 02154 } 02155 02156 02157 02158 /******************************************************************************************** 02159 > virtual Spread* OpZoomFitSelectedDescriptor::GetSpread(DocView* pDocView) const 02160 02161 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02162 Created: 26/5/94 02163 Inputs: pDocView pointer to a DocView showing selected objects 02164 Outputs: - 02165 Returns: A pointer to the first spread within the viewed document that 02166 contains selected objects. 02167 Purpose: Provides the spread that OpZoomDescriptor::HandleButtonMsg will zoom 02168 in on. 02169 Errors: - 02170 SeeAlso: OpZoomDescriptor::HandleButtonMsg; DocView::GetFirstSelectedSpread 02171 ********************************************************************************************/ 02172 02173 Spread* OpZoomFitSelectedDescriptor::GetSpread(DocView* pDocView) const 02174 { 02175 return pDocView->GetFirstSelectedSpread(); 02176 } 02177 02178 02179 02180 /******************************************************************************************** 02181 > virtual DocRect OpZoomFitSelectedDescriptor::GetRect(Spread* pSpread) 02182 02183 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02184 Created: 27/5/94 02185 Inputs: pSpread pointer to the spread containing the selection 02186 Outputs: - 02187 Returns: The bounding rectangle of the selected objects. 02188 Purpose: Assuming that some objects are selected, this calculates the bounding 02189 rectangle of the selected objects, including blobs. 02190 Errors: ERROR2/3 failure if there isn't any selected objects - if this happens 02191 then something is screwy, as SelRange immediately before reported 02192 that there are selected objects, or this function wouldn't have been 02193 called. 02194 SeeAlso: OpZoomFitSelectedDescriptor::GetSpread; SelRange::GetBlobBoundingRect 02195 ********************************************************************************************/ 02196 02197 DocRect OpZoomFitSelectedDescriptor::GetRect(Spread* pSpread) 02198 { 02199 // If this function is called then we know that there is a valid selection 02200 // somewhere. 02201 SelRange* pSel = GetApplication()->FindSelection(); 02202 02203 // Doesn't do any harm to check, though! 02204 ERROR3IF(pSel == 0 || pSel->FindFirst() == 0, 02205 "Can't find a selected node in OpZoomFitSelectedDescriptor::GetRect"); 02206 ERROR3IF(pSpread != pSel->FindFirst()->FindParent(CC_RUNTIME_CLASS(Spread)), 02207 "Spread pointer has changed between calls on SelRange"); 02208 02209 // We really need to call the equivalent of GetUnionBlobBoundingRect() for the SelRange, 02210 // but this function doesn't exist, so we mimic its result here. 02211 DocRect drSel = pSel->GetBlobBoundingRect().Union(pSel->GetBoundingRect()); 02212 02213 // And convert it into document coordinates 02214 pSpread->SpreadCoordToDocCoord(&drSel); 02215 02216 // Return the bounding rectangle of the selection in "proper" document coordinates. 02217 return drSel; 02218 } 02219 02220 02221 02222 /******************************************************************************************** 02223 > virtual void OpZoomFitSelectedDescriptor::AdjustRect(DocRect* pRect) const 02224 02225 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02226 Created: 31/5/94 02227 Inputs: pRect pointer to a DocRect to adjust 02228 Outputs: The adjusted DocRect. 02229 Returns: - 02230 Purpose: Inflates the given rectangle by the same amount as the selector tool when it 02231 draws bounds blobs around the selection. This ensures that after a "Fit to 02232 Selected" zoom the bounds blobs of the zoomed object will be visible. 02233 Errors: - 02234 SeeAlso: OpZoomFitSelectedDescriptor::GetRect; SelectorTool::InflateByBlobBorder 02235 ********************************************************************************************/ 02236 02237 void OpZoomFitSelectedDescriptor::AdjustRect(DocRect* pRect) const 02238 { 02239 #ifndef STANDALONE 02240 SelectorTool::InflateByBlobBorder(pRect); 02241 #endif 02242 } 02243 02244 02246 // class OpZoomFitRectDescriptor 02247 02248 /******************************************************************************************** 02249 > OpZoomFitRectDescriptor::OpZoomFitRectDescriptor() 02250 02251 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02252 Created: 13/9/96 02253 Inputs: - 02254 Outputs: - 02255 Returns: - 02256 Purpose: Constructs an OpDescriptor for zooming to a specified rect. 02257 Errors: - 02258 SeeAlso: class OpZoomDescriptor 02259 ********************************************************************************************/ 02260 02261 OpZoomFitRectDescriptor::OpZoomFitRectDescriptor() 02262 : OpZoomDescriptor(OPTOKEN_ZOOMRECT, 0, 0, 0), 02263 TheRect(0, 0, 0, 0) 02264 { 02265 // Empty. 02266 } 02267 02268 /******************************************************************************************** 02269 02270 > void OpZoomFitRectDescriptor::SetZoomRect(const DocRect& rect) 02271 02272 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02273 Created: 13/9/96 02274 Inputs: pRect 02275 Outputs: - 02276 Purpose: Sets the rectangle that the op will zoom to. 02277 Errors: - 02278 02279 ********************************************************************************************/ 02280 02281 void OpZoomFitRectDescriptor::SetZoomRect(const DocRect& rect) 02282 { 02283 TheRect = rect; 02284 } 02285 02286 /******************************************************************************************** 02287 > virtual DocRect OpZoomFitRectDescriptor::GetRect(Spread* pSpread) 02288 02289 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02290 Created: 13/9/96 02291 Inputs: pSpread pointer to a spread 02292 Outputs: - 02293 Returns: The "bounds" of the drawing on the given spread, ignoring invisible 02294 layers. 02295 Purpose: Provides the rectangle that OpZoomDescriptor::HandleButtonMsg will 02296 zoom in on. 02297 Errors: - 02298 SeeAlso: OpZoomDescriptor::HandleButtonMsg; OpZoomFitSpreadDescriptor::AdjustRect; 02299 Spread::GetPageVisibleBounds 02300 ********************************************************************************************/ 02301 02302 DocRect OpZoomFitRectDescriptor::GetRect(Spread* pSpread) 02303 { 02304 DocRect t = TheRect; 02305 // Convert the value from spread coordinates to document coords 02306 pSpread->SpreadCoordToDocCoord(&t); 02307 02308 return t; 02309 //return TheRect; 02310 } 02311 02312 02314 // class OpZoomPrevZoomDescriptor 02315 02316 /******************************************************************************************** 02317 > OpZoomPrevZoomDescriptor::OpZoomPrevZoomDescriptor() 02318 02319 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02320 Created: 26/5/94 02321 Inputs: - 02322 Outputs: - 02323 Returns: - 02324 Purpose: Constructs an OpDescriptor for the "Previous zoom" button. 02325 Errors: - 02326 SeeAlso: class OpZoomDescriptor 02327 ********************************************************************************************/ 02328 02329 OpZoomPrevZoomDescriptor::OpZoomPrevZoomDescriptor() 02330 : OpZoomDescriptor(OPTOKEN_ZOOMPREV, _R(IDS_ZOOMPREVSTATUSTEXT), 0, _R(IDBBL_PREV_ZOOM)) 02331 { 02332 // Empty. 02333 } 02334 02335 02336 02337 /******************************************************************************************** 02338 > virtual BOOL OpZoomPrevZoomDescriptor::IsAvailable() 02339 02340 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02341 Created: 26/5/94 02342 Inputs: - 02343 Outputs: - 02344 Returns: TRUE if the "previous zoom" button is available 02345 Purpose: Decides whether the "Previous zoom" button is enabled, which it is if 02346 there is a "selected" DocView and at least one zoom has been performed 02347 upon it. 02348 Errors: - 02349 SeeAlso: OpZoom::GetState; OpZoomDescriptor::IsAvailable 02350 ********************************************************************************************/ 02351 02352 BOOL OpZoomPrevZoomDescriptor::IsAvailable() 02353 { 02354 // Check for a selected DocView, if any (the base class IsAvailable does this), and 02355 // "grey" the button if it doesn't exist or hasn't been zoomed previously. 02356 DocView* pDocView = DocView::GetCurrent(); 02357 return pDocView != 0 && pDocView->GetPrevZoomIndex() != cUninitZoomIndex; 02358 } 02359 02360 02361 02362 /******************************************************************************************** 02363 > static void OpZoomPrevZoomDescriptor::SaveZoom(DocView* pDocView) 02364 02365 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02366 Created: 26/5/94 02367 Inputs: pDocView the DocView whose current "zoom setting" is to be saved 02368 Outputs: - 02369 Returns: - 02370 Purpose: Saves the given DocView's view-scale, scroll-offsets, and index into 02371 OpZoom::ZoomTable. Used by the "Previous zoom" button. This function 02372 is called by all zoom tool routines that perform a zoom. 02373 Errors: - 02374 SeeAlso: OpZoomPrevZoomDescriptor::HandleButtonMsg; DocView::SetPrevZoomIndex; 02375 DocView::SetPrevZoomScale; DocView::SetPrevZoomOffset 02376 ********************************************************************************************/ 02377 02378 void OpZoomPrevZoomDescriptor::SaveZoom(DocView* pDocView) 02379 { 02380 // Save data about the current zoom. 02381 ERROR3IF(pDocView == 0, "No DocView in OpZoomPrevZoomDescriptor::SaveZoom"); 02382 if (pDocView != 0) 02383 { 02384 pDocView->SetPrevZoomIndex(pDocView->GetZoomTableIndex()); 02385 pDocView->SetPrevZoomScale(pDocView->GetViewScale()); 02386 pDocView->SetPrevZoomOffset(pDocView->GetScrollOffsets()); 02387 } 02388 02389 #if !defined(EXCLUDE_FROM_RALPH) 02390 // Force the GetState function to be called again. 02391 DialogBarOp::SetSystemStateChanged(); 02392 02393 // If we have saved a "previous zoom" then there is a new zoom, hence the status- 02394 // bar text must have become invalid. 02395 ZoomTool::InvalidateStatusText(); 02396 #endif 02397 } 02398 02399 02400 02401 /******************************************************************************************** 02402 > virtual BOOL OpZoomPrevZoomDescriptor::DoZoom(OpZoom* pOpZoom) 02403 02404 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02405 Created: 21/9/95 02406 Inputs: pZoomOp pointer to the OpZoom to be used, can be 0 for this. 02407 Returns: True if operation has happened correctly 02408 Purpose: Overrides the base zoom descriptor class function for performing a zoom 02409 operation. This one is different as it just needs to invoke the previous zoom 02410 that was in operation. 02411 Performs the zoom, after saving the current zoom settings, then updates 02412 the zoom combo box. 02413 Similar button to HandleButtonMsg but is designed to be called by the Do() 02414 operator in OpZoom and hence from keyboard short-cuts or menu operations. 02415 Errors: - 02416 SeeAlso: OpZoom::Do; OpZoomDescriptor::DoZoom; 02417 OpZoomDescriptor::GetSpread; OpZoomDescriptor::GetRect; 02418 OpZoomDescriptor::AdjustRect 02419 ********************************************************************************************/ 02420 02421 BOOL OpZoomPrevZoomDescriptor::DoZoom(OpZoom* pZoomOp) 02422 { 02423 // ZoomOp can be null. 02424 // ERROR2IF(pZoomOp == 0, FALSE, "No operation in OpZoomPrevZoomDescriptor::DoZoom") 02425 02426 // Get the selected DocView. 02427 DocView* pDocView = DocView::GetCurrent(); 02428 ERROR2IF(pDocView == 0, FAIL, "No DocView in OpZoomPrevZoomDescriptor::HandleClickMsg"); 02429 02430 DialogBarOp::SetSystemStateChanged(); 02431 02432 // Record the current scale and scroll offset. 02433 INT32 nIndex = pDocView->GetZoomTableIndex(); 02434 FIXED16 fxScale = pDocView->GetViewScale(); 02435 WorkCoord wcOffset = pDocView->GetScrollOffsets(); 02436 02437 // Restore the previous scale factor and scroll offsets. 02438 pDocView->SetZoomTableIndex(pDocView->GetPrevZoomIndex()); 02439 pDocView->SetViewScale(pDocView->GetPrevZoomScale()); 02440 pDocView->SetScrollOffsets(pDocView->GetPrevZoomOffset(), FALSE); 02441 02442 // Remember the "previous previous" zoom . . . 02443 pDocView->SetPrevZoomIndex(nIndex); 02444 pDocView->SetPrevZoomScale(fxScale); 02445 pDocView->SetPrevZoomOffset(wcOffset); 02446 02447 #ifndef RALPH 02448 // Update the combo-box etc. 02449 OpZoomComboDescriptor::Update(); 02450 ZoomTool::InvalidateStatusText(); 02451 #endif 02452 02453 // Finally, force a redraw and return the success code. 02454 pDocView->ForceRedraw(TRUE); 02455 02456 // End the operation as we have finished 02457 if (pZoomOp) 02458 pZoomOp->End(); 02459 02460 // tell people things have changed on screen 02461 TRACEUSER( "Diccon", _T("DoZoom\n")); 02462 BROADCAST_TO_ALL(ScreenChangeMsg(TRUE)); 02463 return TRUE; 02464 } 02465 02466 /******************************************************************************************** 02467 > virtual MsgResult OpZoomPrevZoomDescriptor::HandleButtonMsg(DialogOp*, CGadgetID) 02468 02469 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02470 Created: 26/5/94 02471 Inputs: (not used, see OpZoomDescriptor::HandleButtonMsg) 02472 Outputs: - 02473 Returns: The message result code (always OK) 02474 Purpose: Responds to a click on the "Previous zoom" button by reading the 02475 saved zoom parameters in the "selected" DocView, if any, and resetting 02476 the DocView to them. 02477 Errors: - 02478 SeeAlso: OpZoomPrevZoomDescriptor::SaveZoom; DocView::SetZoomTableIndex; 02479 DocView::SetPrevZoomIndex; DocView::SetPrevZoomOffset; 02480 DocView::SetPrevZoomScale 02481 ********************************************************************************************/ 02482 02483 MsgResult OpZoomPrevZoomDescriptor::HandleButtonMsg(DialogOp*, CGadgetID) 02484 { 02485 // Just call the DoZoom operator but with 0 as we have no valid operation 02486 return DoZoom(0) ? OK : FAIL; 02487 } 02488 02489 02490 02492 // class OpZoomComboDescriptor 02493 02494 /******************************************************************************************** 02495 > OpZoomComboDescriptor::OpZoomComboDescriptor() 02496 02497 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02498 Created: 26/5/94 02499 Inputs: - 02500 Outputs: - 02501 Returns: - 02502 Purpose: Constructs an OpDescriptor for the zoom control's combo-box, which 02503 contains a list of percentage zoom factors. 02504 Errors: - 02505 SeeAlso: class OpZoomDescriptor 02506 ********************************************************************************************/ 02507 02508 OpZoomComboDescriptor::OpZoomComboDescriptor() 02509 : OpZoomDescriptor(OPTOKEN_ZOOMCOMBO, _R(IDS_ZOOMCOMBOSTATUSTEXT), 0, _R(IDBBL_ZOOM_COMBO), _R(IDCB_ZOOM_COMBO_BOX), _R(IDCB_ZOOM_COMBO_BOX)) 02510 { 02511 02512 // Empty. 02513 } 02514 02515 02516 02517 /******************************************************************************************** 02518 > BOOL OpZoomComboDescriptor::IsAvailable() 02519 02520 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02521 Created: 20/7/94 02522 Inputs: - 02523 Outputs: - 02524 Returns: TRUE if the zoom combo is available for use, FALSE otherwise. 02525 Purpose: Checks if their is a "selected" DocView, if so you can use the zoom combo 02526 on it. 02527 Errors: - 02528 SeeAlso: OpZoom::GetState; OpZoomDescriptor::IsAvailable 02529 ********************************************************************************************/ 02530 02531 BOOL OpZoomComboDescriptor::IsAvailable() 02532 { 02533 return DocView::GetSelected() != 0; 02534 } 02535 02536 02537 02538 /******************************************************************************************** 02539 > virtual MsgResult OpZoomComboDescriptor::Message(Msg* pMsg) 02540 02541 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02542 Created: 26/5/94 02543 Inputs: pMsg a pointer to a kernel message to process 02544 Outputs: - 02545 Returns: A message result code (generally OK) 02546 Purpose: Despatches a message, if relevant to the appropriate handler for it, 02547 after "unpacking" it into a more useful form. 02548 Errors: - 02549 SeeAlso: OpZoomComboDescriptor::HandleViewChangeMsg; 02550 OpZoomComboDescriptor::HandleCreateMsg; 02551 OpZoomComboDescriptor::HandleSelectMsg; 02552 class DocViewMsg 02553 ********************************************************************************************/ 02554 02555 MsgResult OpZoomComboDescriptor::Message(Msg* pMsg) 02556 { 02557 // Does the message mean that something has happened to the DocView? 02558 if (MESSAGE_IS_A(pMsg, DocViewMsg)) 02559 { 02560 DocViewMsg* pViewMsg = (DocViewMsg*) pMsg; 02561 switch (pViewMsg->State) 02562 { 02563 case DocViewMsg::BORN: 02564 // Initialise our data in the DocView when it is constructed. 02565 pViewMsg->pDocView->SetZoomTableIndex(cDefaultZoomIndex); 02566 pViewMsg->pDocView->SetPrevZoomIndex(cUninitZoomIndex); 02567 return OK; 02568 02569 case DocViewMsg::SELCHANGED: 02570 // Handle the selected view changing. 02571 return HandleViewChangeMsg(pViewMsg->pNewDocView); 02572 02573 case DocViewMsg::SCALECHANGED: 02574 // Handle the scale being changed. Since it can be set to anything, 02575 // say that it is fractional so the field is updated properly. 02576 pViewMsg->pDocView->SetZoomTableIndex(cFractionalZoomIndex); 02577 return HandleViewChangeMsg(pViewMsg->pDocView); 02578 02579 default: 02580 // Ignore all other messages. 02581 return OK; 02582 } 02583 } 02584 02585 // If we have dropped down the combo-box - make sure it is upto date! 02586 if (MESSAGE_IS_A(pMsg, OpDescControlMsg)) 02587 { 02588 OpDescControlMsg* pOpDescControlMsg = (OpDescControlMsg*) pMsg; 02589 02590 if (pOpDescControlMsg->DlgMsg == DIM_LISTDROPPED) 02591 { 02592 if (DocView::GetCurrent() != 0) 02593 { 02594 // We really don't want the name gallery to have any effect on the zoom dropdown... 02595 // CreateDisplayScan().Scan(); 02596 Update(TRUE); 02597 } 02598 } 02599 } 02600 02601 // Check if the message is an OpDesc message. 02602 if (!MESSAGE_IS_A(pMsg, OpDescMsg)) return OK; 02603 02604 // Cast it into the correct type etc. 02605 OpDescMsg* pOpDescMsg = (OpDescMsg*) pMsg; 02606 02607 // Is it for us? 02608 if (pOpDescMsg->OpDesc != this) return OK; 02609 02610 02611 02612 // Process the message . . . 02613 if (MESSAGE_IS_A(pOpDescMsg, OpDescControlCreateMsg)) 02614 return HandleCreateMsg(pOpDescMsg->pDlgOp, pOpDescMsg->SetGadgetID); 02615 02616 // Let base class do the default. 02617 return OpZoomDescriptor::Message(pMsg); 02618 } 02619 02620 02621 02622 /******************************************************************************************** 02623 > MsgResult OpZoomComboDescriptor::HandleViewChangeMsg(DocView* pSelectedDocView) 02624 02625 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02626 Created: 26/5/94 02627 Inputs: pSelectedDocView points to the DocView that is now "selected", 02628 or 0 if there isn't a selected view. 02629 Returns: A message result code (always OK) 02630 Purpose: Updates the zoom control combo-box with the zoom factor of a DocView 02631 as the user moves from view to view. 02632 Errors: Out of memory 02633 SeeAlso: OpZoomComboDescriptor::UpdateComboWithViewScale; 02634 OpZoomComboDescriptor::Message 02635 ********************************************************************************************/ 02636 02637 MsgResult OpZoomComboDescriptor::HandleViewChangeMsg(DocView* pSelectedDocView) 02638 { 02639 #if !defined(EXCLUDE_FROM_RALPH) 02640 ZoomTool::InvalidateStatusText(); 02641 String_256 dummy; 02642 return (pSelectedDocView != 0 02643 // There is a new view, so set the combos to the scale factor. 02644 ? UpdateComboWithViewScale(pSelectedDocView) 02645 // There is no view, so blank the zoom combos. 02646 : UpdateAllCombos(&dummy)) 02647 ? OK : FAIL; 02648 #else 02649 return OK; 02650 #endif 02651 } 02652 02653 02654 02655 /******************************************************************************************** 02656 > BOOL OpZoomComboDescriptor::UpdateAllCombos(String_256* pStr) 02657 02658 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02659 Created: 26/5/94 02660 Inputs: pStr the text to be placed in all zoom combos 02661 Returns: TRUE if successful. 02662 Errors: Out of memory 02663 Purpose: Updates the zoom combo-box(es) with the given text. The function is 02664 complicated by design deficiencies in the Operation system! 02665 Errors: - 02666 SeeAlso: OpDescriptor::BuildGadgetList; DocView::GetZoomTableIndex 02667 ********************************************************************************************/ 02668 02669 BOOL OpZoomComboDescriptor::UpdateAllCombos(String_256* pStr) 02670 { 02671 #if !defined(EXCLUDE_FROM_RALPH) 02672 // We must set the combos to something! 02673 ERROR3IF(pStr == 0, "No parameter in OpZoomComboDescriptor::UpdateAllCombos"); 02674 02675 // Create a list for the dialogue manager to put gadget ID's on. 02676 List* pGadgetList = new List; 02677 ERRORIF(pGadgetList == 0, _R(IDE_NOMORE_MEMORY), FALSE); 02678 02679 // See if the dialogue manager can remember where its controls live, or even 02680 // what identifiers they possess . . . 02681 if (BuildGadgetList(pGadgetList)) 02682 { 02683 // Success. Walk the generated list 02684 ListItem* pListItem = pGadgetList->GetHead(); 02685 while (pListItem != 0) 02686 { 02687 // Set the edit field of each gadget (which according to Simon will all be 02688 // combo-boxes) to the given percentage text. 02689 GadgetListItem* pGadgetItem = (GadgetListItem*) pListItem; 02690 pGadgetItem->pDialogOp->SetStringGadgetValue(pGadgetItem->gidGadgetID, 02691 *pStr, 02692 FALSE, 02693 -1); 02694 02695 // This can be useful when bamboozled by the Operations system . . . 02696 /* TRACEUSER( "JustinF", _T("\t\tUpdating zoom combo at 0x%lX (GID# %lX)\n"), 02697 (UINT32) pGadgetItem, (UINT32) pGadgetItem->gidGadgetID); 02698 */ 02699 // Do the next control in the list, if any. 02700 pListItem = pGadgetList->GetNext(pListItem); 02701 } 02702 } 02703 /* else 02704 { 02705 // Something went wrong! 02706 TRACEUSER( "JustinF", _T("Couldn't build gadget list in ") 02707 "OpZoomComboDescriptor::UpdateAllCombos!\n"); 02708 } 02709 */ 02710 // Don't forget to delete the list afterwards! 02711 pGadgetList->DeleteAll(); 02712 delete pGadgetList; 02713 #endif 02714 02715 return TRUE; 02716 } 02717 02718 02719 02720 /******************************************************************************************** 02721 > BOOL OpZoomComboDescriptor::UpdateComboWithViewScale(DocView* pDocView) 02722 02723 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02724 Created: 26/5/94 02725 Inputs: pDocView the DocView whose zoom factor will appear in the 02726 zoom control's combo-box. 02727 Returns: TRUE if successful. 02728 Errors: Out of memory 02729 Purpose: Updates the combo-box with the DocView's current percentage zoom 02730 factor. This works even if there is more than one combo-box. The 02731 function is complicated by design deficiencies in the Operation system! 02732 Errors: - 02733 SeeAlso: OpDescriptor::BuildGadgetList; DocView::GetZoomTableIndex 02734 ********************************************************************************************/ 02735 02736 BOOL OpZoomComboDescriptor::UpdateComboWithViewScale(DocView* pDocView) 02737 { 02738 // Get the DocView's scale percentage. If it's -1 then we must calculate the 02739 // percentage from the raw scale factor, otherwise we can look it up. 02740 INT32 nScalePercent; 02741 String_256 txt; 02742 02743 if (pDocView) 02744 { 02745 INT32 nTableIndex = pDocView->GetZoomTableIndex(); 02746 if (nTableIndex == cUninitZoomIndex) 02747 { 02748 // This value is set by DocView's constructor, and means that the view has not 02749 // been given a ZoomTableIndex yet. Give it the default, ie. 100%. 02750 pDocView->SetZoomTableIndex(nTableIndex = cDefaultZoomIndex); 02751 nScalePercent = OpZoom::GetPresetZoomPercent(nTableIndex); 02752 } 02753 else if (nTableIndex == cFractionalZoomIndex) 02754 { 02755 // Convert from a fixed16 scale factor to a percentage. This must be rounded 02756 // to the nearest percent. 02757 nScalePercent = ((pDocView->GetViewScale() * 100) + FIXED16_DBL(0.5)).MakeInt(); 02758 } 02759 else 02760 { 02761 nScalePercent = OpZoom::GetPresetZoomPercent(nTableIndex); 02762 } 02763 02764 // Convert the percentage to a formatted text string. 02765 txt.MakeMsg(_R(IDS_ZOOM_INFO_FORMAT), nScalePercent); 02766 } 02767 02768 // Update all existing zoom combos with the text. 02769 return UpdateAllCombos(&txt); 02770 } 02771 02772 02773 02774 /******************************************************************************************** 02775 > BOOL OpZoomComboDescriptor::RefreshList() 02776 02777 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02778 Created: 26/5/94 02779 Purpose: Fills the zoom control's combo-box with a list of percentage scale 02780 factors and set names, corresponding to those held in OpZoom::ZoomTable[] 02781 Returns: TRUE if successful. 02782 Errors: Out of memory 02783 SeeAlso: OpZoomComboDescriptor::Message; DialogOp::SetStringGadgetValue 02784 ********************************************************************************************/ 02785 02786 BOOL OpZoomComboDescriptor::RefreshList() 02787 { 02788 List* pList = new List; 02789 ERRORIF(pList == 0, _R(IDE_NOMORE_MEMORY), FALSE); 02790 02791 // See if the dialogue manager can remember where its controls live, or even 02792 // what identifiers they possess . . . 02793 if (BuildGadgetList(pList)) 02794 { 02795 // Success. Walk the generated list 02796 ListItem* pListItem = pList->GetHead(); 02797 while (pListItem != 0) 02798 { 02799 DialogOp* pBarOp = ((GadgetListItem*) pListItem)->pDialogOp; 02800 CGadgetID gid = ((GadgetListItem*) pListItem)->gidGadgetID; 02801 02802 // Start with a clean sheet. 02803 pBarOp->DeleteAllValues(gid); 02804 02805 // Set each percentage zoom factor at successive positions in the combo-box. 02806 String_256 txt; 02807 INT32 i; 02808 for (i = 0; i < cZoomTableSize; i++) 02809 { 02810 txt.MakeMsg(_R(IDS_ZOOM_INFO_FORMAT), OpZoom::GetPresetZoomPercent(i)); 02811 pBarOp->SetStringGadgetValue(gid, txt, FALSE, i); 02812 } 02813 02814 // Insert a divider so it all looks nice. 02815 String_256 strDivide(_R(IDS_ZOOM_COMBO_DIVIDER)); 02816 pBarOp->SetStringGadgetValue(gid, strDivide, FALSE, i++); 02817 02818 // Add the text commands after the percentages. 02819 txt.Load(_R(IDS_ZOOMSPREADCOMBOTEXT)); 02820 pBarOp->SetStringGadgetValue(gid, txt, FALSE, i++); 02821 txt.Load(_R(IDS_ZOOMDRAWINGCOMBOTEXT)); 02822 pBarOp->SetStringGadgetValue(gid, txt, FALSE, i++); 02823 02824 #ifndef STANDALONE 02825 txt.Load(_R(IDS_ZOOMSELECTEDCOMBOTEXT)); 02826 pBarOp->SetStringGadgetValue(gid, txt, FALSE, i++); 02827 #endif 02828 02829 txt.Load(_R(IDS_ZOOMPREVIOUSCOMBOTEXT)); 02830 pBarOp->SetStringGadgetValue(gid, txt, FALSE, i++); 02831 02832 // Set the required depth of the combo-box when it drops down. 02833 pBarOp->SetComboListLength(gid); 02834 02835 // Blank the string to start off with 02836 txt=_T(""); 02837 pBarOp->SetStringGadgetValue(gid, txt, FALSE, -1); 02838 02839 // Do the next control in the list, if any. 02840 pListItem = pList->GetNext(pListItem); 02841 } 02842 02843 pList->DeleteAll(); 02844 } 02845 02846 delete pList; 02847 return TRUE; 02848 } 02849 02850 02851 02852 /******************************************************************************************** 02853 > MsgResult OpZoomComboDescriptor::HandleCreateMsg(DialogOp* popdlgThis, 02854 CGadgetID gidThis) 02855 02856 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02857 Created: 26/5/94 02858 Inputs: popdlgThis points to a DialogOp (a control?) 02859 gidThis gadget ID of control 02860 Outputs: - 02861 Returns: A message result (always EAT_MSG) 02862 Purpose: Fills the zoom control's combo-box with a list of percentage scale 02863 factors, corresponding to those held in OpZoom::ZoomTable[] 02864 Errors: - 02865 SeeAlso: OpZoomComboDescriptor::Message; DialogOp::SetStringGadgetValue 02866 ********************************************************************************************/ 02867 02868 MsgResult OpZoomComboDescriptor::HandleCreateMsg(DialogOp* popdlgThis, CGadgetID gidThis) 02869 { 02870 #if !defined(EXCLUDE_FROM_RALPH) 02871 // Delegate delegate delegate! 02872 if (!RefreshList()) return FAIL; 02873 02874 // Make sure the visuals reflect all this. 02875 DocView* pDocView = DocView::GetCurrent(); 02876 if (pDocView != 0) UpdateComboWithViewScale(pDocView); 02877 #endif 02878 // Processed message successfully. 02879 return EAT_MSG; 02880 } 02881 02882 02883 02884 /******************************************************************************************** 02885 > void OpZoomComboDescriptor::OnSelectionChange(OpDescControlMsg* pCtrlMsg, 02886 List* pGadgetList) 02887 02888 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02889 Created: 18/7/94 02890 Inputs: pCtrlMsg --- pointer to the message from a control 02891 pGadgetList --- list of all gadgets associated with this OpDescriptor. 02892 Outputs: - 02893 Returns: - 02894 Purpose: Handles the user changing the selection, or typing text, in the zoom factor 02895 combo-box. Reads the selected text, checking for "%" or "x" which 02896 indicates a percentage zoom factor (absolute) or a multiplier (relative), 02897 converts to a number and performs the requested zoom on the selected 02898 view. 02899 Errors: - 02900 SeeAlso: OpZoomComboDescriptor::StringToLong; OpZoomDescriptor::FakeInvoke 02901 ********************************************************************************************/ 02902 02903 void OpZoomComboDescriptor::OnSelectionChange(OpDescControlMsg* pCtrlMsg, List*) 02904 { 02905 #if !defined(EXCLUDE_FROM_RALPH) 02906 // Check that we have reasonable input. 02907 ERROR3IF(pCtrlMsg == 0 || pCtrlMsg->pDlgOp == 0, 02908 "No OpDescriptor message in OpZoomComboDescriptor::OnSelectionChange"); 02909 if (pCtrlMsg == 0 || pCtrlMsg->pDlgOp == 0) return; 02910 02911 // Get the selected DocView etc. 02912 DocView* pDocView = DocView::GetCurrent(); 02913 ERROR3IF(pDocView == 0, 02914 "No current DocView in OpZoomComboDescriptor::OnSelectionChange"); 02915 if (pDocView == 0) return; 02916 02917 // If the selected text is actually one of the zoom commands, eg. "(Fit to) Spread", 02918 // then dispatch that to the appropriate handler. 02919 WORD wComboIndex; 02920 pCtrlMsg->pDlgOp->GetValueIndex(pCtrlMsg->SetGadgetID, &wComboIndex); 02921 INT32 nComboIndex = (short) wComboIndex; 02922 switch (nComboIndex) 02923 { 02924 case cFitToSpreadIndex: 02925 FakeInvoke(OPTOKEN_ZOOMSPREAD); 02926 return; 02927 02928 case cFitToDrawingIndex: 02929 FakeInvoke(OPTOKEN_ZOOMDRAWING); 02930 return; 02931 02932 case cFitToSelectedIndex: 02933 FakeInvoke(OPTOKEN_ZOOMSELECTED); 02934 return; 02935 02936 case cPreviousZoomIndex: 02937 FakeInvoke(OPTOKEN_ZOOMPREV); 02938 return; 02939 02940 case cComboDivider1: 02941 case cComboDivider2: 02942 // Beep(); 02943 wxBell(); 02944 OpZoomComboDescriptor::Update(); 02945 return; 02946 02947 default: 02948 break; 02949 } 02950 02951 // Have we selected a set item from the list? 02952 // We really don't want the name gallery to have any effect on the zoom dropdown... 02953 /* INT32 n = nComboIndex - cComboDivider2; 02954 if (n > 0) 02955 { 02956 NameGallery *pNameGallery = NameGallery::Instance(); 02957 if (pNameGallery) 02958 { 02959 SGUsedNames* pUsedNames = pNameGallery->GetUsedNames(); 02960 if (pUsedNames != 0) 02961 { 02962 SGNameItem* pItem = (SGNameItem*) pUsedNames->GetChild(); 02963 if (pItem != 0) 02964 { 02965 for (; pItem != 0; pItem = (SGNameItem*) pItem->GetNext()) 02966 if (!pItem->GetSetBounds().IsEmpty() && --n == 0) 02967 { 02968 // Extract the bounds of the chosen set and zoom to them. 02969 ERROR3IF(!pItem->GetSetBounds().IsValid(), 02970 "OpZoomComboDescriptor::OnSelectionChange: invalid bounds"); 02971 OpZoomDescriptor::FakeZoomToRect(pItem->GetSetBounds()); 02972 return; 02973 } 02974 02975 Beep(); 02976 ERROR3("OpZoomComboDescriptor::OnSelectionChange: can't find SGNameItem"); 02977 return; 02978 } 02979 } 02980 } 02981 } 02982 */ 02983 02984 // Extract the highlighted text. We pass a pointer to our "StringToLong" function 02985 // that knows how to extract a zoom factor from the user's input. 02986 BOOL bIsValid; 02987 INT32 nPercent = pCtrlMsg->pDlgOp->GetLongGadgetValue(pCtrlMsg->SetGadgetID, 02988 INT32_MIN, INT32_MAX, 02989 _R(IDE_INVALIDZOOMFACTOR), 02990 &bIsValid, StringToLong); 02991 02992 // Check if the input is valid. If it isn't then reset the result. The 02993 // GetStringGadgetValue will have reported the error if the input isn't valid. 02994 if (!bIsValid) 02995 { 02996 UpdateComboWithViewScale(pDocView); 02997 return; 02998 } 02999 03000 // If the returned value is negative it represents a "multiplier", which must 03001 // first be converted to a percentage. 03002 if (nPercent < 0) 03003 { 03004 INT32 nIndex = pDocView->GetZoomTableIndex(); 03005 if (nIndex == cFractionalZoomIndex) 03006 nPercent = -nPercent * ((pDocView->GetViewScale() * 100) + FIXED16(0.5)).MakeInt(); 03007 else 03008 nPercent = -nPercent * OpZoom::GetPresetZoomPercent(nIndex); 03009 03010 // If the zoom factor is larger than the permitted maximum then adjust it. 03011 INT32 nMaxPercent = OpZoom::GetPresetZoomPercent(0); 03012 if (nPercent > nMaxPercent) nPercent = nMaxPercent; 03013 } 03014 03015 // Begin by assuming the percentage isn't in the table. 03016 INT32 nIndex = cFractionalZoomIndex; 03017 03018 // Look for the percentage in the zoom factor table. 03019 for (INT32 i = 0; i < cZoomTableSize; i++) 03020 { 03021 if (OpZoom::GetPresetZoomPercent(i) == nPercent) 03022 { 03023 // Found the percentage in the table. 03024 nIndex = i; 03025 break; 03026 } 03027 } 03028 03029 // Try to create an OpZoom operation. 03030 OpZoom* pZoomOp = new OpZoom; 03031 if (pZoomOp == 0) 03032 { 03033 // We ran out of memory, so sorry. 03034 InformError(_R(IDE_NOMORE_MEMORY)); 03035 return; 03036 } 03037 03038 // Find the mid-point of the view, in work coordinates. 03039 WorkRect wrView = pDocView->GetViewRect(); 03040 WorkCoord wcMidView((wrView.lo.x + wrView.hi.x) / 2, 03041 (wrView.lo.y + wrView.hi.y) / 2); 03042 03043 // Ask the operation to zoom at this point. 03044 pDocView->SetZoomTableIndex(nIndex); 03045 pZoomOp->ZoomAtPoint(wcMidView, ((FIXED16) (INT32) nPercent) / 100); 03046 #endif 03047 } 03048 03049 03050 03051 /******************************************************************************************** 03052 > static BOOL OpZoomComboDescriptor::StringToLong(const StringBase& strIn, INT32* pnOut) 03053 03054 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03055 Created: 18/7/94 03056 Inputs: pstrIn --- pointer to the string containing text 03057 pnOut --- pointer to the number which will contain the result 03058 Outputs: - 03059 Returns: TRUE if the text is successfully parsed, FALSE otherwise. 03060 Purpose: Parses the text within the zoom factor combo-box, checking for a percentage 03061 factor ("%") or a multiplier factor ("x"), converting it to a number. 03062 Errors: - 03063 SeeAlso: OpZoomComboDescriptor::OnSelectionChange; DialogOp::GetLongGadgetValue 03064 ********************************************************************************************/ 03065 03066 BOOL OpZoomComboDescriptor::StringToLong(const StringBase& strIn, INT32* pnOut) 03067 { 03068 const StringBase * pstrIn = &strIn; 03069 ERROR2IF(pstrIn == 0 || pnOut == 0, FALSE, 03070 "No parameter(s) in OpZoomComboDescriptor::StringToLong"); 03071 03072 // Remove any leading or trailing whitespace. psczStart is set to point to first non- 03073 // whitespace character (or the terminating null), pszEnd points to the last. If the 03074 // string is entirely whitespace these two will cross over, and we return FALSE. 03075 const TCHAR* psczStart = (const TCHAR*) *pstrIn; 03076 const TCHAR* psczForward = psczStart; 03077 const TCHAR* psczBack = psczStart + pstrIn->Length() - 1; 03078 03079 while (StringBase::IsSpace(*psczForward)) 03080 psczForward = camStrinc(psczForward); 03081 03082 while (psczBack > psczForward && StringBase::IsSpace(*psczBack)) 03083 psczBack = camStrdec(psczStart, psczBack); 03084 03085 if (psczForward >= psczBack) return FALSE; 03086 03087 // Check if the string ends with a '%' or an 'x'. If it is an 'x' then the number 03088 // is a multipler, eg. "2 x" (two times). If it is a '%', or not there at all, 03089 // then it represents a percentage. 03090 BOOL bIsMultiplier = FALSE; 03091 if (*psczBack == TEXT('x') || *psczBack == TEXT('X')) 03092 { 03093 // Parse a multiplier. Skip over the 'x'. 03094 psczBack--; 03095 bIsMultiplier = TRUE; 03096 } 03097 else if (*psczBack == TEXT('%')) 03098 { 03099 // Parse a percentage. Skip over the '%' 03100 psczBack--; 03101 } 03102 else if (!StringBase::IsNumeric(*psczBack)) 03103 { 03104 // Can't recognise the format - not a number. 03105 return FALSE; 03106 } 03107 03108 // Make a working copy of what is left of the string. 03109 String_256 strWork; 03110 pstrIn->Mid(&strWork, (INT32) (psczForward - psczStart), 03111 (INT32) (psczBack - psczForward) + 1); 03112 03113 // Convert the remaining text into a number and return it. Percentages and 03114 // multipliers cannot be negative or zero (especially as multipliers are returned 03115 // back as negative to distinguish them from percentages). 03116 if (!Convert::StringToLong(strWork, pnOut) || *pnOut <= 0) return FALSE; 03117 03118 // Make sure it's within allowed bounds. 03119 INT32 nMaxPercent = OpZoom::GetPresetZoomPercent(0); 03120 INT32 nMinPercent = OpZoom::GetPresetZoomPercent(cZoomTableSize - 1); 03121 03122 if (*pnOut > nMaxPercent) *pnOut = nMaxPercent; 03123 if (*pnOut < nMinPercent && !bIsMultiplier) *pnOut = nMinPercent; 03124 if (bIsMultiplier) *pnOut = -(*pnOut); 03125 03126 return TRUE; 03127 } 03128 03129 03130 03131 /******************************************************************************************** 03132 > static BOOL OpZoomComboDescriptor::Update(BOOL fRefreshList = FALSE) 03133 03134 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03135 Created: 26/5/94 03136 Inputs: fRefreshList --- if TRUE then regenerate all items in the 03137 list (by default, just regenerate the item 03138 shown in the edit field). 03139 Purpose: Gets a pointer to the (one and only) OpZoomComboDescriptor in the 03140 system, and calls its member function UpdateComboWithViewScale for 03141 the "selected" DocView, if any. Available publicly to other zoom 03142 tool classes, to be called when they modify a DocView's zoom factor. 03143 Returns: FALSE if there's an error. 03144 Errors: Out of memory. 03145 SeeAlso: OpZoomComboDescriptor::UpdatecomboWithViewScale; 03146 OpDescriptor::FindOpDescriptor; DocView::GetSelected 03147 ********************************************************************************************/ 03148 03149 BOOL OpZoomComboDescriptor::Update(BOOL fRefreshList) 03150 { 03151 // Get the "selected" DocView, ie. the view that the user has made top-most. 03152 DocView* pDocView = DocView::GetCurrent(); 03153 ERROR3IF(pDocView == 0, "No current DocView in OpZoomComboDescriptor::Update"); 03154 if (pDocView == 0) return FALSE; 03155 03156 // WEBSTER - markn 15/1/97 03157 // No rulers in Webster 03158 #ifndef WEBSTER 03159 #if !defined(EXCLUDE_FROM_RALPH) 03160 // update the rulers after every scale change 03161 if (pDocView->GetpRulerPair()) pDocView->GetpRulerPair()->Update(); 03162 #endif 03163 #endif // WEBSTER 03164 03165 // Find the one and only OpZoomComboDescriptor object. 03166 OpDescriptor* popd = OpDescriptor::FindOpDescriptor(OPTOKEN_ZOOMCOMBO); 03167 ERROR3IF(popd == 0, "Can't find OpZoomComboDescriptor in " 03168 "OpZoomFitSelectedDescriptor::HandleButtonMsg"); 03169 if (popd == 0) return FALSE; 03170 03171 // Update it with values of the Selected DocView. 03172 OpZoomComboDescriptor* pCombo = (OpZoomComboDescriptor*) popd; 03173 if (fRefreshList && !pCombo->RefreshList()) return FALSE; 03174 return pCombo->UpdateComboWithViewScale(pDocView); 03175 03176 } 03177 03178 03179 #if !defined(EXCLUDE_FROM_RALPH) 03180 03182 // Classes ZoomInfoBarOp and ZoomInfoBarOpCreate. 03183 03184 /******************************************************************************************** 03185 > ZoomInfoBarOp::ZoomInfoBarOp() 03186 03187 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03188 Created: 15/3/95 03189 Inputs: - 03190 Outputs: - 03191 Returns: - 03192 Purpose: Constructs a zoom info-bar operation. 03193 Errors: - 03194 SeeAlso: - 03195 ********************************************************************************************/ 03196 #if 0 03197 ZoomInfoBarOp::ZoomInfoBarOp() 03198 : InformationBarOp(0) 03199 { 03200 // Empty. 03201 } 03202 #endif 03203 03204 03205 /******************************************************************************************** 03206 > virtual MsgResult ZoomInfoBarOp::Message(Msg* pMsg) 03207 03208 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03209 Created: 15/3/95 03210 Inputs: - 03211 Outputs: - 03212 Returns: The result of processing the message. 03213 Purpose: Handles a Camelot message for the zoom info-bar. 03214 Errors: - 03215 SeeAlso: DialogBarOp::Message 03216 ********************************************************************************************/ 03217 03218 MsgResult ZoomInfoBarOp::Message(Msg* pMsg) 03219 { 03220 // Pass on to base class for default handling. 03221 return DialogBarOp::Message(pMsg); 03222 } 03223 03224 03225 03226 /******************************************************************************************** 03227 > virtual DialogBarOp* ZoomInfoBarOpCreate::Create() 03228 03229 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03230 Created: 26/5/94 03231 Inputs: - 03232 Outputs: - 03233 Returns: A pointer to a DialogBarOp, which represents an info-bar. 03234 Purpose: Constructs a ZoomInfoBarOp (or derivative) on the heap and returns a 03235 pointer to it. Used internally by the info-bar system. 03236 Errors: - 03237 SeeAlso: class ZoomInfoBarOp; class InformationBarOp 03238 ********************************************************************************************/ 03239 03240 DialogBarOp* ZoomInfoBarOpCreate::Create() 03241 { 03242 return new ZoomInfoBarOp; 03243 } 03244 03245 #endif