00001 // $Id: zoomtool.cpp 1464 2006-07-18 12:32:26Z gerry $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // The Zoom Tool 00099 /* 00100 */ 00101 00102 #include "camtypes.h" 00103 00104 //#include "opdesc.h" 00105 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "stockcol.h" 00107 //#include "lineattr.h" 00108 //#include "ensure.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 //#include "resource.h" 00110 //#include "barsdlgs.h" 00111 //#include "errors.h" 00112 //#include "mario.h" 00113 //#include "viewrc.h" 00114 //#include "infobar.h" 00115 //#include "basestr.h" 00116 #include "csrstack.h" 00117 //#include "progress.h" 00118 #include "osrndrgn.h" 00119 //#include "mainfrm.h" 00120 //#include "winrect.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00121 #include "wrkrect.h" 00122 //#include "oilfiles.h" 00123 //#include "dlgmgr.h" 00124 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00125 //#include "app.h" 00126 //#include "range.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00127 //#include "justin.h" 00128 //#include "markn.h" 00129 //#include "blobs.h" 00130 #include "zoomtool.h" 00131 #include "zoomops.h" 00132 //#include "selector.h" // for SelectorTool::InflateByBlobBorder 00133 00134 #include "module.h" 00135 //#include "tool.h" 00136 //#include "zoomres.h" 00137 //#include "ezmodule.h" 00138 00139 //#include "will2.h" 00140 //#include "hotlink.h" 00141 //#include "userattr.h" 00142 //#include "ralphdoc.h" 00143 00144 DECLARE_SOURCE("$Revision: 1464 $"); 00145 00146 CC_IMPLEMENT_MEMDUMP(ZoomTool, Tool_v1) 00147 00148 // Declare smart memory handling in Debug builds 00149 #define new CAM_DEBUG_NEW 00150 00151 // ******************************************************* 00152 // MIN and MAX Macros - These should not be here, I'm sure 00153 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 00154 #define MAX(a, b) ((a) < (b) ? (b) : (a)) 00155 // ******************************************************* 00156 00157 00158 00160 // class ZoomTool 00161 00162 TCHAR *ZoomTool::FamilyName = _T("View Tools"); 00163 TCHAR *ZoomTool::ToolName = _T("Zoom Tool"); 00164 TCHAR *ZoomTool::Purpose = _T("To zoom in on a document"); 00165 TCHAR *ZoomTool::Author = _T("JustinF"); 00166 BOOL ZoomTool::bIsActive = FALSE; 00167 00168 00169 /******************************************************************************************** 00170 > ZoomTool::ZoomTool() 00171 00172 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00173 Created: 1/7/93 00174 Purpose: Dummy Constructor 00175 ********************************************************************************************/ 00176 00177 ZoomTool::ZoomTool() 00178 : Inited(FALSE), 00179 pcZoomCursor(NULL), 00180 pcZoomOutCursor(NULL), 00181 pZoomInfoBarOp(NULL), 00182 psStatusText(NULL), 00183 bStatusTextValid(FALSE) 00184 { 00185 // Empty. 00186 } 00187 00188 00189 00190 /******************************************************************************************** 00191 > virtual ZoomTool::~ZoomTool() 00192 00193 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00194 Created: 1/7/93 00195 Purpose: Destructor (Virtual) 00196 ********************************************************************************************/ 00197 00198 ZoomTool::~ZoomTool() 00199 { 00200 // Empty 00201 } 00202 00203 00204 00205 /******************************************************************************************** 00206 > virtual BOOL ZoomTool::Init() 00207 00208 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00209 Created: 4/5/94 00210 Returns: TRUE if the Zoom Tool initialised OK, FALSE otherwise. 00211 Purpose: To Test if the tool had started up ok 00212 Errors: Sends warning to debugging terminal if the info-bar can't be 00213 initialised. 00214 ********************************************************************************************/ 00215 00216 BOOL ZoomTool::Init() 00217 { 00218 // Don't initialise twice, dummy! 00219 if (Inited) return FALSE; 00220 Inited = TRUE; 00221 00222 #if defined(EXCLUDE_FROM_RALPH) 00223 return OpZoom::Declare(); 00224 #else 00225 pZoomInfoBarOp = new ZoomInfoBarOp(_R(IDD_ZOOMINFO)); 00226 BOOL ok=(pZoomInfoBarOp!=NULL) && OpZoom::Declare(); 00227 #if 0 00228 // Load in the info-bar stuff. 00229 CCResTextFile file; // Resource File 00230 ZoomInfoBarOpCreate BarCreate; // Object that creates ZoomInfoBarOp objects 00231 00232 // Register the OpDescriptors and THEN open the bar resource file! 00233 BOOL ok = OpZoom::Declare() && file.open(_R(IDM_ZOOM_BAR), _R(IDT_INFO_BAR_RES)); 00234 if (ok) ok = DialogBarOp::ReadBarsFromFile(file, BarCreate); // Read & create bar 00235 if (ok) file.close(); // Close resource 00236 00237 ENSURE(ok, "Unable to load ZOOMBAR.INI from resource\n"); 00238 00239 if (ok) 00240 { 00241 // Info bar now exists. Now get a pointer to it. 00242 String_32 str(_R(IDS_ZOOMTOOL_INFOBARNAME)); 00243 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str); 00244 00245 ok = (pDialogBarOp != NULL); 00246 if (ok) ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(ZoomInfoBarOp)); 00247 if (ok) pZoomInfoBarOp = (ZoomInfoBarOp*) pDialogBarOp; 00248 00249 ENSURE(ok, "Couldn't find zoom tool info bar"); 00250 } 00251 #endif 00252 return ok; 00253 #endif 00254 } 00255 00256 00257 00258 /******************************************************************************************** 00259 > virtual void ZoomTool::Describe(void* InfoPtr) 00260 00261 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00262 Created: 8/7/93 00263 Inputs: InfoPtr - Pointer to a block that will hold the name data 00264 Purpose: The tool declares what versions of the tool module interface it 00265 can understand as well as its name, family etc 00266 ********************************************************************************************/ 00267 00268 void ZoomTool::Describe(void* InfoPtr) 00269 { 00270 // Cast structure into the latest one we understand. 00271 ToolInfo_v1* Info = (ToolInfo_v1*) InfoPtr; 00272 Info->InfoVersion = 1; 00273 00274 // You should always have this line. 00275 Info->InterfaceVersion = GetToolInterfaceVersion(); 00276 00277 // These are all arbitrary at present. 00278 Info->Version = 1; 00279 Info->ID = GetID(); 00280 Info->TextID = _R(IDS_ZOOM_TOOL); 00281 00282 // Make a note of the tools description. 00283 Info->Family = FamilyName; 00284 Info->Name = ToolName; 00285 Info->Purpose = Purpose; 00286 Info->Author = Author; 00287 00288 // this tool uses the infobar, so supply a dialog id to put in the info bar. 00289 Info->InfoBarDialog = _R(IDD_ZOOMINFO); 00290 Info->BubbleID = _R(IDBBL_ZOOM_TOOLICON); 00291 } 00292 00293 00294 00295 /******************************************************************************************** 00296 > virtual UINT32 ZoomTool::GetID() 00297 00298 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00299 Created: 12/5/94 00300 Inputs: - 00301 Outputs: - 00302 Returns: - 00303 Purpose: 00304 Errors: - 00305 SeeAlso: - 00306 ********************************************************************************************/ 00307 00308 UINT32 ZoomTool::GetID() 00309 { 00310 return TOOLID_ZOOM; 00311 } 00312 00313 00314 00315 /******************************************************************************************** 00316 > virtual void ZoomTool::SelectChange(BOOL fIsSelected) 00317 00318 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00319 Created: 23/11/93 00320 Inputs: isSelected - TRUE if the tool is becoming selected 00321 Purpose: Called when the tool is selected or deselected. Creates and pushes the 00322 tool's cursor; pops and destroys it. 00323 Errors: Sends warning to debugging terminal if creating the cursor fails. 00324 SeeAlso: ZoomTool::IsSelectedTool 00325 ********************************************************************************************/ 00326 00327 void ZoomTool::SelectChange(BOOL fIsSelected) 00328 { 00329 if (fIsSelected) 00330 { 00331 // This tool has just been selected. Set the internal global flag so this 00332 // can be easily checked. 00333 bIsActive = TRUE; 00334 // TRACEUSER( "JustinF", _T("===================================== into ZOOM TOOL\n")); 00335 00336 // Try to load our cursors. 00337 pcZoomCursor = new Cursor(this, _R(IDC_ZOOMTOOLCURSOR)); 00338 pcZoomOutCursor = new Cursor(this, _R(IDC_ZOOMOUTTOOLCURSOR)); 00339 00340 #ifdef RALPH 00341 //Graham 20/9/96. This cursor is needed to activate 00342 //HotLinks (TM) in Ralph (TM). The cursor is a static member of 00343 //the Cursor class and so we don't need to delete it. 00344 pcHotLinkCursor = Cursor::PointingHand; 00345 #endif //Ralph 00346 00347 if (pcZoomCursor == NULL || !pcZoomCursor->IsValid()) 00348 return; 00349 00350 // Push cursor, but don't display now. 00351 CurrentCursorID = CursorStack::GPush(pcZoomCursor, FALSE); 00352 00353 #if !defined(EXCLUDE_FROM_RALPH) 00354 // Show the info-bar. 00355 pZoomInfoBarOp->Create(); 00356 #endif 00357 00358 // Allocate the string used for status-bar text, if necessary. 00359 // Graham 7/9/96: We now do this in Ralph too. 00360 00361 if (psStatusText == NULL) 00362 { 00363 psStatusText = new String_256; 00364 #ifdef _DEBUG 00365 if (psStatusText == NULL) 00366 TRACE( _T("Couldn't allocate a String for zoom tool status bar text!\n") ); 00367 #endif 00368 bStatusTextValid = FALSE; 00369 } 00370 00371 00372 // Which blobs do I want displayed? 00373 // Used to declare an interest in no blobs which meant that all blobs disappeared 00374 // when this tool is selected. Now try not to affect this by not declaring an 00375 // interest. 00376 // Changed by Neville 16/8/94 00377 // BlobManager* BlobMgr = GetApplication()->GetBlobManager(); 00378 // if ((BlobMgr != NULL) && (Document::GetCurrent() != NULL)) 00379 // { 00380 // // Decide which blobs to display 00381 // BlobStyle MyBlobs; 00382 // 00383 // // We want them all off, which is the default 00384 // // tell the blob manager 00385 // BlobMgr->ToolInterest(MyBlobs); 00386 // } 00387 } 00388 else 00389 { 00390 // TRACEUSER( "JustinF", _T("------------------------------------- out of ZOOM TOOL\n")); 00391 00392 // No longer the selected tool. 00393 bIsActive = FALSE; 00394 00395 // Deselection - destroy the tool's cursor, if there is one. 00396 if (pcZoomCursor != NULL) 00397 { 00398 CursorStack::GPop(CurrentCursorID); 00399 delete pcZoomCursor; 00400 delete pcZoomOutCursor; 00401 CurrentCursorID = 0; 00402 } 00403 #if !defined(EXCLUDE_FROM_RALPH) 00404 // Hide the info-bar. 00405 pZoomInfoBarOp->Delete(); 00406 #endif 00407 00408 // Deallocate the status-bar text "mask". 00409 // Graham 7/9/96: And we now do this in Ralph too. 00410 delete psStatusText; 00411 psStatusText = NULL; 00412 00413 } 00414 } 00415 00416 00417 00418 /**************************************************************************** 00419 00420 > void ZoomTool::OnKeyPress(KeyPress* pKey) 00421 00422 Author: Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com> 00423 Created: 23/02/2004 00424 00425 Inputs: pKey - pointer to a KeyPress 00426 Purpose: 00427 00428 ****************************************************************************/ 00429 00430 BOOL ZoomTool::OnKeyPress(KeyPress* pKey) 00431 { 00432 // Find the current state of the "click" keyboard modifiers... 00433 ClickModifiers ClickMods = ClickModifiers::GetClickModifiers(); 00434 Cursor* pPointerShape = pcZoomCursor; 00435 00436 // if the shift key is pressed... 00437 if (ClickMods.Adjust && !ClickMods.Constrain && !ClickMods.Alternative1) 00438 { 00439 pPointerShape = pcZoomOutCursor; 00440 } 00441 00442 // only change if this cursor is different from the current cursor 00443 if (pPointerShape != MyCurrentCursor) 00444 { 00445 // set this cursor as the current cursor and immediately display it 00446 CursorStack::GSetTop(pPointerShape, CurrentCursorID); 00447 // remember this is our current cursor 00448 MyCurrentCursor = pPointerShape; 00449 } 00450 00451 // return FALSE so that the key press gets passed on (e.g. Space needs to be passed 00452 // on so that the "swap to selector tool" works. 00453 return FALSE; 00454 } 00455 00456 /******************************************************************************************** 00457 > virtual void ZoomTool::OnClick(DocCoord dcMousePos, ClickType ctype, 00458 ClickModifiers cmods, Spread* pMouseSpread) 00459 00460 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00461 Created: 23/4/95 00462 Inputs: dcMousePos - The Coords (in DocCoords) of the point where the mouse 00463 button was clicked. 00464 ctype - Describes the type of click that was detected. 00465 cmods - Indicates which buttons caused the click and which 00466 modifers were pressed at the same time. 00467 pMouseSpread - The spread that the click was on 00468 Returns: TRUE if it handled the Click, FALSE otherwise 00469 Purpose: Handle a mouse click and perform a zoom if needed. If we decided to 00470 do a zoom we first have to create an operation and a drag is started 00471 on it. If the user was just clicking on the window, then the drag 00472 will be very short lived and the operation will be able to detect 00473 that is was in reality just a click. Once the drag has been started 00474 our part of the program is complete and it is up to the operation to 00475 actually change the zoom factor and get the document to redraw. 00476 ********************************************************************************************/ 00477 00478 void ZoomTool::OnClick(DocCoord dcMousePos, ClickType ctype, 00479 ClickModifiers cmods, Spread* pMouseSpread) 00480 { 00481 // We only act on single clicks. 00482 if (ctype != CLICKTYPE_SINGLE) return; 00483 if (cmods.Menu) return; // Don't do anything if the user clicked the Menu button 00484 00485 #ifdef RALPH 00486 //Graham 20/9/96: If we're in Ralph, clicking on a Hot Link activates it. 00487 //The one exception to this rule is if CTRL or SHIFT is pressed, in which case 00488 //the tool acts as normal. 00489 00490 //That way CTRL acts as a "Don't activate Hot Links" key, and SHIFT-clicks 00491 //work as normal 00492 00493 //So, is CTRL or SHIFT pressed? 00494 if (!(cmods.Constrain) && !(cmods.Adjust)) 00495 { 00496 //No. Are we on a Hot Link? Let's try and find one. 00497 00498 //First, find a Hot Link 00499 00500 Node* pHotLinkNode= DocView::FindHotLinkNode(dcMousePos); 00501 00502 //If we've found one, go to that Hot Link 00503 if (pHotLinkNode) 00504 { 00505 DocView::GoToHotLink((AttrUser*) pHotLinkNode); 00506 return; 00507 } 00508 } 00509 00510 //If CTRL was pressed, or if we weren't over a Hot Link, we treat 00511 //the click as a normal Zoom click. Read on... 00512 00513 #endif //Ralph 00514 00515 // Try to make a zoom operation. 00516 OpZoom* pZoomOp = new OpZoom; 00517 if (pZoomOp == NULL) 00518 { 00519 // We're out of memory, so we can't do the operation. 00520 InformError(_R(IDE_NOMORE_MEMORY)); 00521 return; 00522 } 00523 00524 // If the click is with the adjust button we zoom out, otherwise we always start 00525 // a drag with a non-adjust click. If it turns out that the drag is insignificant 00526 // we will zoom in, ignoring the drag. 00527 if (cmods.Adjust) 00528 { 00529 DocView* pDocView = DocView::GetCurrent(); 00530 ERROR3IF(pDocView == NULL, "Null current DocView in ZoomTool::OnClick"); 00531 pZoomOp->ZoomOut(pDocView->GetClickWorkCoord()); 00532 } 00533 else 00534 { 00535 pZoomOp->DoDrag(pMouseSpread, dcMousePos, cmods); 00536 } 00537 } 00538 00539 00540 00541 /******************************************************************************************** 00542 > virtual void ZoomTool::OnMouseMove(DocCoord dcPoint, Spread* pSpread, ClickModifiers mods) 00543 00544 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 00545 Created: 23/11/94 00546 Inputs: (not used) ...except in Ralph (says Graham) 00547 Purpose: immediately updates status line text 00548 ********************************************************************************************/ 00549 00550 void ZoomTool::OnMouseMove(DocCoord dcPoint, Spread* pSpread, ClickModifiers mods) 00551 { 00552 #ifdef RALPH 00553 //Graham 20/9/96. 00554 //We need to check if the zoom tool's over a Hot Link. If it is, the cursor changes 00555 //to a pointing hand 00556 00557 //The one exception is if CTRL's pressed, in which case the cursor is the 00558 //normal Zoom cursor. 00559 00560 //First, try and find a node with a Hot Link 00561 AttrUser* pHotLinkNode= (AttrUser*) DocView::FindHotLinkNode(dcPoint); 00562 00563 if (pHotLinkNode && !(mods.Constrain) && !(mods.Adjust)) 00564 { 00565 //Yes. So change the cursor to a pointing hand 00566 ChangeCursor(Cursor::PointingHand); 00567 00568 //And now to update the status bar of the browser 00569 00570 //So first get a pointer to the document 00571 00572 //And a pointer to the Ralph document... 00573 Document* ThisDoc=Document::GetSelected(); 00574 RalphDocument* ThisRalphDoc=ThisDoc->GetRalphDoc(); 00575 00576 ERROR3IF(ThisRalphDoc==NULL, "DocView::OnMouseMoveWithNoTool has no Ralph Doc"); 00577 00578 //Then get the base URL of this Ralph document as a Web Address 00579 WebAddress wBase(ThisRalphDoc->GetBaseURL()); 00580 00581 //And get the URL of this node as a Web Address 00582 WebAddress wEmbedded(pHotLinkNode->GetWebAddress()); 00583 00584 //This function makes wEmbedded into an absolute URL (if necessary) 00585 wEmbedded.Combine(wBase); 00586 00587 //Make the Web Address into a normal string 00588 String_256 strEmbedded=wEmbedded.GetWebAddress(); 00589 00590 //Now get the full status bar string and put the URL into it 00591 String_256 sZoomTool; 00592 00593 sZoomTool.MakeMsg(_R(IDS_ZOOMTOOL_HOTLINK), (TCHAR*) strEmbedded); 00594 00595 //And tell the Ralph document to show the string in the browser's status 00596 //bar 00597 ThisRalphDoc->SetStatusBar(&sZoomTool); 00598 } 00599 else 00600 { 00601 //No, the cursor is not over a Hot Link 00602 //Change the cursor to the standard selector-style "arrow" 00603 ChangeCursor(pcZoomCursor); 00604 00605 //And get the status bar text 00606 ValidateStatusText(); 00607 if (psStatusText) DocView::SetBrowserStatusBar(psStatusText); 00608 00609 } 00610 #else 00611 00612 //If we're in Camelot rather than Ralph 00613 00614 ValidateStatusText(); 00615 00616 if (psStatusText) GetApplication()->UpdateStatusBarText(psStatusText); 00617 #endif //Ralph 00618 00619 } 00620 00621 /******************************************************************************************** 00622 > void ZoomTool::ValidateStatusText(); 00623 00624 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00625 Created: 24/6/95 00626 Outputs: validates string pointed to by psStatusText 00627 Purpose: Checks if the text in the status-bar needs updating, for example if a new 00628 zoom factor has been selected since it was last painted, and does what is 00629 required. 00630 00631 Graham 7/9/96: We now get status line text in Ralph too. 00632 ********************************************************************************************/ 00633 00634 void ZoomTool::ValidateStatusText() 00635 { 00636 // If there is some status text to update ... 00637 if (psStatusText == NULL) return; 00638 00639 #ifndef RALPH 00640 // If the zoom factor has not changed since we last created the string ... 00641 // Graham 7/10/96: In Ralph, we assume the status bar text is always invalid 00642 if (bStatusTextValid) return; 00643 #endif 00644 00645 // Get the selected DocView, if any. 00646 DocView* pDocView = DocView::GetSelected(); 00647 if (pDocView == NULL) return; 00648 00649 // Get the view's index into the zoom table, if initialised. 00650 INT32 nIndex = DocView::GetSelected()->GetZoomTableIndex(); 00651 if (nIndex == cUninitZoomIndex) return; 00652 00653 // Check if we have a 'fractional' zoom index that is equivalent to a preset 00654 // zoom factor. If we have then convert it now to the equivalent preset, as 00655 // it makes the logic simpler, if slightly slower. 00656 INT32 nFracPercent = (pDocView->GetViewScale() * 100 + FIXED16_DBL(0.5)).MakeInt(); 00657 if (nIndex == cFractionalZoomIndex) 00658 { 00659 // Convert the fractional index into a percentage. 00660 for (INT32 i = 0; i < cZoomTableSize; i++) 00661 { 00662 // If it's the same is the preset set it to the preset. 00663 if (nFracPercent == OpZoom::GetPresetZoomPercent(i)) 00664 { 00665 pDocView->SetZoomTableIndex(nIndex = i); 00666 break; 00667 } 00668 } 00669 } 00670 00671 // Work out what percentages we get if we zoom in and zoom out from the current zoom 00672 // factor. If we are at the maximum or minimum zoom we note this here as well. 00673 INT32 nInPercent, nOutPercent; 00674 if (nIndex != cFractionalZoomIndex) 00675 { 00676 // Handle a zoom factor that appears in the zoom table. 00677 if (nIndex == 0) 00678 { 00679 // Can't zoom in any further. Use the special code for that, a 0% zoom. 00680 nInPercent = 0; 00681 nOutPercent = OpZoom::GetPresetZoomPercent(1); 00682 } 00683 else if (nIndex == cZoomTableSize - 1) 00684 { 00685 // Can't zoom out any further. 00686 nInPercent = OpZoom::GetPresetZoomPercent(cZoomTableSize - 2); 00687 nOutPercent = 0; 00688 } 00689 else 00690 { 00691 // The in/out factors are the next and previous presets. 00692 nInPercent = OpZoom::GetPresetZoomPercent(nIndex - 1); 00693 nOutPercent = OpZoom::GetPresetZoomPercent(nIndex + 1); 00694 } 00695 } 00696 else 00697 { 00698 // Handle a zoom factor that doesn't appear in the zoom table. 00699 // Search the zoom factor table looking for two consequetive entries that 00700 // bracket the current percentage. 00701 INT32 i; 00702 for (i = 0; i < cZoomTableSize; i++) 00703 if (nFracPercent > OpZoom::GetPresetZoomPercent(i)) break; 00704 00705 // Convert the found bounds into "in" and "out" percentages. 00706 if (i == 0) 00707 { 00708 // Can't zoom in any further, and more than the maximum preset. 00709 nInPercent = 0; 00710 nOutPercent = OpZoom::GetPresetZoomPercent(0); 00711 } 00712 else if (i == cZoomTableSize) 00713 { 00714 // Can't zoom out any further, and less than the minimum preset. 00715 nInPercent = OpZoom::GetPresetZoomPercent(cZoomTableSize - 1); 00716 nOutPercent = 0; 00717 } 00718 else 00719 { 00720 // Current zoom percentage lies within the bounds of the table. 00721 nInPercent = OpZoom::GetPresetZoomPercent(i - 1); 00722 nOutPercent = OpZoom::GetPresetZoomPercent(i); 00723 } 00724 } 00725 00726 #ifdef RALPH 00727 //Graham 7/9/96: In Ralph, the status bar text only refers to the current zoom 00728 psStatusText->Empty(); 00729 00730 String_256 s; 00731 s.MakeMsg(_R(IDS_RALPH_ZOOMTOOLSTR), nFracPercent); 00732 *psStatusText+=s; 00733 00734 #else 00735 // (Re)create the status-bar text string from the two string-sub masks. 00736 psStatusText->Empty(); 00737 if (nInPercent != 0) psStatusText->MakeMsg(_R(IDS_STATUS_ZOOM_IN_MASK), nInPercent); 00738 if (nOutPercent != 0) 00739 { 00740 String_256 s; 00741 s.MakeMsg(_R(IDS_STATUS_ZOOM_OUT_MASK), nOutPercent); 00742 *psStatusText += s; 00743 } 00744 00745 // Append some text about dragging. 00746 *psStatusText += String_256(_R(IDS_STATUS_ZOOM_DRAG_TEXT)); 00747 00748 // Mark the status-bar text as now valid. 00749 bStatusTextValid = TRUE; 00750 #endif //Ralph 00751 } 00752 00753 00754 /***************************************************************************** 00755 > virtual BOOL ZoomTool::GetStatusLineText(String_256* ptext, Spread* pSpread, 00756 DocCoord DocPos, ClickModifiers ClickMods); 00757 00758 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 00759 Created: 23/11/94 00760 Inputs: pSpread - pointer to spread under mouse (else NULL) 00761 DocPos - position of mouse in doc (in spread coords) 00762 ClickMods - mouse click modifiers 00763 Outputs: ptext - text for status line 00764 Returns: TRUE if outputting valid text 00765 Purpose: generate up-to-date text for the status line (called on idles) 00766 *****************************************************************************/ 00767 00768 BOOL ZoomTool::GetStatusLineText(String_256* ptext, Spread*, DocCoord, ClickModifiers) 00769 { 00770 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00771 ERROR3IF(ptext==NULL,"ZoomTool::GetStatusLineText() - ptext passed as null"); 00772 00773 ValidateStatusText(); 00774 if (psStatusText==NULL) return FALSE; 00775 00776 *ptext=*psStatusText; 00777 return TRUE; 00778 #else 00779 return FALSE; 00780 #endif 00781 } 00782 00783 00784 /******************************************************************************************** 00785 > static BOOL ZoomTool::IsSelectedTool() 00786 00787 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00788 Created: 28/6/94 00789 Inputs: - 00790 Outputs: - 00791 Returns: TRUE if the zoom tool is the currently active ("selected") tool. 00792 Purpose: 00793 Errors: - 00794 SeeAlso: ZoomTool::SelectChange 00795 ********************************************************************************************/ 00796 00797 BOOL ZoomTool::IsSelectedTool() 00798 { 00799 return bIsActive; 00800 } 00801 00802 00803 00804 /******************************************************************************************** 00805 > static void ZoomTool::InvalidateStatusText() 00806 00807 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00808 Created: 28/6/94 00809 Inputs: - 00810 Outputs: - 00811 Returns: - 00812 Purpose: Checks if the zoom tool is the currently active ("selected") tool, and if 00813 it is then "invalidates" the status-bar text, forcing it to be updated on 00814 receipt of the next call to OnMouseMove 00815 Errors: - 00816 SeeAlso: ZoomTool::OnMouseMove 00817 ********************************************************************************************/ 00818 00819 void ZoomTool::InvalidateStatusText() 00820 { 00821 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00822 // If we are the current tool and have a status-bar text string, then "invalidate" it. 00823 if (IsSelectedTool()) 00824 { 00825 ZoomTool* pTool = (ZoomTool*) Tool::GetCurrent(); 00826 ENSURE(pTool != NULL, "Null current Tool* in ZoomTool::InvalidateStatusText"); 00827 if (pTool->psStatusText != NULL) pTool->bStatusTextValid = FALSE; 00828 } 00829 #endif 00830 } 00831 00832 #ifdef RALPH 00833 /******************************************************************************************** 00834 00835 > void ZoomTool::ChangeCursor(Cursor* cursor) 00836 00837 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>, from Jim's code 00838 Created: 20/9/96 00839 Inputs: ID of the cursor you want to flip to 00840 Outputs: - 00841 Returns: - 00842 Purpose: We only need this in Ralph (at present), where the zoom tool cursor 00843 sometimes changes to a pointing hand, which is used to activate Hot Links. 00844 00845 Changes to the specified cursor. Will only change the cursor if it isn't already 00846 this cursor, so it doesn't flicker. 00847 00848 Errors: can fail if the cursor cannot be created - the cursor code will fail. 00849 SeeAlso: - 00850 00851 ********************************************************************************************/ 00852 00853 void ZoomTool::ChangeCursor(Cursor* cursor) 00854 { 00855 // only change if this cursor is different from the current cursor 00856 if (cursor != MyCurrentCursor) 00857 { 00858 // set this cursor as the current cursor and immediately display it 00859 CursorStack::GSetTop(cursor, CurrentCursorID); 00860 // remember this is our current cursor 00861 MyCurrentCursor = cursor; 00862 } 00863 } 00864 00865 /******************************************************************************************** 00866 00867 > void ZoomTool::OnKeyPress(KeyPress* pKey) 00868 00869 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 00870 Created: 20/9/96 00871 Inputs: Keypress object 00872 Outputs: - 00873 Returns: - 00874 Purpose: When a key is pressed, we call the Mouse Move function to update the 00875 cursor and status bar text. 00876 00877 00878 ********************************************************************************************/ 00879 /* 00880 BOOL ZoomTool::OnKeyPress(KeyPress* pKey) 00881 { 00882 //First get the current click modifiers, pointer position and spread 00883 ClickModifiers ClickMods = ClickModifiers::GetClickModifiers(); 00884 00885 Spread* pSpread; 00886 DocCoord dcMousePos; 00887 if (DocView::GetCurrentMousePos(&pSpread, &dcMousePos)) 00888 OnMouseMove(dcMousePos, pSpread, ClickMods); 00889 00890 return TRUE; 00891 } 00892 */ 00893 #endif //Ralph 00894 00895 // These lines make this a stand-alone DLL when required. 00896 /* 00897 IMPLEMENT_SIMPLE_MODULE(ZoomModule, 00898 MODULEID_ZOOM, 00899 ZoomTool, 00900 "Zoom Tool", 00901 "To scale the view", 00902 "Camelot team"); 00903 */