00001 // $Id: docview.cpp 1729 2006-08-30 12:48:48Z luke $ 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 DocView.CPP - DocView class definition file. 00101 00102 This is the Camelot document viewer object. 00103 00104 ********************************************************************************************/ 00105 00106 #include "camtypes.h" 00107 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 #include "camview.h" 00109 #include "vstate.h" 00110 #include "wrkrect.h" 00111 //#include "tool.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 #include "toollist.h" 00113 //#include "monotime.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00114 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 #include "osrndrgn.h" 00116 #include "grndrgn.h" 00117 #include "paper.h" 00118 //#include "oilcoord.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00119 //#include "doccoord.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00120 //#include "winrect.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00121 //#include "oilrect.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 //#include "errors.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00123 //#include "mario.h" 00124 //#include "will.h" 00125 #include "camelot.h" // For DisableSys flag 00126 #include "ccdc.h" 00127 #include "csrstack.h" 00128 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00129 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00130 #include "nodedoc.h" 00131 #include "chapter.h" 00132 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00133 #include "page.h" 00134 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00135 #include "blobs.h" 00136 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00137 #include "snap.h" 00138 //#include "progress.h" 00139 #include "lineattr.h" 00140 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00141 #include "nodepath.h" 00142 #include "nodeshap.h" 00143 #include "nodershp.h" 00144 //#include "dragcol.h" 00145 //#include "mainfrm.h" 00146 #include "zoomops.h" 00147 #include "viewmenu.h" 00148 #include "menuops.h" 00149 //#include "clikmods.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00150 #include "nodetext.h" 00151 #include "nodetxts.h" 00152 #include "rulers.h" 00153 #include "dlgmgr.h" 00154 //#include "bubbleid.h" 00155 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00156 #include "keypress.h" 00157 #include "nodebev.h" 00158 00159 // for shadow node hit-testing 00160 #include "nodecont.h" 00161 #include "nodeshad.h" 00162 #include "nbevcont.h" 00163 00164 #include "pushtool.h" // For OpPush 00165 //#include "bars.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00166 00167 #ifdef PHOTOSHOPPLUGINS 00168 #include "plugmngr.h" // CheckHaveDetailsOnPlugIns 00169 #endif //PHOTOSHOPPLUGINS 00170 00171 //#include "resource.h" // Matt 12/01/2001 - For _R(IDC_PUSHTOOLCURSOR) 00172 00173 #include "colplate.h" // For on-screen separated rendering 00174 00175 #include "rendwnd.h" // Shouldn't need this 00176 #include "draginfo.h" 00177 00178 DECLARE_SOURCE("$Revision: 1729 $"); 00179 00180 00181 // Used by SpreadRedraws class. 00182 #define MAX_REDRAW_REGIONS (20) 00183 00184 /******************************************************************************************** 00185 00186 > class SpreadRedraws : public ListItem 00187 00188 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00189 Created: 22/12/94 00190 Purpose: Encapsulates a set of regions on a spread, which must be accumulated in order 00191 for them to be redrawn at some point, possibly all in one go. This class 00192 chooses the most efficient invalidation method, according to the number 00193 and nature of regions added. 00194 SeeAlso: PendingRedraws 00195 00196 ********************************************************************************************/ 00197 00198 class SpreadRedraws : public ListItem 00199 { 00200 CC_DECLARE_MEMDUMP(SpreadRedraws); 00201 00202 public: 00203 SpreadRedraws(Spread*); 00204 00205 Spread *GetSpread() { return pInvalidSpread; } 00206 void AddInvalidRegion(DocRect, Node* pInvalidNode); 00207 void FlushRedraw(DocView*); 00208 void ClearBackmostChangedNode(Node* pNode); 00209 00210 private: 00211 Spread *pInvalidSpread; 00212 UINT32 RectCount; 00213 BOOL TooManyRegions; 00214 DocRect InvalidRegions[MAX_REDRAW_REGIONS]; 00215 Node* m_pBackmostChangedNode; 00216 }; 00217 00218 00219 00220 CC_IMPLEMENT_MEMDUMP(PendingRedraws, List) 00221 CC_IMPLEMENT_MEMDUMP(SpreadRedraws, ListItem) 00222 CC_IMPLEMENT_DYNAMIC(DocView, View) 00223 CC_IMPLEMENT_DYNAMIC(DocViewMsg, Msg) 00224 CC_IMPLEMENT_DYNCREATE(OpToggleFore, Operation) 00225 CC_IMPLEMENT_DYNCREATE(OpToggleScroll, Operation) 00226 CC_IMPLEMENT_DYNCREATE(OpToggleSolidDrag, Operation) 00227 00228 00229 #define new CAM_DEBUG_NEW 00230 00231 00232 00233 //-----------------------------------------------------------------------------------------// 00234 // Swap macro 00235 // this is too beautiful to work! (This is too obscure to be worth it!) 00236 00237 #define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b)) 00238 00239 00240 00241 // ******************************************************* 00242 // MIN and MAX Macros - These should not be here, I'm sure 00243 00244 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 00245 #define MAX(a, b) ((a) < (b) ? (b) : (a)) 00246 00247 // ******************************************************* 00248 00249 00250 00251 //-----------------------------------------------------------------------------------------// 00252 // Initialise class static variables... 00253 // 00254 DocView* DocView::Selected = NULL; 00255 00256 INT32 DocView::OnTopCount = 0; 00257 OnTopCode DocView::OnTopReason = Normal; 00258 Spread* DocView::OnTopSpread = NULL; 00259 RenderRegion* DocView::OnTopRenderRegion = NULL; 00260 00261 00262 /******************************************************************************************** 00263 00264 Preference: ConstrainAngle 00265 Section: Constraints 00266 Range: >0 ---> <2PI 00267 Purpose: This is the default angle to which angles are constrained to (eg when 00268 rotating with constrain on, it will only rotate in multiples of this 00269 constrain angle. It must be greater than zero degrees and less than 00270 360 degrees (note that it is recorded in radians). 00271 00272 ********************************************************************************************/ 00273 00274 double DocView::DefaultConstrainAngle = PI / 4.0; 00275 00276 00277 /******************************************************************************************** 00278 00279 Preference: BackgroundRendering 00280 Section: Rendering 00281 Range: 0 or 1 00282 Purpose: Defines whether or not to use background rendering on new views. 00283 0 => No background rendering 00284 1 => Use background rendering 00285 00286 ********************************************************************************************/ 00287 00288 BOOL DocView::BackgroundRendering = TRUE; 00289 00290 00291 //-----------------------------------------------------------------------------------------// 00292 00293 00294 00295 /******************************************************************************************** 00296 00297 Preference: SolidDragging 00298 Section: Dragging 00299 Range: 0 or 1 00300 Purpose: Defines whether or not solid dragging is enabled. 00301 0 => Solid dragging disabled 00302 1 => Solid dragging enabled 00303 00304 ********************************************************************************************/ 00305 00306 BOOL DocView::SolidDragging = TRUE; 00307 00308 00309 //-----------------------------------------------------------------------------------------// 00310 00311 00312 00313 /******************************************************************************************** 00314 00315 Preference: IdleDragDelay 00316 Section: Dragging 00317 Range: 0 to 10000 00318 Purpose: Defines delay time in milliseconds between detecting idle state and showing 00319 extra dragging info. 00320 00321 ********************************************************************************************/ 00322 00323 UINT32 DocView::IdleDragDelay = 200; 00324 00325 00326 //-----------------------------------------------------------------------------------------// 00327 00328 00329 00330 /******************************************************************************************** 00331 00332 Preference: IdleDragDelay2 00333 Section: Dragging 00334 Range: 0 to 10000 00335 Purpose: Defines delay time in milliseconds between detecting idle state and showing 00336 extra dragging info. 00337 00338 ********************************************************************************************/ 00339 00340 UINT32 DocView::IdleDragDelay2 = 1000; 00341 00342 00343 //-----------------------------------------------------------------------------------------// 00344 00345 00346 00347 /******************************************************************************************** 00348 00349 Preference: SolidDragTimeLimit 00350 Section: Dragging 00351 Range: 0 to 10000 00352 Purpose: Defines time limit in milliseconds for solid drag redraw. When redraw takes 00353 longer than this value, dragging falls back to outline mode 00354 00355 ********************************************************************************************/ 00356 00357 UINT32 DocView::SolidDragTimeLimit = 333; 00358 00359 00360 //-----------------------------------------------------------------------------------------// 00361 00362 00363 00364 /******************************************************************************************** 00365 00366 Preference: OriginOutlineShowNonOverlap 00367 Section: Dragging 00368 Range: 0 or 1 00369 Purpose: Original outlines will be shown as soon as dragged items don't overlap 00370 originals. 00371 00372 ********************************************************************************************/ 00373 00374 BOOL DocView::OriginOutlineShowNonOverlap = FALSE; 00375 00376 00377 //-----------------------------------------------------------------------------------------// 00378 00379 00380 00381 /******************************************************************************************** 00382 00383 Preference: OriginOutlineShowAlways 00384 Section: Dragging 00385 Range: 0 or 1 00386 Purpose: Original outlines will be shown as soon as dragged items don't overlap 00387 originals. 00388 00389 ********************************************************************************************/ 00390 00391 BOOL DocView::OriginOutlineShowAlways = FALSE; 00392 00393 00394 //-----------------------------------------------------------------------------------------// 00395 00396 00397 00398 /******************************************************************************************** 00399 00400 Preference: OutlineShowBounds 00401 Section: Dragging 00402 Range: 0 or 1 00403 Purpose: Dragged outlines will show a bounding rectangle. 00404 00405 ********************************************************************************************/ 00406 00407 BOOL DocView::OutlineShowBounds = TRUE; 00408 00409 00410 //-----------------------------------------------------------------------------------------// 00411 00412 00413 00414 /******************************************************************************************** 00415 00416 > SpreadRedraws::SpreadRedraws(Spread *pSpread) 00417 00418 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00419 Created: 22/12/94 00420 Inputs: pSpread - the spread on which invalid regions will occur. 00421 Purpose: Construct a spread redraw regions object for a given spread. The invalid 00422 region is initially NULL. 00423 SeeAlso: SpreadRedraws; PendingRedraws 00424 00425 ********************************************************************************************/ 00426 00427 SpreadRedraws::SpreadRedraws(Spread *pSpread) 00428 { 00429 pInvalidSpread = pSpread; 00430 RectCount = 0; 00431 TooManyRegions = FALSE; 00432 m_pBackmostChangedNode = NULL; 00433 } 00434 00435 /******************************************************************************************** 00436 00437 > void SpreadRedraws::AddInvalidRegion(DocRect Rect, Node* pInvalidNode) 00438 00439 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00440 Created: 22/12/94 00441 Inputs: Rect - the region to add (in document co-ordinates) 00442 Purpose: Add another invalid region to the collection of regions for a spread. 00443 SeeAlso: SpreadRedraws; PendingRedraws 00444 00445 ********************************************************************************************/ 00446 00447 void SpreadRedraws::AddInvalidRegion(DocRect Rect, Node* pInvalidNode) 00448 { 00449 if (pInvalidNode!=NULL) 00450 if (m_pBackmostChangedNode==NULL || pInvalidNode->IsUnder(m_pBackmostChangedNode)) m_pBackmostChangedNode = pInvalidNode; 00451 00452 if (TooManyRegions) 00453 { 00454 // We have exceeded the maximum number of inidividual regions, so we just 00455 // union them all together. 00456 InvalidRegions[0] = InvalidRegions[0].Union(Rect); 00457 } 00458 else 00459 { 00460 // Have we just exceeded the maximum number of regions? 00461 if (RectCount == MAX_REDRAW_REGIONS) 00462 { 00463 // Yes - gather all the existing regions together into one. 00464 for (INT32 i = 1; i < MAX_REDRAW_REGIONS; i++) 00465 { 00466 InvalidRegions[0] = InvalidRegions[0].Union(InvalidRegions[i]); 00467 } 00468 00469 // Now merge the new region in 00470 InvalidRegions[0] = InvalidRegions[0].Union(Rect); 00471 00472 // Indicate that we have too many regions 00473 RectCount = 1; 00474 TooManyRegions = TRUE; 00475 } 00476 else 00477 { 00478 // Otherwise, just add region to the array 00479 InvalidRegions[RectCount] = Rect; 00480 RectCount++; 00481 } 00482 } 00483 } 00484 00485 /******************************************************************************************** 00486 00487 > void SpreadRedraws::ClearBackMostChangedNode(Node* pNode) 00488 00489 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00490 Created: 22/12/94 00491 Inputs: Rect - the region to add (in document co-ordinates) 00492 Purpose: Add another invalid region to the collection of regions for a spread. 00493 SeeAlso: SpreadRedraws; PendingRedraws 00494 00495 ********************************************************************************************/ 00496 00497 void SpreadRedraws::ClearBackmostChangedNode(Node* pNode) 00498 { 00499 if (pNode && (m_pBackmostChangedNode==pNode || pNode->IsNodeInSubtree(m_pBackmostChangedNode))) 00500 m_pBackmostChangedNode = pNode->FindParentSpread(); 00501 } 00502 00503 /******************************************************************************************** 00504 00505 > void SpreadRedraws::FlushRedraw(DocView *pDocView) 00506 00507 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00508 Created: 22/12/94 00509 Inputs: pDocView - the DocView to invalidate 00510 Purpose: Force the specified DocView to immediately update all the regions 00511 encapsulated by this object. 00512 SeeAlso: SpreadRedraws; PendingRedraws 00513 00514 ********************************************************************************************/ 00515 00516 void SpreadRedraws::FlushRedraw(DocView *pDocView) 00517 { 00518 // Cause an immediate update of the DocView 00519 for (UINT32 i = 0; i < RectCount; i++) 00520 { 00521 // For the moment, assume that pending redraws must have been due to editing... 00522 pDocView->ForceRedraw(pInvalidSpread, InvalidRegions[i], FALSE, m_pBackmostChangedNode); 00523 } 00524 } 00525 00526 00527 /******************************************************************************************** 00528 00529 > PendingRedraws::PendingRedraws() 00530 00531 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00532 Created: 22/12/94 00533 Purpose: Initialise a PendingRedraws object. 00534 SeeAlso: SpreadRedraws; PendingRedraws 00535 00536 ********************************************************************************************/ 00537 00538 PendingRedraws::PendingRedraws() 00539 { 00540 } 00541 00542 00543 /******************************************************************************************** 00544 00545 > PendingRedraws::~PendingRedraws() 00546 00547 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00548 Created: 22/12/94 00549 Purpose: Destroys a PendingRedraws object. 00550 SeeAlso: SpreadRedraws; PendingRedraws 00551 00552 ********************************************************************************************/ 00553 00554 PendingRedraws::~PendingRedraws() 00555 { 00556 DeleteAll(); 00557 } 00558 00559 00560 /******************************************************************************************** 00561 00562 > BOOL PendingRedraws::AddInvalidRegion(Spread *pSpread, DocRect Rect, Node* pInvalidNode) 00563 00564 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00565 Created: 22/12/94 00566 Inputs: pSpread - the spread on which the invalid region is located. 00567 Rect - the invalid region (in document co-ordinates) 00568 Returns: TRUE if added ok; 00569 FALSE if not 00570 Purpose: Add another invalid region to the specified Spread's collection. 00571 Errors: Out of memory => ERROR1 00572 SeeAlso: SpreadRedraws; PendingRedraws 00573 00574 ********************************************************************************************/ 00575 00576 BOOL PendingRedraws::AddInvalidRegion(Spread *pSpread, DocRect Rect, Node* pInvalidNode) 00577 { 00578 // Look for this spread in our list 00579 SpreadRedraws *pItem = (SpreadRedraws *) GetHead(); 00580 00581 while ((pItem != NULL) && (pItem->GetSpread() != pSpread)) 00582 { 00583 // Nope - try next item 00584 pItem = (SpreadRedraws *) GetNext(pItem); 00585 } 00586 00587 if (pItem == NULL) 00588 { 00589 // No entry for the spread - we'd better make one 00590 pItem = new SpreadRedraws(pSpread); 00591 00592 // Did it work? 00593 if (pItem == NULL) 00594 return FALSE; 00595 00596 // Yes - add to the list 00597 AddTail(pItem); 00598 } 00599 00600 // Got an an entry for this spread - add the region 00601 pItem->AddInvalidRegion(Rect, pInvalidNode); 00602 00603 // All ok 00604 return TRUE; 00605 } 00606 00607 /******************************************************************************************** 00608 00609 > void PendingRedraws::FlushRedraw(DocView *pDocView) 00610 00611 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00612 Created: 22/12/94 00613 Inputs: pDocView - the DocView to invalidate. 00614 Purpose: Cause all pending update regions on all spreads for this DocView to be 00615 updated immediately. 00616 SeeAlso: SpreadRedraws; PendingRedraws 00617 00618 ********************************************************************************************/ 00619 00620 void PendingRedraws::FlushRedraw(DocView *pDocView) 00621 { 00622 // Invalidate the regions on each spread... 00623 SpreadRedraws *pItem = (SpreadRedraws *) GetHead(); 00624 00625 while (pItem != NULL) 00626 { 00627 // Invalid the regions on this spread, and delete this item 00628 pItem->FlushRedraw(pDocView); 00629 delete RemoveItem(pItem); 00630 00631 // Now try the next item... 00632 pItem = (SpreadRedraws *) GetHead(); 00633 } 00634 } 00635 00636 00637 /******************************************************************************************** 00638 00639 > void PendingRedraws::HanldeNodeDeletion(Node* pNode) 00640 00641 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00642 Created: 22/12/94 00643 Inputs: pDocView - the DocView to invalidate. 00644 Purpose: Cause all pending update regions on all spreads for this DocView to be 00645 updated immediately. 00646 SeeAlso: SpreadRedraws; PendingRedraws 00647 00648 ********************************************************************************************/ 00649 00650 void PendingRedraws::HandleNodeDeletion(Node* pNode) 00651 { 00652 // Invalidate the regions on each spread... 00653 SpreadRedraws *pItem = (SpreadRedraws *) GetHead(); 00654 00655 while (pItem != NULL) 00656 { 00657 pItem->ClearBackmostChangedNode(pNode); 00658 00659 // Now try the next item... 00660 pItem = (SpreadRedraws *) this->GetNext(pItem); 00661 } 00662 } 00663 00664 00665 /******************************************************************************************** 00666 00667 > static BOOL DocView::DeclarePreferences() 00668 00669 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 00670 Created: 19/10/94 00671 Returns: TRUE if it worked, FALSE if it failed 00672 Purpose: Declares any preferences that the DocView class needs to decalre 00673 00674 ********************************************************************************************/ 00675 00676 BOOL DocView::DeclarePreferences() 00677 { 00678 // NB. Constrain angle must be between 1 and 359 degrees. 00679 return GetApplication()->DeclareSection(TEXT("Constraints"), 1) 00680 && GetApplication()->DeclarePref(TEXT("Constraints"), TEXT("Constrain Angle"), 00681 &DefaultConstrainAngle, 00682 (2 * PI) / 360, ((2 * PI) * 359) / 360) 00683 00684 && GetApplication()->DeclareSection(TEXT("Rendering"), 2) 00685 && GetApplication()->DeclarePref(TEXT("Rendering"), TEXT("BackgroundRendering"), 00686 &BackgroundRendering, FALSE, TRUE) 00687 00688 && GetApplication()->DeclareSection(TEXT("AutoScrolling"), 1) 00689 && GetApplication()->DeclarePref(TEXT("AutoScrolling"), TEXT("ScrollToShowMargin"), 00690 &ScrollToShowMargin) 00691 00692 && GetApplication()->DeclareSection(TEXT("Dragging"), 6) 00693 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("SolidDragging"), 00694 &SolidDragging, FALSE, TRUE) 00695 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("IdleDragDelay"), 00696 (UINT32*)&IdleDragDelay, 0, 10000) 00697 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("IdleDragDelay2"), 00698 (UINT32*)&IdleDragDelay2, 0, 10000) 00699 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("SolidDragTimeLimit"), 00700 (UINT32*)&SolidDragTimeLimit, 0, 10000) 00701 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("OriginOutlineShowAlways"), 00702 &OriginOutlineShowAlways, FALSE, TRUE) 00703 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("OriginOutlineShowNonOverlap"), 00704 &OriginOutlineShowNonOverlap, FALSE, TRUE) 00705 && GetApplication()->DeclarePref(TEXT("Dragging"), TEXT("OutlineShowBounds"), 00706 &OutlineShowBounds, FALSE, TRUE); 00707 } 00708 00709 /******************************************************************************************** 00710 00711 > DocView::DocView() 00712 00713 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00714 Created: 12/5/93 00715 Inputs: Pointer to Document to which it belongs 00716 Outputs: None 00717 Returns: None 00718 Purpose: DocView class constructor 00719 A DocView object is usually created by the Document and is linked into a list 00720 of DocViews owned by the Document. So the DocView constructor takes and stores 00721 a pointer to the Document object so that it can get to it quickly. 00722 Errors: None 00723 00724 00725 ********************************************************************************************/ 00726 /* 00727 Technical notes: 00728 In debugging mode, constructor will assert that the Owner document pointer is not null. 00729 00730 ********************************************************************************************/ 00731 00732 DocView::DocView(Document* pOwnerDoc) : 00733 m_PushCursor( (Tool_v1*)NULL, _R(IDC_PUSHTOOLCURSOR) ) 00734 { 00735 // Set the flag that indicates if the view is dying or not. Make sure it is not dying 00736 IsViewDying = FALSE; 00737 00738 // Implementation... 00739 ERROR3IF( pOwnerDoc == NULL, "DocView has no Owner Document !!" ); 00740 00741 pDoc = pOwnerDoc; // Maintain link to Document which owns us 00742 pViewWindow = NULL; // Clear pointer to window 00743 pVState = NULL; 00744 PushToolCursorID = 0; // Matt 12/01/2001 - Ensure it is set to a sensible value at creation 00745 pCurrentDragOp = NULL; // we aren't dragging just yet 00746 Scale = 1.0; // Viewing scale = 1.00 00747 00748 ViewFlags.BackgroundRender = BackgroundRendering; // Use preference 00749 00750 ViewFlags.GridShow = FALSE; // Grid not shown 00751 ViewFlags.GridSnap = FALSE; // Grid not snapping 00752 ViewFlags.ObjectsSnap = FALSE; // All objects not snapping 00753 ViewFlags.MagObjectsSnap = FALSE; // Magnetic objects not snapping 00754 ViewFlags.PrintBorderShow = FALSE; // Print borders not shown 00755 ViewFlags.LogicalView = TRUE; // Chapters are shown one above the other 00756 ViewFlags.WorkClickCached = FALSE; // Haven't got a click cached 00757 ViewFlags.Dragging = FALSE; // We're not dragging anything 00758 ViewFlags.GuidesSnap = TRUE; // Not snapping to guides 00759 ViewFlags.GuidesShow = TRUE; // Show guides by default 00760 00761 // Get the default quality level 00762 RenderQuality = Quality::DefaultQuality; 00763 00764 // Initialise the snap object to NULL. This is set up in the Snap functions 00765 pCSnap = NULL; 00766 00767 // init pointer to rulers 00768 pRulerPair = NULL; 00769 00770 // make sure we don't prevent ourselves from rendering 00771 m_bPreventRenderView = FALSE; 00772 00773 // Setup solid dragging flags 00774 m_bSolidDragSupported = FALSE; 00775 m_bSolidDrag = FALSE; 00776 00777 // Make ourselves current. 00778 SetCurrent(); 00779 00780 // Broadcast a message to all that there's a new view on the block . . . 00781 BROADCAST_TO_ALL(DocViewMsg(this, DocViewMsg::BORN)); 00782 00783 } 00784 00785 00786 00787 /******************************************************************************************** 00788 > virtual DocView::~DocView() 00789 00790 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00791 Created: 12/5/93 00792 Inputs: None 00793 Outputs: None 00794 Returns: None 00795 Purpose: DocView class destructor 00796 Errors: None 00797 ********************************************************************************************/ 00798 00799 DocView::~DocView() 00800 { 00801 // delete the rulers (must be done first to prevent them receiving doc view dying messages) 00802 if(pRulerPair) 00803 { 00804 delete pRulerPair; 00805 } 00806 pRulerPair=NULL; 00807 00808 // Set the flag that indicates if the view is dying. 00809 IsViewDying = TRUE; 00810 00811 // Make sure that Current and Selected do not refer to the dying DocView 00812 if (this == Current) SetNoCurrent(); 00813 if (this == Selected) Document::SetNoSelectedViewAndSpread(); 00814 00815 Camelot.DeleteRenderRegions(this); 00816 00817 // Inform parent doc that we are about to die 00818 pDoc->OnDocViewDying(this); 00819 00820 // Bye bye to the ViewState object (DON'T deallocate - done by CCamView). 00821 pVState = NULL; 00822 00823 // If we have an attached CSnap object, junk it 00824 if (pCSnap != NULL) delete pCSnap; 00825 00826 // Broadcast to everyone that this view is a dead duck. 00827 BROADCAST_TO_ALL(DocViewMsg(this, DocViewMsg::KILLED)); 00828 } 00829 00830 00831 /******************************************************************************************** 00832 > BOOL DocView::Init() 00833 00834 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 00835 Created: 1/9/95 00836 Returns: FALSE if fails 00837 Purpose: Init a doc view 00838 ********************************************************************************************/ 00839 00840 BOOL DocView::Init() 00841 { 00842 pRulerPair = NULL; 00843 00844 pRulerPair = new RulerPair(); 00845 ERROR2IF(pRulerPair==NULL,FALSE,"DocView::Init() - failed to create RulerPair"); 00846 00847 // update indicator in StatusLine 00848 DialogBarOp::SetSystemStateChanged(); 00849 00850 return TRUE; 00851 } 00852 00853 /******************************************************************************************** 00854 00855 > DocView::ScrollToShowMargin 00856 00857 Author: Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com> 00858 Created: 3/6/1996 00859 Purpose: Margins to use (in millipoints) when autoscrolling with a margin 00860 00861 See Also: ScrollToShowWithMargin 00862 00863 ********************************************************************************************/ 00864 00865 UINT32 DocView::ScrollToShowMargin = 18000; // defaults to 1/4 inch 00866 00867 /******************************************************************************************** 00868 > BOOL DocView::SetScrollOffsets(WorkCoord NewTopLeft, BOOL RedrawNeeded = TRUE) 00869 00870 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 00871 Created: 6/7/93 00872 Inputs: New scroll offsets 00873 Flag to control whether redraw is needed or not 00874 Purpose: To scroll this view to a new position over the document. The coordinate 00875 supplied is the coordinate of the top left corner of the viewport onto the 00876 document. The RedrawNeeded flag is TRUE when any invalid areas created should 00877 be redrawn immediately and FALSE if they should be ignored. 00878 ********************************************************************************************/ 00879 00880 BOOL DocView::SetScrollOffsets(WorkCoord NewTopLeft, BOOL RedrawNeeded) 00881 { 00882 if (!View::SetScrollOffsets(NewTopLeft, RedrawNeeded)) 00883 // Something went wrong - report failure to caller. 00884 return FALSE; 00885 00886 WorkCoord RoundedTopLeft = GetScrollOffsets(); 00887 00888 // Tell Oil they've changed 00889 pViewWindow->SetScrollOffset(RoundedTopLeft, RedrawNeeded); 00890 00891 return TRUE; 00892 } 00893 00894 00895 00896 /******************************************************************************************** 00897 00898 > void DocView::ScrollToShow(DocCoord* pCoord) 00899 00900 Author: Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com> 00901 Created: 6/3/1996 00902 Inputs: pCoord - coord to show in spread coords 00903 Outputs: - 00904 Returns: - 00905 Purpose: Scrolls the currently selected document view to bring this coord into view. 00906 If this coord is already visible then we do nothing. 00907 00908 If an ordinate of pCoord is zero then it is ignored and the view willnot 00909 be scrolled in that direction. 00910 00911 ********************************************************************************************/ 00912 00913 void DocView::ScrollToShow(DocCoord* pCoord) 00914 { 00915 ERROR3IF(pCoord == NULL,"pCoord is NULL"); 00916 if (pCoord == NULL) return; 00917 00918 // call ScrollToShowAux, which does the actual work 00919 ScrollToShowAux(pCoord, DocCoord(0,0)); 00920 } 00921 00922 00923 00924 /******************************************************************************************** 00925 00926 > void DocView::ScrollToShow(DocRect *RectToShow) 00927 00928 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00929 Created: 22/3/96 00930 Inputs: RectToShow - Rectangle to show, in spread coords 00931 00932 Purpose: Scrolls the currently selected view to ensure that as much as possible of 00933 RectToShow is visible. If the entire rect cannot be seen, then it will scroll 00934 the minimum distance in order to make a part of it visible. 00935 00936 i.e. Unlike the other ScrollToShow functions, this actually scrolls to show 00937 the given rectangle, as opposed to single points. 00938 00939 ********************************************************************************************/ 00940 00941 void DocView::ScrollToShow(DocRect *RectToShow) 00942 { 00943 ERROR3IF(RectToShow == NULL, "Illegal NULL params"); 00944 00945 Spread* pSpread = GetFirstSelectedSpread(); 00946 00947 if (pSpread == NULL) 00948 return; 00949 00950 // The TRUE argument for GetPasteBoardRect means that the result gets 00951 // pixelised. Otherwise the clipping code below doesn't work properly 00952 DocRect ViewRect = (GetDocViewRect(pSpread)).ToSpread(pSpread, this); 00953 00954 // If the rect is entirely visible, or as much as possible of it is visible, then don't scroll! 00955 if (ViewRect.ContainsRect(*RectToShow) || RectToShow->ContainsRect(ViewRect)) 00956 return; 00957 00958 // Find the distance of the rectangle from each edge of the view rect, and work out 00959 // the distance we should scroll the view by 00960 DocCoord Offset(0,0); 00961 00962 // If we need to scroll in x axis, work out by how much 00963 // "Need to scroll" means: The target rect lies outside the view rect on *only* one side 00964 if ( 00965 (RectToShow->lo.x < ViewRect.lo.x || RectToShow->hi.x > ViewRect.hi.x) && // Outside 00966 !(RectToShow->lo.x < ViewRect.lo.x && RectToShow->hi.x > ViewRect.hi.x) // On one side only 00967 ) 00968 { 00969 // Find the distance needed to scroll the left edge of target to the left edge of the view 00970 // and the right edge to the right edge. 00971 INT32 Diff1 = RectToShow->lo.x - ViewRect.lo.x; 00972 INT32 Diff2 = RectToShow->hi.x - ViewRect.hi.x; 00973 00974 // We need to scroll by the smaller of these 2 distances 00975 INT32 AbsDiff1 = ABS(Diff1); 00976 INT32 AbsDiff2 = ABS(Diff2); 00977 00978 Offset.x = (AbsDiff1 < AbsDiff2) ? Diff1 : Diff2; 00979 } 00980 00981 // Repeat the above for the Y axis 00982 if ( 00983 (RectToShow->lo.y < ViewRect.lo.y || RectToShow->hi.y > ViewRect.hi.y) && // Outside 00984 !(RectToShow->lo.y < ViewRect.lo.y && RectToShow->hi.y > ViewRect.hi.y) // On one side only 00985 ) 00986 { 00987 // Find the distance to scroll to the left and right edges 00988 INT32 Diff1 = RectToShow->lo.y - ViewRect.lo.y; 00989 INT32 Diff2 = RectToShow->hi.y - ViewRect.hi.y; 00990 00991 // We need to scroll by the smaller of these 2 distances 00992 INT32 AbsDiff1 = ABS(Diff1); 00993 INT32 AbsDiff2 = ABS(Diff2); 00994 00995 Offset.y = (AbsDiff1 < AbsDiff2) ? Diff1 : Diff2; 00996 } 00997 00998 // Ensure we don't scroll off the pasteboard area. This should really be done by 00999 // SetScrollOffsets, but it appears that function is complete pants, and I've already 01000 // had to change over 60 files because of poorly designed fundamental code, so 01001 // I really don't have time to fix yet more problems. 01002 DocRect PasteRect = (pSpread->GetPasteboardRect(TRUE)).ToSpread(pSpread, this); 01003 if (Offset.x < 0) 01004 { 01005 if (ViewRect.lo.x + Offset.x < PasteRect.lo.x) 01006 Offset.x = ViewRect.lo.x - PasteRect.lo.x; 01007 } 01008 else 01009 { 01010 if (ViewRect.hi.x + Offset.x > PasteRect.hi.x) 01011 Offset.x = PasteRect.hi.x - ViewRect.hi.x; 01012 } 01013 01014 if (Offset.y < 0) 01015 { 01016 if (ViewRect.lo.y + Offset.y < PasteRect.lo.y) 01017 Offset.y = ViewRect.lo.y - PasteRect.lo.y; 01018 } 01019 else 01020 { 01021 if (ViewRect.hi.y + Offset.y > PasteRect.hi.y) 01022 Offset.y = PasteRect.hi.y - ViewRect.hi.y; 01023 } 01024 01025 // determine if we need to scroll or not, 01026 if (Offset != DocCoord(0,0)) 01027 { 01028 WorkCoord ScrollOffset; 01029 WorkCoord WorkOffset; 01030 01031 WorkOffset.x = (XLONG) (MakeXLong(Offset.x) * GetViewScale()); 01032 WorkOffset.y = (XLONG) (MakeXLong(Offset.y) * GetViewScale()); 01033 01034 ScrollOffset = GetScrollOffsets(); 01035 ScrollOffset.x = ScrollOffset.x + WorkOffset.x; 01036 ScrollOffset.y = ScrollOffset.y + WorkOffset.y; 01037 01038 if (ScrollOffset.x < (XLONG) 0) ScrollOffset.x = (XLONG) 0; 01039 if (ScrollOffset.y > (XLONG) 0) ScrollOffset.y = (XLONG) 0; 01040 01041 SetScrollOffsets(ScrollOffset, TRUE); 01042 } 01043 } 01044 01045 01046 01047 /******************************************************************************************** 01048 01049 > DocView::ScrollToShow(DocRect* pBoundingBox, DocCoord Direction) 01050 01051 Author: Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com> 01052 Created: 6/3/1996 01053 Inputs: pBoundingBox - DocRect to show in spread coords 01054 Direction - Direction of movement 01055 Outputs: - 01056 Returns: - 01057 Purpose: Scrolls the currently selected view to ensure that edge(s) of pBoundingBox 01058 are visible. The Direction argument tells us which edges. If the movement 01059 was towards the top of the screen then we need to make the top edge of the 01060 DocRect visible. 01061 01062 If an ordinate of Direction is zero then we ignore it and no scrolling is done 01063 in that direction. 01064 01065 ********************************************************************************************/ 01066 01067 void DocView::ScrollToShow(DocRect* pBoundingBox, DocCoord Direction) 01068 { 01069 ERROR3IF(pBoundingBox == NULL,"pBoundingBox is NULL"); 01070 if (pBoundingBox == NULL) return; 01071 01072 DocCoord Point; 01073 01074 if (Direction.x > 0) 01075 Point.x = pBoundingBox->hi.x; 01076 else if (Direction.x < 0) 01077 Point.x = pBoundingBox->lo.x; 01078 else 01079 Point.x = 0; 01080 01081 if (Direction.y > 0) 01082 Point.y = pBoundingBox->hi.y; 01083 else if (Direction.y < 0) 01084 Point.y = pBoundingBox->lo.y; 01085 else 01086 Point.y = 0; 01087 01088 // call ScrollToShowAux which does the actual work 01089 ScrollToShowAux(&Point, DocCoord(0,0)); 01090 } 01091 01092 01093 01094 /******************************************************************************************** 01095 01096 > void DocView::ScrollToShowWithMargin(DocCoord* pCoord) 01097 01098 Author: Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com> 01099 Created: 6/3/1996 01100 Inputs: pCoord - coord to show in spread coords 01101 Outputs: - 01102 Returns: - 01103 Purpose: Scrolls the currently selected view to show the coord; if the coord in already 01104 in view then we do nothing. 01105 01106 If an ordinate of pCoord is zero then we ignore it and do not scroll in that 01107 direction. 01108 01109 ********************************************************************************************/ 01110 01111 void DocView::ScrollToShowWithMargin(DocCoord* pCoord) 01112 { 01113 ERROR3IF(pCoord == NULL,"pCoord is NULL"); 01114 if (pCoord == NULL) return; 01115 01116 DocCoord Margin; 01117 01118 double Scale = GetViewScale().MakeDouble(); 01119 01120 Margin.x = (INT32) (ScrollToShowMargin/Scale); 01121 Margin.y = (INT32) (ScrollToShowMargin/Scale); 01122 01123 // call ScrollToShowAux, which does all the actual work 01124 ScrollToShowAux(pCoord, Margin); 01125 } 01126 01127 01128 01129 /******************************************************************************************** 01130 01131 > void DocView::ScrollToShowWithMargin(DocRect *RectToShow) 01132 01133 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 01134 Created: 22/3/96 01135 Inputs: RectToShow - Rectangle to show, in spread coords 01136 01137 Purpose: Scrolls the currently selected view to ensure that as much as possible of 01138 RectToShow is visible. If the entire rect cannot be seen, then it will scroll 01139 the minimum distance in order to make a part of it visible. 01140 01141 i.e. Unlike the other ScrollToShow functions, this actually scrolls to show 01142 the given rectangle, as opposed to single points. 01143 01144 ********************************************************************************************/ 01145 01146 void DocView::ScrollToShowWithMargin(DocRect *RectToShow) 01147 { 01148 ERROR3IF(RectToShow == NULL, "Illegal NULL params"); 01149 01150 DocRect Temp(*RectToShow); 01151 01152 double Scale = GetViewScale().MakeDouble(); 01153 01154 INT32 Margin = (INT32) (ScrollToShowMargin / Scale); 01155 01156 Temp.Inflate(Margin, Margin); 01157 01158 ScrollToShow(&Temp); 01159 } 01160 01161 01162 01163 /******************************************************************************************** 01164 01165 > void DocView::ScrollToShowWithMargin(DocRect* pBoundingBox, DocCoord Direction) 01166 01167 Author: Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com> 01168 Created: 6/3/1996 01169 Inputs: pBoundingBox - DocRect to show, in spread coords 01170 Direction - direction of movement 01171 Outputs: - 01172 Returns: - 01173 Purpose: Scrolls the current view to show parts of pBoundingBox. The edge(s) of 01174 pBoundingBox are determined by Direction, if we have moved objects towards 01175 the top of the screen then we need to ensure that the top edge of the DocRect 01176 is visible. 01177 01178 If an ordinate of Direction is zero then we ignore it and do not scroll in 01179 that direction. 01180 01181 ********************************************************************************************/ 01182 01183 void DocView::ScrollToShowWithMargin(DocRect* pBoundingBox, DocCoord Direction) 01184 { 01185 ERROR3IF(pBoundingBox == NULL,"pBoundingBox is NULL"); 01186 if (pBoundingBox == NULL) return; 01187 01188 DocCoord Point; 01189 DocCoord Margin; 01190 01191 if (Direction.x > 0) 01192 Point.x = pBoundingBox->hi.x; 01193 else if (Direction.x < 0) 01194 Point.x = pBoundingBox->lo.x; 01195 else 01196 Point.x = 0; 01197 01198 if (Direction.y > 0) 01199 Point.y = pBoundingBox->hi.y; 01200 else if (Direction.y < 0) 01201 Point.y = pBoundingBox->lo.y; 01202 else 01203 Point.y = 0; 01204 01205 double Scale = GetViewScale().MakeDouble(); 01206 Margin.x = (INT32) (ScrollToShowMargin/Scale); 01207 Margin.y = (INT32) (ScrollToShowMargin/Scale); 01208 01209 // call ScrollToShowAux, which does all the actual work 01210 ScrollToShowAux(&Point, Margin); 01211 } 01212 01213 /******************************************************************************************** 01214 01215 > void DocView::ScrollToShowAux(DocCoord *pCoord, DocCoord Margin) 01216 01217 Author: Andy_Hayward (Xara Group Ltd) <camelotdev@xara.com> 01218 Created: 6/3/1996 01219 Inputs: pCoord - coord to show in spread coords 01220 Margin - margin to give between point and edge of view 01221 Outputs: - 01222 Returns: - 01223 Purpose: Scrolls the view to ensure that pCoord is in the view, with a margin of Margin 01224 between it and the edges of the view. 01225 01226 If an ordinate of pCoord is zero then we ignore it and do not scroll in that 01227 direction. 01228 01229 ********************************************************************************************/ 01230 01231 void DocView::ScrollToShowAux(DocCoord *pCoord, DocCoord Margin) 01232 { 01233 ERROR3IF(pCoord == NULL,"pCoord is NULL"); 01234 if (pCoord == NULL) return; 01235 01236 ERROR3IF(Margin.x < 0,"Negative X margin"); 01237 if (Margin.x < 0) return; 01238 01239 ERROR3IF(Margin.y < 0,"Negative Y margin"); 01240 if (Margin.y < 0) return; 01241 01242 Spread* pSpread = GetFirstSelectedSpread(); 01243 01244 if (pSpread == NULL) 01245 { 01246 // do nothing 01247 } 01248 else 01249 { 01250 DocRect ViewRect; 01251 DocRect PasteRect; 01252 DocCoord Offset; 01253 01254 // The TRUE argument for GetPasteBoardRect means that the result gets 01255 // pixelised. Otherwise the clipping code below doesn't work properly 01256 ViewRect = (GetDocViewRect(pSpread)).ToSpread(pSpread, this); 01257 PasteRect = (pSpread->GetPasteboardRect(TRUE)).ToSpread(pSpread, this); 01258 01259 Offset = DocCoord(0,0); 01260 01261 // suppose the view rectangle is smaller than two margins width, either in height or 01262 // width, we'll need to alter the margin to half the height or width as appropriate 01263 { 01264 INT32 Width = ViewRect.hi.x - ViewRect.lo.x; 01265 INT32 Height = ViewRect.hi.y - ViewRect.lo.y; 01266 01267 if (Width < 2*Margin.x) 01268 Margin.x = Width/2; 01269 01270 if (Height < 2*Margin.y) 01271 Margin.y = Height/2; 01272 } 01273 01274 // only scroll in the X direction if pCoord->x is not zero 01275 if (pCoord->x != 0) 01276 { 01277 if (pCoord->x >= PasteRect.hi.x-Margin.x) pCoord->x = PasteRect.hi.x-Margin.x; 01278 if (pCoord->x <= PasteRect.lo.x+Margin.x) pCoord->x = PasteRect.lo.x+Margin.x; 01279 01280 if (pCoord->x < (ViewRect.lo.x+Margin.x)) 01281 { 01282 // need to scroll to the left 01283 Offset.x = pCoord->x - (ViewRect.lo.x + Margin.x); 01284 } 01285 01286 if (pCoord->x > (ViewRect.hi.x-Margin.x)) 01287 { 01288 // need to scroll to the right 01289 Offset.x = pCoord->x - (ViewRect.hi.x - Margin.x); 01290 } 01291 } 01292 else 01293 { 01294 Offset.x = 0; 01295 } 01296 01297 // only scroll in the Y direction if pCoord->y is not zero 01298 if (pCoord->y != 0) 01299 { 01300 if (pCoord->y >= PasteRect.hi.y-Margin.y) pCoord->y = PasteRect.hi.y-Margin.y; 01301 if (pCoord->y <= PasteRect.lo.y+Margin.y) pCoord->y = PasteRect.lo.y+Margin.y; 01302 01303 if (pCoord->y < (ViewRect.lo.y+Margin.y)) 01304 { 01305 // need to scroll down 01306 Offset.y = pCoord->y - (ViewRect.lo.y+Margin.y); 01307 } 01308 01309 if (pCoord->y > (ViewRect.hi.y-Margin.y)) 01310 { 01311 // need to scroll up 01312 Offset.y = pCoord->y - (ViewRect.hi.y-Margin.y); 01313 } 01314 } 01315 else 01316 { 01317 Offset.y = 0; 01318 } 01319 01320 // determine if we need to scroll or not, 01321 if (Offset != DocCoord(0,0)) 01322 { 01323 WorkCoord ScrollOffset; 01324 WorkCoord WorkOffset; 01325 01326 WorkOffset.x = (XLONG) (MakeXLong(Offset.x) * GetViewScale()); 01327 WorkOffset.y = (XLONG) (MakeXLong(Offset.y) * GetViewScale()); 01328 01329 ScrollOffset = GetScrollOffsets(); 01330 ScrollOffset.x = ScrollOffset.x + WorkOffset.x; 01331 ScrollOffset.y = ScrollOffset.y + WorkOffset.y; 01332 01333 if (ScrollOffset.x < (XLONG) 0) ScrollOffset.x = (XLONG) 0; 01334 if (ScrollOffset.y > (XLONG) 0) ScrollOffset.y = (XLONG) 0; 01335 01336 SetScrollOffsets(ScrollOffset, TRUE); 01337 } 01338 // else do nothing 01339 } 01340 } 01341 01342 /******************************************************************************************** 01343 01344 > BOOL DocView::ViewStateChanged() 01345 01346 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01347 Created: 18/5/93 01348 Purpose: Inform the DocView that the ViewState has been changed in some way. 01349 When this function detects a new ViewState object (IsNewView = TRUE) it sets 01350 the scroll offsets to the top left hand corner of the first page in the 01351 document. 01352 01353 ********************************************************************************************/ 01354 /* 01355 Technical notes: 01356 This function is called soon after construction of every DocView. At this time the CCamView 01357 has written lots of useful stuff into the ViewState (like the size of pixels) and so we 01358 can now calculate the extents of the document and give them back to CCamView. 01359 01360 ********************************************************************************************/ 01361 01362 BOOL DocView::ViewStateChanged() 01363 { 01364 // Local variables... 01365 DocCoord ExtentLo; // coord of bottom-left of logical extent 01366 DocCoord ExtentHi; // coord of top-right of logical extent 01367 01368 DialogBarOp::SetSystemStateChanged(); 01369 01370 // Implementation... 01371 ERROR2IF(this==NULL,FALSE,"DocView member func called on NULL pointer"); 01372 ERROR2IF(pDoc==NULL,FALSE,"ViewStateChanged: There MUST be an owner doc for this view!"); 01373 01374 // Read DocCoords extent of document & set extent in platform-indy ViewState struct. 01375 pDoc->GetExtents(&ExtentLo, &ExtentHi, &PhysExtent, this); 01376 SetExtent(ExtentLo, ExtentHi); 01377 01378 // Set extent in platform-indy ViewState struct 01379 ViewFlags.WorkClickCached = FALSE; 01380 return TRUE; 01381 } 01382 01383 01384 /********************************************************************************************* 01385 01386 > BOOL DocView::SetViewScale(FIXED16 NewScale) 01387 01388 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01389 Created: 31/5/93 01390 Inputs: New view scale factor 01391 Purpose: Set the viewing scale factor for this view. 01392 (Also, sets up the scaled pixel size in DocCoord if this View is current. 01393 01394 *********************************************************************************************/ 01395 01396 BOOL DocView::SetViewScale(FIXED16 NewScale) 01397 { 01398 if (!View::SetViewScale(NewScale)) 01399 // Error 01400 return FALSE; 01401 01402 // Tell everyone that a DocView scale has changed. 01403 BROADCAST_TO_ALL(DocViewMsg(this,DocViewMsg::SCALECHANGED)); 01404 01405 return TRUE; 01406 } 01407 01408 01409 01410 /******************************************************************************************** 01411 > void DocView::OnNewView() 01412 01413 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01414 Created: 26/4/94 01415 Inputs: - 01416 Outputs: - 01417 Returns: - 01418 Purpose: Called by CCamView as part of its "initial update" function provided that 01419 this view onto a document has not been previously saved and reloaded. 01420 Sets the defaults, eg. scroll offset, for newly created views. 01421 Errors: - 01422 SeeAlso: DocView::OnLoadedView; CCamView::OnInitialUpdate; struct ViewState 01423 ********************************************************************************************/ 01424 01425 void DocView::OnNewView() 01426 { 01427 // Only set the scroll offsets if they have not been set yet. 01428 // eg. When a document is loaded it is possible that it has already set the Scroll Offsets 01429 // to something sensible. 01430 WorkCoord CurrentOffset = GetScrollOffsets(); 01431 if ((CurrentOffset.x==0) && (CurrentOffset.y==0)) 01432 { 01433 // Find the first page in the document and set the scroll offsets so that the top 01434 // left corner of the page is in the top left corner of the view. 01435 Node* pSearchNode = Node::DocFindFirstDepthFirst(pDoc); 01436 while (pSearchNode != NULL && !pSearchNode->IsSpread()) 01437 pSearchNode = pSearchNode->DocFindNextDepthFirst(); 01438 01439 ERROR3IF(pSearchNode == NULL, "ViewStateChanged: Can't find first spread."); 01440 01441 if (pSearchNode != NULL) 01442 { 01443 Spread *pSpread = (Spread *)pSearchNode; 01444 01445 // OK, found the spread. Go look for the first page 01446 Page *pPage = pSpread->FindFirstPageInSpread(); 01447 ERROR3IF(pPage == NULL, "ViewStateChanged: Can't find first page in spread."); 01448 01449 if (pPage != NULL) 01450 { 01451 // OK, found the first page. 01452 // Read its position in the spread, translate into Doc Coord space 01453 DocRect PageRect = pPage->GetPageRect(); 01454 01455 DocCoord TopLeft(PageRect.lo.x, PageRect.hi.y); 01456 pSpread->SpreadCoordToDocCoord(&TopLeft); 01457 01458 // Then translate to work coords 01459 WorkCoord TopLeftWrk = TopLeft.ToWork(pSpread, this); 01460 01461 // Shift the corner of the page 1/8th of an inch into the window. 01462 TopLeftWrk.x -= (72000/8); 01463 TopLeftWrk.y += (72000/8); 01464 01465 // Only set the new scroll offsets if valid. Otherwise we will get an Error2. 01466 // We may try to set illegal values now that we allow zero sized pasterboards. 01467 if (TopLeftWrk.x >= (XLONG)0 && TopLeftWrk.y <= (XLONG)0) 01468 { 01469 // And scroll to place that offset at the top left of the view window 01470 SetScrollOffsets(TopLeftWrk, FALSE); 01471 } 01472 } 01473 } 01474 } 01475 01476 DialogBarOp::SetSystemStateChanged(); 01477 01478 // Change the View State so that it is no longer marked as new 01479 PORTNOTE("other","Removed ViewState usage") 01480 #ifndef EXCLUDE_FROM_XARALX 01481 if (pVState!=NULL) 01482 pVState->IsNewView = FALSE; 01483 #endif 01484 } 01485 01486 01487 01488 /******************************************************************************************** 01489 > void DocView::OnLoadedView() 01490 01491 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 01492 Created: 27/4/94 01493 Inputs: - 01494 Outputs: - 01495 Returns: - 01496 Purpose: Called by CCamView as part of its "initial update" function provided that 01497 this view onto a document has been previously saved and reloaded. 01498 Currently does nothing, but one day - who knows. 01499 Errors: - 01500 SeeAlso: DocView::OnNewView; CCamView::OnInitialUpdate; struct ViewState 01501 ********************************************************************************************/ 01502 01503 void DocView::OnLoadedView() 01504 { 01505 // empty for now 01506 } 01507 01508 01509 01510 /******************************************************************************************** 01511 01512 > void DocView::SetExtent(DocCoord lolog, DocCoord hilog) 01513 01514 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01515 Created: 26/5/93 01516 Inputs: Two DocCoords describing the low and high corners of a rectangle in logical 01517 space describing the full extent of the document. I.E. the bottom-left corner 01518 of the last chapter and the top-right corner of the first. 01519 Purpose: Informs the DocView that the extent of the document has changed in some way and 01520 that the view must be altered to take this into account (namely the 01521 scrollbars). 01522 01523 ********************************************************************************************/ 01524 01525 void DocView::SetExtent(DocCoord lolog, DocCoord hilog) 01526 { 01527 if (ViewFlags.LogicalView) 01528 { 01529 // "Pixelise" the extent DocCoords. 01530 // Effectively, this helps ensure that the spread will be aligned to a whole pixel boundary 01531 // and allows both GDraw and GDI to consistently plot the same pixels when rendering 01532 // the same primitive 01533 lolog.Pixelise(this); 01534 hilog.Pixelise(this); 01535 01536 // Logical view means that chapters are shown in a contiguous column 01537 // Convert the extent given in DocCoord to WorkCoords... 01538 pVState->WorkAreaExtent.lo = lolog.ToWork(pDoc, this); 01539 pVState->WorkAreaExtent.hi = hilog.ToWork(pDoc, this); 01540 01541 // If we know where the OIL view is then tell it that the extents have changed... 01542 if (pViewWindow) 01543 { 01544 pViewWindow->SetWorkAreaExtent(pVState->WorkAreaExtent, FALSE); 01545 } 01546 } 01547 else 01548 { 01549 // Physical view means that chapters are shown in their true positions in Document space 01550 ERROR3("DocView::SetExtent - Can't do physical views yet!"); 01551 } 01552 } 01553 01554 01555 01556 01557 01558 01559 /******************************************************************************************** 01560 01561 > WorkRect DocView::GetViewRect() 01562 01563 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01564 Created: 5/7/93 01565 Returns: A WorkCoords rectangle describing the viewport onto the document which this 01566 view is displaying. I.E. The top left corner of this rectangle is the same as 01567 the value returned by GetScrollOffsets(). 01568 Purpose: To find the rectangle describing the viewport onto the document. 01569 01570 ********************************************************************************************/ 01571 01572 WorkRect DocView::GetViewRect() 01573 { 01574 ERROR3IF(pViewWindow == NULL, "DocView::GetViewRect called when we have no ViewWindow"); 01575 01576 // Get the width and height of the view in OS units 01577 INT32 ClientWidth = 0; 01578 INT32 ClientHeight = 0; 01579 pViewWindow->GetClientSize(&ClientWidth, &ClientHeight); 01580 01581 OilRect OilViewRect; 01582 OilViewRect.lo.x = 0; 01583 OilViewRect.lo.y = -ClientHeight; 01584 OilViewRect.hi.x = ClientWidth; 01585 OilViewRect.hi.y = 0; 01586 01587 // Convert the OSRect into Workarea coords 01588 // WorkCoord pos; 01589 // pViewWindow->GetScrollOffset(&pos); 01590 // pVState->SetScrollPos(pos); 01591 // return OilViewRect.ToWork(pos); 01592 return OilViewRect.ToWork(pVState->GetScrollPos()); 01593 } 01594 01595 01596 01597 01598 /******************************************************************************************** 01599 01600 > DocRect DocView::GetDocViewRect(Spread* pSpread) 01601 01602 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01603 Created: 21/7/93 01604 Inputs: pSpread - the spread that we are interested in 01605 Returns: A DocCoords rectangle describing the viewport onto the document which this 01606 view is displaying. I.E. The top left corner of this rectangle is the same as 01607 the value returned by GetScrollOffsets() except in DocCoords. 01608 Purpose: To find the rectangle describing the viewport onto the document. 01609 01610 ********************************************************************************************/ 01611 01612 DocRect DocView::GetDocViewRect(Spread* pSpread) 01613 { 01614 ERROR3IF(pViewWindow == NULL, "DocView::GetDocViewRect called when we have no view"); 01615 01616 INT32 ClientWidth = 0; 01617 INT32 ClientHeight = 0; 01618 01619 // Get the width and height of the view in OS units 01620 pViewWindow->GetClientSize(&ClientWidth, &ClientHeight); 01621 01622 OilRect OilViewRect; 01623 OilViewRect.lo.x = 0; 01624 OilViewRect.lo.y = -ClientHeight; 01625 OilViewRect.hi.x = ClientWidth; 01626 OilViewRect.hi.y = 0; 01627 01628 // Convert the OSRect into Doc coords 01629 return OilViewRect.ToDoc(pSpread, this); 01630 } 01631 01632 01633 01634 /********************************************************************************************* 01635 01636 > void DocView::SetForeBackMode(BOOL NewFlag) 01637 01638 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01639 Created: 31/5/93 01640 Inputs: NewFlag - New bg render flag. 01641 Purpose: Set the background render flag for this view. 01642 Also sets the new value to be used as the default preference. 01643 01644 *********************************************************************************************/ 01645 01646 void DocView::SetForeBackMode(BOOL NewFlag) 01647 { 01648 ViewFlags.BackgroundRender = NewFlag; 01649 01650 // Update the preference to use this 01651 // Ensure that we either set TRUE or FALSE and not -1 or 0. 01652 // The preference is limited to 0 and 1 values and so -1 is illegal 01653 if (NewFlag == FALSE) 01654 BackgroundRendering = FALSE; 01655 else 01656 BackgroundRendering = TRUE; 01657 } 01658 01659 01660 01661 /********************************************************************************************* 01662 01663 > BOOL DocView::GetForeBackMode() 01664 01665 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01666 Created: 31/5/93 01667 Returns: TRUE if background rendering is on 01668 Purpose: To find out if background rendering is on 01669 01670 *********************************************************************************************/ 01671 01672 BOOL DocView::GetForeBackMode() 01673 { 01674 // As the flag is a BOOL in a bitfield, it seems to like returning -1 or 0 01675 // Therefore, ensure that we always return TRUE or FALSE 01676 01677 if (ViewFlags.BackgroundRender == FALSE) 01678 return (FALSE); 01679 else 01680 return (TRUE); 01681 01682 } 01683 01684 01685 01686 01687 /******************************************************************************************** 01688 01689 > void DocView::RenderView(RenderRegion* pRRegion, Matrix& ViewTransform, Spread *pSpread, 01690 BOOL bPrintPaper, BOOL fDeleteRegionAfter = TRUE, 01691 BOOL bForceImmediate = TRUE) 01692 01693 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01694 Created: 19/5/93 01695 Inputs: pRRegion - the region to use for rendering the spread 01696 ViewTransform - the matrix to use when transforming document coordinates 01697 into Window coordinates. 01698 pSpread - the spread we are rendering with this render region. 01699 bPrintPaper should be TRUE if paper-like items need to be rendered e.g. page 01700 marks, blobs, etc, or FALSE otherwise. A TRUE value also will enable background 01701 rendering, so long as Viewflags.BackgroundRender is also set. 01702 fDeleteRegionAfter --- by default TRUE - if so then this function will 01703 deallocate the RenderRegion passed to it when it has been comletely rendered. 01704 Purpose: To render a Document through a given RenderRegion. 01705 The dominating factor in this routine is that it renders the document with as 01706 little time overhead as possible. Obviously, this is mainly down to 01707 RenderRegions and the tree scanning routines working fast but we can do a bit 01708 to help. 01709 This routine is called directly by other functions in DocView and externally 01710 from the Background redraw Idle event processor. 01711 01712 ********************************************************************************************/ 01713 /* 01714 Technical notes: 01715 This routine stores and restores its position in the document tree from the 01716 RenderRegion. If it ever picks up a NULL it assumes that the RenderRegion has 01717 just been created and renders the background to the document, eg. pages, 01718 pasteboard, etc... 01719 When the routine hits the end of the tree it will pass a NULL in for the 01720 RenderRegion to store as its state. This can be used a a signal that rendering 01721 in this RenderRegion is complete and that the RenderRegion can be destroyed. 01722 01723 The control flow path through this routine is very carefully laid out. When 01724 the call to GetRenderState returns NULL, we assume that the RenderRegion is 01725 newly created and in that case we render all paper nodes and find the first 01726 ink node before dropping through to the renderer proper. 01727 When GetRenderState returns a pointer to a node then this RenderRegion has 01728 already rendered some ink nodes in the tree and so we must carry on where we 01729 left off. In this case the control path must be VERY CLEAN - it must not 01730 alter the tree pointer or change any attributes because the RenderRegion has 01731 records of all of these things set from the previous session. 01732 01733 ********************************************************************************************/ 01734 01735 void DocView::RenderView(RenderRegion* pRRegion, Matrix& ViewTransform, 01736 Spread *pSpread, BOOL bPrintPaper, 01737 BOOL fDeleteRegionAfter, 01738 BOOL bForceImmediate) 01739 { 01740 Node* pNode = NULL; 01741 BOOL CleanUp = TRUE; // TRUE if cleanup at end, FALSE if dont 01742 BOOL IsMoreBands = FALSE; 01743 DocRect ClipRect; 01744 01745 BOOL HasRendered = FALSE; 01746 BOOL Continue = TRUE; 01747 BOOL bPaperRenderedThisTime = FALSE; 01748 01749 // Record time when rendering started 01750 StartTime.Sample(); 01751 01752 // Scroll offsets etc may have changed, so transfer matrix. 01753 pRRegion->SetMatrix(ViewTransform); 01754 01755 // Prepare to find out whether any bounds in selection are changed during redraw 01756 m_bBoundsChanged = FALSE; 01757 01758 // Start the first band 01759 if (!pRRegion->SetFirstBand()) 01760 { 01761 goto ExitRenderNoStop; 01762 } 01763 01764 do 01765 { 01766 // See if we are actually waiting for memory 01767 if (pRRegion->IsWaitingForRAM) 01768 { 01769 // See if we can get the memory yet ? 01770 pRRegion->GetNextBand(); 01771 01772 if (pRRegion->IsWaitingForRAM) 01773 break; // Nope still not enough 01774 } 01775 01776 // Tell the RenderRegion that I am going to start rendering. 01777 if (!pRRegion->StartRender()) 01778 { 01779 TRACEALL( _T("StartRender failed in RenderView\n") ); 01780 // will be deleted quickly 01781 goto ExitRenderNoStop; // skip StopRender call 01782 } 01783 01784 // If the state is NULL I take this to mean that the RenderRegion has only just been 01785 // created and I will therefore ensure that the window background is rendered by rendering 01786 // all the "paper" parts of the document. That is, the pages, chapters, pasteboard, etc... 01787 if (pRRegion->IsPaperRendered == FALSE) 01788 { 01789 if (bPrintPaper) 01790 { 01791 // Render all paper nodes from there into the real render region 01792 pRRegion->SaveContext(); 01793 RenderPaper(pRRegion, pSpread); 01794 pRRegion->RestoreContext(); 01795 01796 if (pRRegion->NeedsOSPaper) 01797 { 01798 // This render region uses the OS to render paper, so if we don't 01799 // render anything except paper then there is no need for e.g. 01800 // GRenderRegions to blit anything. Hence we call this function 01801 // to clear the changed bbox. 01802 pRRegion->SetClean(TRUE, FALSE); 01803 } 01804 } 01805 01806 #ifdef _DEBUG 01807 // TEMP BODGE! DO NOT RELEASE! 01808 //if (pRRegion->IsKindOf(CC_RUNTIME_CLASS(GRenderRegion))) 01809 // ((GRenderRegion*)pRRegion)->DebugTrace(); 01810 #endif 01811 01812 // The Paper is now done 01813 pRRegion->IsPaperRendered = TRUE; 01814 bPaperRenderedThisTime = TRUE; 01815 } 01816 01817 // ------------------------------------------ 01818 // Call the central tree renderer... 01819 Continue = pRRegion->RenderTree(pSpread, 01820 ViewFlags.BackgroundRender && !bForceImmediate // Only timeslice if bgr && ! rendering paper 01821 ); 01822 // ------------------------------------------ 01823 01824 // Reset state to new posn in tree. 01825 BOOL bRendered = pRRegion->StopRender(); 01826 HasRendered = HasRendered || bRendered; 01827 01828 // Dragging blobs/boxes. 01829 Operation* pDragOp = Operation::GetCurrentDragOp(); 01830 if (pDragOp) pDragOp->RenderDragBlobs(pRRegion->GetClipRect(), pSpread, m_bSolidDrag); 01831 01832 // Assume we ran out of time 01833 IsMoreBands = FALSE; 01834 01835 // If we did not run out of time, prepare the next band 01836 if (Continue) 01837 { 01838 IsMoreBands = pRRegion->GetNextBand(); 01839 01840 if (pRRegion->IsWaitingForRAM) 01841 break; // Leave this region for a while 01842 } 01843 } while (IsMoreBands); 01844 01845 // Could jump straight to here if the render region was waiting for some ram to show up 01846 01847 ExitRenderNoStop: 01848 pNode = pRRegion->GetRenderState(); 01849 01850 // Find out whether all bounds have become cached during this render 01851 // If so, update the SelRange and tell all tools the SelRange has changed 01852 // This handles the situation where effects change their bounds during rendering 01853 if (m_bBoundsChanged) 01854 { 01855 // Only broadcast to the rest of the program if we're not trying to be quick 01856 Camelot.FindSelection()->Update(!Operation::GetQuickRender(NULL)); 01857 } 01858 01859 // Find out the rectangle of the whole unbanded region 01860 DocRect BlobClipRect = pRRegion->GetRegionRect(); 01861 BOOL IsRegionFinished = CleanUp && !pRRegion->IsWaitingForRAM && pRRegion->IsLastBand && !pNode; 01862 01863 // If the region has finished rendering, delete it, otherwise update its context node. 01864 if (IsRegionFinished) 01865 { 01866 if (fDeleteRegionAfter) 01867 { 01868 // Unlink the RenderRegion from list 01869 BOOL InList = Camelot.DeleteRenderRegion(pRRegion); 01870 ERROR2IF(!InList, (void)0, "DocView::RenderView tried to delete a RenderRegion not in list"); 01871 delete pRRegion; 01872 } 01873 } 01874 01875 // Draw the blobs if we are the "selected" view. 01876 // And we're not solid dragging... 01877 if (this == Selected && !(pCurrentDragOp!=NULL && m_bSolidDrag)) 01878 { 01879 // Tool & selection blobs. 01880 // HasRendered really means "Has blitted and wiped out previous blobs within the changedrect..." 01881 // So we should redraw the blobs inside the changed rect (note that the paper chanegd rect 01882 // needs to be derived differently than the ink changed rect) 01883 // BUT we don't know here what the changed rect is! 01884 // SO, all we can do is wait until the render is over then put the blobs back on 01885 // if (HasRendered || bPaperRenderedThisTime)) 01886 if (IsRegionFinished) 01887 { 01888 Tool* pTool = Tool::GetCurrent(); 01889 if (pTool) 01890 { 01891 pTool->RenderToolBlobs(pSpread, &BlobClipRect); 01892 } 01893 01894 // Render the Currently selected objects selection blobs 01895 RenderSelectBlobs(BlobClipRect, pSpread); 01896 } 01897 } 01898 } 01899 01900 01901 01902 01903 /******************************************************************************************** 01904 01905 > void DocView::ContinueRenderView(RenderRegion* pRRegion, Chapter* pChapter, 01906 BOOL fRenderPaper = TRUE, 01907 BOOL fDeleteRegionAfter = TRUE, 01908 BOOL bForceImmediate = FALSE) 01909 01910 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 01911 Created: 11/7/93 01912 Inputs: Pointer to RenderRegion which needs rendering to be performed. 01913 Pointer to chapter which RenderRegion represents. 01914 fRenderPaper --- if TRUE then render paper, blobs etc. 01915 By default TRUE. 01916 fDeleteRegionAfter --- if TRUE then this function will deallocate the 01917 RenderRegion passed to it when it has been 01918 completely rendered. By default TRUE. 01919 Outputs: None 01920 Returns: None 01921 Scope: Public 01922 Purpose: To re-start rendering a Document through a given RenderRegion. This call is 01923 different from RenderView because it may need to re-compute the Doc to OS 01924 matrix. 01925 Errors: None 01926 01927 ********************************************************************************************/ 01928 01929 void DocView::ContinueRenderView(RenderRegion* pRRegion, Spread* pSpread, 01930 BOOL fRenderPaper /* = TRUE */, 01931 BOOL fDeleteRegionAfter /* = TRUE */, 01932 BOOL bForceImmediate /*= FALSE*/) 01933 { 01934 // Diccon 10/5/2000 my awful flag that prevents rendering of the view from occurring 01935 // whilst a brush stroke is in progress 01936 if (m_bPreventRenderView == TRUE) 01937 return; 01938 01939 // Remove the drag blobs from this region, if there are any. 01940 if (fRenderPaper) 01941 { 01942 Operation* pDragOp = Operation::GetCurrentDragOp(); 01943 if (pDragOp) 01944 pDragOp->RenderDragBlobs(pRRegion->GetClipRect(), pSpread, m_bSolidDrag); 01945 } 01946 01947 // Render the document in one operation. 01948 Matrix mxConv = ConstructRenderingMatrix(pSpread); 01949 01950 if (OnTopCount == 0 && GetColourPlate() != NULL && !GetColourPlate()->IsDisabled()) 01951 { 01952 ColourPlateType PlateType = GetColourPlate()->GetType(); 01953 if (PlateType != COLOURPLATE_NONE && PlateType != COLOURPLATE_COMPOSITE) 01954 { 01955 // We have to do this before the render as the RenderSimpleView call 01956 // will delete the render region 01957 DocRect BlobClipRect = pRRegion->GetRegionRect(); 01958 DocRect DragClipRect = pRRegion->GetClipRect(); 01959 01960 // Do a printer style simple/complex ScanningRenderRegion type render 01961 RenderSimpleView(pRRegion, mxConv, pSpread, fRenderPaper); 01962 01963 // Dragging blobs/boxes. 01964 if (fRenderPaper) 01965 { 01966 Operation* pDragOp = Operation::GetCurrentDragOp(); 01967 if (pDragOp) pDragOp->RenderDragBlobs(DragClipRect, pSpread, m_bSolidDrag); 01968 } 01969 01970 // Draw the blobs if we are the "selected" view. 01971 // And we're not solid dragging... 01972 if (fRenderPaper && this == Selected && !(pCurrentDragOp!=NULL && m_bSolidDrag)) 01973 { 01974 Tool* pTool = Tool::GetCurrent(); 01975 if (pTool) pTool->RenderToolBlobs(pSpread, &BlobClipRect); 01976 01977 // Render the Currently selected objects selection blobs 01978 RenderSelectBlobs(BlobClipRect, pSpread); 01979 } 01980 return; 01981 } 01982 } 01983 01984 RenderView(pRRegion, mxConv, pSpread, fRenderPaper, fDeleteRegionAfter, bForceImmediate); 01985 } 01986 01987 01988 01989 01990 /******************************************************************************************** 01991 01992 > void DocView::RenderEntireView(RenderRegion* pRender, Spread* pSpread) 01993 01994 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01995 Created: 17/8/2000 01996 Inputs: pRRegion - the region to use for rendering the spread 01997 01998 Purpose: To render a Document through a given RenderRegion. 01999 This differs from your regular RenderView service in that it pays no mind as to 02000 how long things take. Once you start this function off it will run until it 02001 renders the lot. 02002 The reason for this is that it is designed for use with the brush tool. Here we 02003 will need to render the entire view into an offscreen bitmap which is then 02004 used to with the brush. It serves as an alternative when we cannot simply blit 02005 the contents of the screen. 02006 I don't really recommend using this function in other circumstances as if you 02007 have a complex document it will probably lock up for a while. 02008 ********************************************************************************************/ 02009 02010 void DocView::RenderEntireView(RenderRegion* pRRegion, Spread* pSpread) 02011 { 02012 DocRect ClipRect; 02013 02014 Matrix ViewTransform = ConstructRenderingMatrix(pSpread); 02015 // Scroll offsets etc may have changed, so transfer matrix. 02016 pRRegion->SetMatrix(ViewTransform); 02017 02018 // Get the region to clip all the rendering to 02019 ClipRect = pRRegion->GetClipRect(); 02020 02021 // If the state is NULL I take this to mean that the RenderRegion has only just been 02022 // created and I will therefore ensure that the window background is rendered by rendering 02023 // all the "paper" parts of the document. That is, the pages, chapters, pasteboard, etc... 02024 if (pRRegion->IsPaperRendered == FALSE) 02025 { 02026 // Render all paper nodes from there into the real render region 02027 pRRegion->SaveContext(); 02028 RenderPaper(pRRegion, pSpread); 02029 pRRegion->RestoreContext(); 02030 02031 // The Paper is now done 02032 pRRegion->IsPaperRendered = TRUE; 02033 } 02034 02035 // Now render all the ink (non-paper) parts of the document. 02036 pRRegion->RenderTree(pSpread, FALSE); 02037 02038 // Reset state to new posn in tree. 02039 pRRegion->StopRender(); 02040 } 02041 02042 02043 /******************************************************************************************** 02044 02045 > void DocView::GetViewParams(FIXED16* pReturnViewScale, 02046 FIXED16* pReturnPixelScaleX, 02047 FIXED16* pReturnPixelScaleY, 02048 WorkCoord* pReturnScrollOffset) 02049 02050 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02051 Created: 24/5/93 02052 Inputs: None 02053 Outputs: None 02054 Returns: None 02055 Purpose: This function returns the parameters which control the transformation of 02056 coordinates between Document space and OS space. These parameters can be used 02057 to build transformation matrices to perform the transformation in either 02058 direction. 02059 Errors: None 02060 02061 ********************************************************************************************/ 02062 /* 02063 void DocView::GetViewParams(FIXED16* pReturnViewScale, 02064 FIXED16* pReturnPixelScaleX, 02065 FIXED16* pReturnPixelScaleY, 02066 WorkCoord* pReturnScrollOffset) 02067 { 02068 ENSURE( pViewWindow != NULL, "DocView::GetViewParams() called when there we no ViewWindow"); 02069 02070 *pReturnViewScale = Scale; 02071 *pReturnPixelScaleX = pVState->PixelXScale; 02072 *pReturnPixelScaleY = pVState->PixelYScale; 02073 *pReturnScrollOffset = pVState->GetScrollPos(); 02074 } 02075 */ 02076 02077 /******************************************************************************************** 02078 02079 > static DocRect DocView::ChapterClip(DocRect& DocClip, Chapter* pChapter) 02080 02081 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 02082 Created: 18/9/93 02083 Inputs: The DocRect to Clip, and a Chapter to clip it with. 02084 Outputs: - 02085 Returns: A Clipped DocRect 02086 Purpose: Clips the DocRect so that it does not go outside the Chapter Bounds. 02087 This is used to try and stop the problems with DocCoords that are not within 02088 any chapters (ie. in OffPaste area). 02089 Errors: - 02090 SeeAlso: - 02091 02092 ********************************************************************************************/ 02093 /* 02094 static DocRect DocView::ChapterClip(DocRect& DocClip, Chapter* pChapter) 02095 { 02096 DocRect ChapterRect = pChapter->GetPasteboardRect(); 02097 02098 ChapterRect.lox = MAX(DocClip.lox, ChapterRect.lox); 02099 ChapterRect.loy = MAX(DocClip.loy, ChapterRect.loy); 02100 ChapterRect.hix = MIN(DocClip.hix, ChapterRect.hix); 02101 ChapterRect.hiy = MIN(DocClip.hiy, ChapterRect.hiy); 02102 02103 return ChapterRect; 02104 } 02105 */ 02106 02107 02108 02109 02110 /********************************************************************************************* 02111 02112 > static DocView *DocView::GetCurrent() 02113 02114 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02115 Created: 24/5/93 02116 Returns: Pointer to the current DocView object. 02117 Purpose: Find the current DocView object which SHOULD have been set as one of the very 02118 first actions during event processing. 02119 02120 *********************************************************************************************/ 02121 02122 DocView *DocView::GetCurrent() 02123 { 02124 View *pView = View::GetCurrent(); 02125 02126 // Make sure it really is a DocView; 02127 if ((pView == NULL) || (pView->IS_KIND_OF(DocView))) 02128 // Yes - return it. 02129 return (DocView *) pView; 02130 02131 // Complain! 02132 //ERROR2(NULL, "DocView::GetCurrent called when current view is not a DocView!"); 02133 TRACEALL( _T("DocView::GetCurrent called when current view is not a DocView!\n") ); 02134 return NULL; 02135 } 02136 02137 02138 /******************************************************************************************** 02139 02140 > void DocView::SetViewPixelSize() 02141 02142 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02143 Created: 02/10/95 02144 Purpose: Sets up the normal and scaled pixel sizes according to this view. 02145 SeeAlso: OilCoord::SetPixelSize; DocCoord::SetScaledPixelSize 02146 02147 ********************************************************************************************/ 02148 02149 void DocView::SetViewPixelSize() 02150 { 02151 // Set the scaled pixel size 02152 ScaledPixelWidth = PixelWidth / Scale; 02153 ScaledPixelHeight = PixelHeight / Scale; 02154 } 02155 02156 /********************************************************************************************* 02157 > static CNativeWnd* DocView::GetCurrentRenderWindow() 02158 02159 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> (modified to use DocView::GetRenderWindow() by Ed 1/9/95) 02160 Created: 15 Oct 93 02161 Returns: Pointer to the current CNativeWnd window object which is being rendered. 02162 Purpose: Useful function allowing fairly direct access to CCamView's render window, 02163 which comes in handy on the odd occasion. 02164 Errors: Returns NULL if there isn't one. 02165 *********************************************************************************************/ 02166 02167 CNativeWnd *DocView::GetCurrentRenderWindow() 02168 { 02169 DocView* pCurrent=GetCurrent(); 02170 if (pCurrent==NULL) 02171 return NULL; 02172 02173 return pCurrent->GetRenderWindow(); 02174 } 02175 02176 02177 /********************************************************************************************* 02178 > CNativeWnd* DocView::GetRenderWindow() 02179 02180 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 02181 Created: 1/9/95 02182 Returns: Pointer to CNativeWnd (else NULL if none) 02183 Purpose: Get a pointer to a CNativeWnd window object associated with a DocView 02184 *********************************************************************************************/ 02185 02186 CNativeWnd* DocView::GetRenderWindow() 02187 { 02188 if (pViewWindow==NULL) 02189 return NULL; 02190 02191 return pViewWindow->GetRenderWindow(); 02192 } 02193 02194 02195 /********************************************************************************************* 02196 02197 > static DocView *DocView::GetSelected() 02198 02199 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02200 Created: 24/5/93 02201 Returns: Pointer to the selected DocView object. 02202 Purpose: Find the selected DocView object which SHOULD have been set as one of the very 02203 first actions during event processing. 02204 02205 *********************************************************************************************/ 02206 02207 DocView *DocView::GetSelected() 02208 { 02209 return Selected; 02210 } 02211 02212 02213 02214 02215 /********************************************************************************************* 02216 02217 > BOOL DocView::SetCurrent() 02218 02219 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02220 Created: 24/5/93 02221 Inputs: - 02222 Outputs: - 02223 Returns: TRUE if function set current correctly 02224 FALSE otherwise (then an Error has been set) 02225 Purpose: Make this object be the 'current' DocView. 02226 02227 *********************************************************************************************/ 02228 02229 BOOL DocView::SetCurrent() 02230 { 02231 return View::SetCurrent(); 02232 } 02233 02234 02235 02236 /********************************************************************************************* 02237 02238 > static void DocView::SetNoCurrent() 02239 02240 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02241 Created: 24/5/93 02242 Inputs: - 02243 Outputs: - 02244 Returns: - 02245 Purpose: Set the current DocView pointer to be NULL, i.e., there is no current 02246 DocView object. 02247 02248 *********************************************************************************************/ 02249 02250 void DocView::SetNoCurrent() 02251 { 02252 View::SetNoCurrent(); 02253 } 02254 02255 02256 02257 /********************************************************************************************* 02258 02259 > static void DocView::SetSelectedInternal(DocView *NewSelected) 02260 02261 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02262 Created: 14/2/95 02263 02264 Inputs: NewSelected - NULL, or the new selected DocView 02265 02266 Purpose: This is an INTERNAL function, which MUST NOT BE CALLED by anything 02267 other than Document::SetSelectedViewAndSpread. 02268 02269 It sets the new selected DocView, but DOES NOT broadcast a message. 02270 The broadcast follows later, via SendSelectedMessage. 02271 02272 It can be used to set No Selected DocView (NewSelected = NULL) 02273 02274 It also sets this DocView as the Current DocView. 02275 02276 SeeAlso: Document::SetSelectedViewAndSpread; DocView::SendSelectedMessage 02277 02278 *********************************************************************************************/ 02279 02280 void DocView::SetSelectedInternal(DocView *NewSelected) 02281 { 02282 Selected = NewSelected; 02283 02284 if (NewSelected == NULL) 02285 DocView::SetNoCurrent(); 02286 else 02287 NewSelected->SetCurrent(); 02288 } 02289 02290 02291 02292 /********************************************************************************************* 02293 02294 > static void DocView::SendSelectedMessage(DocView *OldSelected, DocView *NewSelected); 02295 02296 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 02297 Created: 14/2/95 02298 02299 Inputs: OldSelected - Points to the previously selected DocView (may be NULL) 02300 NewSelected - Points to the new selected DocView (may be NULL) 02301 02302 Purpose: This is an INTERNAL function, which MUST NOT BE CALLED by anything 02303 other than Document::SetSelectedViewAndSpread. 02304 02305 It is used to broadcast a DocViewMsg (SELCHANGED) to inform of a selection 02306 change. It follows a SetSelectedInternal call (a bit later, so that the 02307 message is only broadcast once the document, view, and spread states have 02308 all been updated correctly) 02309 02310 SeeAlso: Document::SetSelectedViewAndSpread; DocView::SetSelectedInternal 02311 02312 *********************************************************************************************/ 02313 02314 void DocView::SendSelectedMessage(DocView *OldSelected, DocView *NewSelected) 02315 { 02316 BROADCAST_TO_ALL(DocViewMsg(OldSelected, NewSelected, DocViewMsg::SELCHANGED)); 02317 } 02318 02319 02320 02321 /******************************************************************************************** 02322 > INT32 DocView::GetZoomTableIndex() const 02323 02324 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02325 Created: 16/5/94 02326 Inputs: - 02327 Outputs: - 02328 Returns: Returns the value of the zoom table index. 02329 Purpose: 02330 Errors: - 02331 SeeAlso: DocView::SetZoomTableIndex 02332 ********************************************************************************************/ 02333 02334 INT32 DocView::GetZoomTableIndex() const 02335 { 02336 return ZoomTableIndex; 02337 } 02338 02339 02340 02341 /******************************************************************************************** 02342 > void DocView::SetZoomTableIndex(INT32 nIndex) 02343 02344 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02345 Created: 16/5/94 02346 Inputs: The new index value. 02347 Outputs: - 02348 Returns: - 02349 Purpose: 02350 Errors: - 02351 SeeAlso: DocView::GetZoomTableIndex 02352 ********************************************************************************************/ 02353 02354 void DocView::SetZoomTableIndex(INT32 nIndex) 02355 { 02356 ZoomTableIndex = nIndex; 02357 } 02358 02359 02360 02361 /******************************************************************************************** 02362 > INT32 DocView::GetPrevZoomIndex() const 02363 02364 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02365 Created: 17/5/94 02366 Inputs: - 02367 Outputs: - 02368 Returns: - 02369 Purpose: Returns the index into the zoom tool's tabel of a previous zoom on this 02370 DocView. 02371 Errors: - 02372 SeeAlso: DocView::SetPrevZoomIndex 02373 ********************************************************************************************/ 02374 02375 INT32 DocView::GetPrevZoomIndex() const 02376 { 02377 return PrevIndex; 02378 } 02379 02380 02381 02382 /******************************************************************************************** 02383 > void DocView::SetPrevZoomIndex(INT32 nIndex) 02384 02385 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02386 Created: 17/5/94 02387 Inputs: The previous zoom index. 02388 Outputs: - 02389 Returns: - 02390 Purpose: Sets the zoom table index of a previous zoom onto this DocView. 02391 Errors: - 02392 SeeAlso: DocView::GetPrevZoomIndex 02393 ********************************************************************************************/ 02394 02395 void DocView::SetPrevZoomIndex(INT32 nIndex) 02396 { 02397 PrevIndex = nIndex; 02398 } 02399 02400 02401 02402 02403 02404 /******************************************************************************************** 02405 > FIXED16 DocView::GetPrevZoomScale() const 02406 02407 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02408 Created: 17/5/94 02409 Inputs: - 02410 Outputs: - 02411 Returns: The scale factor of this view as set by a previous zoom. 02412 Purpose: 02413 Errors: - 02414 SeeAlso: DocView::SetPrevZoomScale 02415 ********************************************************************************************/ 02416 02417 FIXED16 DocView::GetPrevZoomScale() const 02418 { 02419 return PrevScale; 02420 } 02421 02422 02423 02424 /******************************************************************************************** 02425 > void DocView::SetPrevZoomScale(FIXED16 fxScale) 02426 02427 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02428 Created: 17/5/94 02429 Inputs: The previous zoom scale. 02430 Outputs: - 02431 Returns: - 02432 Purpose: Sets the scale factor this DocView will "remember" as a previous zoom. 02433 Errors: - 02434 SeeAlso: DocView::GetPrevZoomScale 02435 ********************************************************************************************/ 02436 02437 void DocView::SetPrevZoomScale(FIXED16 fxScale) 02438 { 02439 PrevScale = fxScale; 02440 } 02441 02442 02443 02444 /******************************************************************************************** 02445 > WorkCoord DocView::GetPrevZoomOffset() const 02446 02447 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02448 Created: 17/5/94 02449 Inputs: - 02450 Outputs: - 02451 Returns: The scroll offset of this DocView during a previous zoom. 02452 Purpose: 02453 Errors: - 02454 SeeAlso: DocView::SetPrevZoomOffset 02455 ********************************************************************************************/ 02456 02457 WorkCoord DocView::GetPrevZoomOffset() const 02458 { 02459 return PrevOffset; 02460 } 02461 02462 02463 02464 /******************************************************************************************** 02465 > void DocView::SetPrevZoomOffset(const WorkCoord& wcOffset) 02466 02467 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 02468 Created: 17/5/94 02469 Inputs: The previous zoom's scroll offset. 02470 Outputs: - 02471 Returns: - 02472 Purpose: Sets the scroll offset this DocView will "remember" as a previous zoom. 02473 Errors: - 02474 SeeAlso: DocView::GetPrevZoomOffset 02475 ********************************************************************************************/ 02476 02477 void DocView::SetPrevZoomOffset(const WorkCoord& wcOffset) 02478 { 02479 PrevOffset = wcOffset; 02480 } 02481 02482 02483 02484 02485 /******************************************************************************************** 02486 02487 > void DocView::ForceRedraw(BOOL ForcePaper = FALSE) 02488 02489 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02490 Created: 1/7/93 02491 Inputs: ForcePaper: TRUE => do a normal OS-style invalidation 02492 FALSE => do a 'clever' internal invalidation which does not 02493 cause paper to be drawn straight away, so we get a 02494 smoother feel to the update. 02495 Purpose: Force the entire view to be redrawn. 02496 NB. If you are redrawing because you have changed the zoom or scroll 02497 offsets, then you must pass in TRUE for ForcePaper!!! 02498 (Because (a) Otherwise our scroll offsets are invalid and the next 02499 time we scroll it gets mucked up, and 02500 (b) Scrolling or zooming should give instant feedback to 02501 the user.) 02502 02503 ********************************************************************************************/ 02504 02505 void DocView::ForceRedraw(BOOL ForcePaper) 02506 { 02507 // Make sure we use this DocView 02508 SetCurrent(); 02509 02510 // Get rid of any render regions associated with this DocView 02511 Camelot.DeleteRenderRegions(this); 02512 02513 // Invalidate the whole view window 02514 if (ForcePaper) 02515 { 02516 // We want an instant update with paper drawn now, so use the OS to do the 02517 // invalidation. 02518 pViewWindow->InvalidateView(); 02519 return; 02520 } 02521 02522 // find type of rendering device 02523 CCamView *pCamView = GetConnectionToOilView(); 02524 ERROR2IF(pCamView == NULL, (void)0, "DocView::ForceRedraw: DocView has no CamView"); 02525 02526 pCamView->AllocateDC(); // allocate a DC 02527 02528 CNativeDC* pDevContext = pCamView->GetRenderDC(); 02529 const RenderType rType = CCDC::GetType(pDevContext, TRUE); 02530 02531 // Get DocView rectangle in 64 bit WorkCoods 02532 WorkRect ClipRect = GetViewRect(); 02533 02534 ERROR3IF(ClipRect.lo.x > ClipRect.hi.x, "DocView::ForceRedraw: clipping rect is invalid"); 02535 ERROR3IF(ClipRect.lo.y > ClipRect.hi.y, "DocView::ForceRedraw: clipping rect is invalid"); 02536 02537 // Find all the spreads in the document that intersect the clipping rect, and create 02538 // a render region for each of them. 02539 02540 // Get the first chapter in the document 02541 for (Chapter* pChapter = Node::FindFirstChapter(pDoc); 02542 pChapter != 0; 02543 pChapter = pChapter->FindNextChapter()) 02544 { 02545 // Convert chapter bounding box to logical coords 02546 DocRect PhysChapterRect = pChapter->GetPasteboardRect(TRUE, this); 02547 WorkRect LogChapterRect; 02548 LogChapterRect.lo = PhysChapterRect.lo.ToWork(pDoc, this); 02549 LogChapterRect.hi = PhysChapterRect.hi.ToWork(pDoc, this); 02550 02551 // Check to see if this chapter intersects the clipping rectangle. 02552 // If the chapter is the last one in the document, then the chapter's pasteboard 02553 // does not include the area of the bottom of the last spread, so we only check 02554 // the chapter's top boundary. 02555 02556 BOOL fIsLastChapter = (pChapter->FindNextChapter() == 0); 02557 02558 if (ClipRect.lo.y <= LogChapterRect.hi.y && 02559 (fIsLastChapter || ClipRect.hi.y >= LogChapterRect.lo.y)) 02560 { 02561 for (Spread* pSpread = pChapter->FindFirstSpread(); 02562 pSpread != 0; 02563 pSpread = pSpread->FindNextSpread()) 02564 { 02565 // Convert spread bounding box to logical coords 02566 DocRect PhysSpreadRect = pSpread->GetPasteboardRect(TRUE); // Pixelised 02567 WorkRect LogSpreadRect; 02568 LogSpreadRect.lo = PhysSpreadRect.lo.ToWork(pSpread, this); 02569 LogSpreadRect.hi = PhysSpreadRect.hi.ToWork(pSpread, this); 02570 02571 BOOL fIsLastSpread = (pSpread->FindNextSpread() == 0); 02572 02573 // Check if spread intersects the clipping rect 02574 if (ClipRect.lo.y <= LogSpreadRect.hi.y && 02575 ((fIsLastChapter && fIsLastSpread) || ClipRect.hi.y >= LogSpreadRect.lo.y)) 02576 { 02577 // Make render region for intersection between spread and cliprect. 02578 DocRect SpreadClipRect = pSpread->GetWidePasteboard(this); 02579 02580 // Convert clip rectangle to document coords 02581 DocRect DocClipRect = GetDocViewRect(pSpread); 02582 02583 // Clip to spread rectangle 02584 SpreadClipRect = SpreadClipRect.Intersection(DocClipRect); 02585 02586 // Make sure that the clip region is valid after the intersection 02587 if (SpreadClipRect.IsValid() && !SpreadClipRect.IsEmpty()) 02588 { 02589 // Convert it to Spread coords and create a render region 02590 pSpread->DocCoordToSpreadCoord(&SpreadClipRect); 02591 MakeNewRenderRegion(pSpread, SpreadClipRect, pDevContext, rType, FALSE); 02592 } 02593 } 02594 } 02595 } 02596 } 02597 02598 pCamView->DoneWithDC(); // deallocate a DC 02599 } 02600 02601 02602 /******************************************************************************************** 02603 02604 > void DocView::ForceRedraw(const DocRect& ForceRect) 02605 02606 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 02607 Created: 1/7/93 02608 Inputs: ForceRect - the rectangle to be invalidated 02609 Purpose: Force a specific rectangle of the view to be redrawn 02610 02611 ********************************************************************************************/ 02612 02613 void DocView::ForceRedraw(WorkRect& ForceRect) 02614 { 02615 PORTNOTETRACE("other","DocView::ForceRedraw - do nothing"); 02616 #ifndef EXCLUDE_FROM_XARALX 02617 ERROR3("Should not be called!"); 02618 02619 OilCoord OilRectLo = (ForceRect.lo).ToOil(GetScrollOffsets()); 02620 OilCoord OilRectHi = (ForceRect.hi).ToOil(GetScrollOffsets()); 02621 02622 OilRect RedrawOilRect(OilRectLo, OilRectHi); 02623 02624 pViewWindow->InvalidateView(&RedrawOilRect); 02625 #endif 02626 } 02627 02628 02629 02630 /******************************************************************************************** 02631 02632 > void DocView::ForceRedraw(Spread *pSpread, DocRect& SpreadRect, BOOL Accumulate = FALSE, Node* pInvalidNode = NULL) 02633 02634 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> & Rik 02635 Created: 14/12/93 02636 Inputs: pSpread - the spread which contains the invalid region. 02637 SpreadRect - the invalid region (in spread coordinates, i.e. (0,0) based) 02638 Accumulate - TRUE => invalidate *now* 02639 FALSE => don't invalidate right now, but accumulate this 02640 into a list of rectangles for this view, and update 02641 intelligently when DocView::FlushRedraw() is called. 02642 ForceRecache - TRUE => Make sure that any overlapping cached bitmaps that capture bits of 02643 objects around/under/over them are thrown away during this redraw 02644 FALSE => Don't need to worry about cached objects because nothing in the tree 02645 has changed 02646 02647 Purpose: Force redraw of an area of a spread. 02648 SeeAlso: DocView::FlushRedraw 02649 02650 ********************************************************************************************/ 02651 02652 void DocView::ForceRedraw(Spread *pSpread, DocRect SpreadRect, BOOL Accumulate, Node* pInvalidNode) 02653 { 02654 ERROR3IF(pSpread == NULL, "ForceRedraw has been passed a NULL spread pointer"); 02655 02656 // Make sure we use this DocView 02657 SetCurrent(); 02658 02659 // This rectangle has come directly from the program and might not lie on pixel 02660 // boundaries. So pixelise it before passing it directly on to the rendering system. 02661 SpreadRect.lo.Pixelise(this); 02662 SpreadRect.hi.Pixelise(this); 02663 02664 // Should we do it now? 02665 // IMMEDIATE REDRAW 02666 // if (FALSE) 02667 if (Accumulate) 02668 { 02669 // No - add it to our list and wait until the Operation finishes...as long as it 02670 // works. 02671 if (PendingRedrawList.AddInvalidRegion(pSpread, SpreadRect, pInvalidNode)) 02672 { 02673 // Worked - exit now and wait for FlushRedraw() to be called. 02674 return; 02675 } 02676 02677 // Otherwise fall through to normal processing (which will probably fail too!) 02678 } 02679 02680 // Is this a bodge I see before me??? 02681 // Not really. This modification expands the invalid region to take anti-aliasing 02682 // pixels into account. It could be made conditional on anti-aliasing being turned on 02683 // but this is simpler and the overhead when anti-aliasing is off is not great. 02684 SpreadRect.Inflate(ScaledPixelWidth.MakeLong(), ScaledPixelHeight.MakeLong()); 02685 02686 // Translate spread coords to document coords 02687 pSpread->SpreadCoordToDocCoord(&SpreadRect); 02688 02689 // Clip this region to the spread 02690 DocRect WidePasteRect = pSpread->GetWidePasteboard(this); 02691 SpreadRect = SpreadRect.Intersection(WidePasteRect); 02692 02693 // need to check for valid intersections here as Intersecting with 02694 // an invalid rectangle again will give a valid rectangle would you 02695 // believe! (Mike 20/12/95) 02696 if ( SpreadRect.IsEmpty() || (!SpreadRect.IsValid()) ) 02697 { 02698 return; 02699 } 02700 02701 // Convert clip rectangle to document coords 02702 DocRect DocClipRect = GetDocViewRect(pSpread); 02703 02704 // Clip to spread rectangle 02705 SpreadRect = SpreadRect.Intersection(DocClipRect); 02706 02707 // Check to see if the result is an empty rectangle 02708 if ((SpreadRect.IsValid()) && (!SpreadRect.IsEmpty())) 02709 { 02710 // Find type of rendering device 02711 CCamView *pCamView = GetConnectionToOilView(); 02712 ERROR2IF(pCamView == NULL, (void)0, "DocView has no CamView!"); 02713 02714 // These next two are commented out because 02715 // a) rType is never used, and 02716 // b) pDevContext idn't needed in MakeNewRenderRegion if PaintPaper is FALSE (which is is) 02717 02718 // CDC *pDevContext = pCamView->GetRenderDC(); 02719 // const RenderType rType = CCDC::GetType(pDevContext, TRUE); 02720 02721 // Translate document coords back to spread coords 02722 pSpread->DocCoordToSpreadCoord(&SpreadRect); 02723 02724 // Use this to make a render region. 02725 // MakeNewRenderRegion(pSpread, SpreadRect, pDevContext, RENDERTYPE_SCREEN, FALSE); // See changed line below 02726 02727 // Notice that because the PaintPaper parameter (5th one) is FALSE, we can pass 02728 // NULL as a pointer to a device context, and thus we don't have to call 02729 // GetRenderDC above at all, and hopefully, this will speed up translation 02730 // no end. 02731 MakeNewRenderRegion(pSpread, SpreadRect, NULL, RENDERTYPE_SCREEN, FALSE, pInvalidNode); 02732 } 02733 } 02734 02735 02736 /******************************************************************************************** 02737 02738 > void DocView::FlushRedraw() 02739 02740 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02741 Created: 22/12/94 02742 Purpose: Intelligently invalidate all the regions gathered so far for this DocView. 02743 This performs smart invalidation depending on the number and nature of the 02744 regions. 02745 SeeAlso: DocView::ForceRedraw; PendingRedraws; SpreadRedraws 02746 02747 ********************************************************************************************/ 02748 02749 void DocView::FlushRedraw() 02750 { 02751 // Ask the update list to do its stuff 02752 PendingRedrawList.FlushRedraw(this); 02753 } 02754 02755 /******************************************************************************************** 02756 02757 > void DocView::HandleNodeDeletion(Node* pNode) 02758 02759 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 02760 Created: 22/12/94 02761 Purpose: Intelligently invalidate all the regions gathered so far for this DocView. 02762 This performs smart invalidation depending on the number and nature of the 02763 regions. 02764 SeeAlso: DocView::ForceRedraw; PendingRedraws; SpreadRedraws 02765 02766 ********************************************************************************************/ 02767 02768 void DocView::HandleNodeDeletion(Node* pNode) 02769 { 02770 // Ask the update list to do its stuff 02771 PendingRedrawList.HandleNodeDeletion(pNode); 02772 } 02773 02774 /******************************************************************************************** 02775 02776 > ObjectDragTarget DocView::IsPointerOverNode(NodeRenderableInk** ThisNode, INT32 Range, 02777 BOOL Interrupt = TRUE, BOOL bIsColourDrag=FALSE) 02778 02779 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> (and Will) 02780 Created: 23/1/95 02781 Outputs: ThisNode - ptr to node over if any NULL otherwise 02782 Inputs: Range - Margin to use in line hittest 02783 Interrupt - TRUE if the Hit Test should be interruptable or not. 02784 02785 // DMc inserted 6/5/99 02786 For colour drags, you don't want to addess the shadow 02787 or bevel controller node, but what's inside 02788 02789 Returns: an ObjectDragTarget - FILL/LINE/STARTFILL/ENDFILL 02790 Purpose: to determine whether pointer is over 1 - an objects outline 02791 2 - any visible fill blobs 02792 3 - a simple (non grouped) object 02793 ********************************************************************************************/ 02794 02795 ObjectDragTarget DocView::IsPointerOverNode(NodeRenderableInk** pThisNode, INT32 Range, 02796 BOOL Interrupt, BOOL bIsColourDrag) 02797 { 02798 Spread *pSpread=NULL; 02799 DocCoord pMousePos; 02800 02801 // get the current spread and mouse pos 02802 if(!GetCurrentMousePos(&pSpread, &pMousePos)) 02803 return NO_TARGET; 02804 02805 // mouse pos to be used at end of drag 02806 DragPos = pMousePos; 02807 02808 // ouch ! 02809 if(!pSpread) 02810 return NO_TARGET; 02811 02812 // See if we are close to the TextStory caret - We can't hittest on it as it is only a blob 02813 if (TextStory::GetFocusStory() != NULL) 02814 { 02815 CaretNode* pCaret = TextStory::GetFocusStory()->GetCaret(); 02816 Matrix matrix; 02817 02818 if ((pCaret != NULL) && pCaret->IsSelected() && (pCaret->GetStoryAndCharMatrix(&matrix)!=FALSE)) 02819 { 02820 // get the bounds of the caret path for the blob bounds 02821 Path* pCaretPath = pCaret->CreatePath(&matrix); 02822 if (pCaretPath != NULL) 02823 { 02824 INT32 CloseSlot = 0; 02825 double mu = 0.0; 02826 if (pCaretPath->IsPointCloseTo(pMousePos, Range*Range, &CloseSlot, &mu)) 02827 { 02828 *pThisNode = pCaret; 02829 delete pCaretPath; 02830 return FILL_TARGET; 02831 } 02832 delete pCaretPath; 02833 } 02834 } 02835 } 02836 02837 // Allow the hit-test to be interrupted if the mouse moves! 02838 Node* pInterruptedNode = NULL; 02839 NodeRenderableInk * pCompoundNode = NULL; 02840 NodeRenderableInk* pSimpleNode = NodeRenderableInk::FindSimpleAtPoint(pSpread, 02841 pMousePos, 02842 NULL, 02843 Interrupt ? &pInterruptedNode : NULL); 02844 02845 if (pInterruptedNode!=NULL) 02846 // hit-test was interrupted... 02847 pSimpleNode=NULL; 02848 02849 // Now we have the 'Simple' node that the pointer was over. 02850 02851 // If we can we should use any Selected nodes, so lets see if 02852 // this node or any of it's parents are selected. 02853 // We will stop if we get to the layer. 02854 02855 if (pSimpleNode != NULL) // Did we hit anything ? 02856 { 02857 Node* pSelNode = NULL; 02858 02859 if ((ClickModifiers::GetClickModifiers().Constrain) || pSimpleNode->IsSelected()) 02860 { 02861 // The node we hit was selected, so we will just use that 02862 pSelNode = pSimpleNode; 02863 } 02864 else 02865 { 02866 // Hunt up the tree, looking for a selected parent 02867 Node* pParent = pSimpleNode->FindParent(); 02868 while (pParent != NULL && !pParent->IsLayer()) 02869 { 02870 if (pParent->IsSelected()) 02871 { 02872 // Found a selected parent, so we'll use that 02873 02874 // don't do it for shadow controller nodes, or bevel nodes 02875 if ((!pSimpleNode->IsKindOf(CC_RUNTIME_CLASS(NodeShadow)) && 02876 !pSimpleNode->IsKindOf(CC_RUNTIME_CLASS(NodeBevel))) || 02877 !bIsColourDrag) 02878 { 02879 pSelNode = pParent; 02880 } 02881 else 02882 { 02883 pSelNode = pSimpleNode; 02884 } 02885 02886 02887 break; 02888 } 02889 02890 pParent = pParent->FindParent(); 02891 } 02892 } 02893 02894 if (pSelNode != NULL) 02895 { 02896 // We will use the selected node in preference to anything else 02897 pSimpleNode = (NodeRenderableInk*)pSelNode; 02898 } 02899 else 02900 { 02901 // We didn't find any selected nodes, so we will try and apply 02902 // to a Parent group of the hit node. 02903 02904 // This function will return the same node, if it has no parent group 02905 02906 // DMc 6/5/99 02907 // change to hit testing for drags - don't do a compound node 02908 // for bevel controller or shadow controller nodes 02909 pCompoundNode = NodeRenderableInk::FindCompoundFromSimple(pSimpleNode); 02910 pSimpleNode = pCompoundNode; 02911 02912 if ((!pSimpleNode->IsKindOf(CC_RUNTIME_CLASS(NodeShadow)) && 02913 !pSimpleNode->IsKindOf(CC_RUNTIME_CLASS(NodeBevel))) || 02914 !bIsColourDrag) 02915 { 02916 pSimpleNode = pCompoundNode; 02917 } 02918 02919 } 02920 } 02921 02922 // we can pass this back to the drag target 02923 02924 *pThisNode = pSimpleNode; 02925 02926 02927 // get the object bounds for this object 02928 DocRect pSimpleBounds; 02929 if(pSimpleNode) 02930 pSimpleBounds = pSimpleNode->GetBoundingRect(); 02931 else 02932 pSimpleBounds.MakeEmpty(); 02933 02934 AttrColourDrop *Attrib = new AttrColourDrop(pMousePos,pSimpleBounds,DocColour(COLOUR_TRANS)); 02935 02936 // this will sort out whether we are over any fill blobs 02937 // pThisNode will then point to the relevant Node 02938 // OverFill is the FillControl type we are currently over 02939 FillControl OverFill = AttrFillGeometry::DoColourDropTest(Attrib,pThisNode,NULL); 02940 delete Attrib; 02941 02942 ObjectDragTarget TargetHit; 02943 02944 // return the appropriate colour drag target 02945 switch(OverFill) 02946 { 02947 case FILLCONTROL_STARTPOINT: 02948 TargetHit = STARTCOL_TARGET; 02949 break; 02950 02951 case FILLCONTROL_ENDPOINT: 02952 case FILLCONTROL_SECONDARYPOINT: 02953 TargetHit = ENDCOL_TARGET; 02954 break; 02955 02956 case FILLCONTROL_ENDPOINT2: 02957 TargetHit = ENDCOL2_TARGET; 02958 break; 02959 02960 case FILLCONTROL_ENDPOINT3: 02961 TargetHit = ENDCOL3_TARGET; 02962 break; 02963 02964 case FILLCONTROL_MANY: 02965 TargetHit = MANY_TARGET; 02966 break; 02967 02968 case FILLCONTROL_NULL: 02969 TargetHit = FILL_TARGET; 02970 break; 02971 02972 default: 02973 TargetHit = FILL_TARGET; 02974 break; 02975 } 02976 02977 // BODGE ??? This should all change when we can do hit testing on lines. 02978 if(pSimpleNode) 02979 { 02980 // we're over an object - we'll see how close to its path we are 02981 Path* pPath = NULL; 02982 02983 if (IS_A(pSimpleNode, NodePath)) 02984 { 02985 // get the node as a NodePath 02986 NodePath* pNPath = (NodePath*) pSimpleNode; 02987 pPath= &(pNPath->InkPath); 02988 } 02989 else if (pSimpleNode->IsKindOf(CC_RUNTIME_CLASS(NodeSimpleShape))) 02990 { 02991 // get the node as a NodeSimpleShape 02992 NodeSimpleShape * pNShape = (NodeSimpleShape*) pSimpleNode; 02993 pPath= &(pNShape->InkPath); 02994 } 02995 else if (pSimpleNode->IsKindOf(CC_RUNTIME_CLASS(NodeRegularShape))) 02996 { 02997 NodeRegularShape * pNShape = (NodeRegularShape*) pSimpleNode; 02998 pNShape->BuildShapePath(&pPath); 02999 } 03000 03001 // we'll use the snap range to determine whether we are close to the path or not 03002 if(pPath) 03003 { 03004 INT32 CloseSlot = 0; 03005 double mu = 0.0; 03006 if (pPath->IsPointCloseTo(pMousePos,Range*Range, &CloseSlot, &mu)) 03007 { 03008 return LINE_TARGET; // yes we are 03009 } 03010 } 03011 } 03012 03013 return TargetHit; 03014 } 03015 03016 /******************************************************************************************** 03017 03018 > BOOL DocView::DM_DragFinished(DragInformation* DragInfo, ViewDragTarget* pDragTarget) 03019 03020 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> (and Will) 03021 Created: 23/1/95 03022 Inputs: DragInformation - about this drag.. 03023 pDragTarget - The drag target created for this DocView 03024 Purpose: act at the end of a general drag according to the drag type. 03025 03026 ********************************************************************************************/ 03027 03028 BOOL DocView::DM_DragFinished(DragInformation* DragInfo, ViewDragTarget* pDragTarget) 03029 { 03030 // The DragInfo must know what to do, or else we wouldn't 03031 // have accepted the drag 03032 BOOL DropOK = DragInfo->OnPageDrop(pDragTarget); 03033 03034 return DropOK; 03035 } 03036 03037 /******************************************************************************************** 03038 03039 > void DocView::DragPointerMove(Operation* pDragOp, OilCoord PointerPos, ClickModifiers Mods) 03040 03041 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03042 Created: 2/7/93 03043 Inputs: pDragOp - Pointer to the current drag operation 03044 PointerPos - Coordinate of pointer in OS space 03045 Mods - Click modifiers structure 03046 Purpose: Tell the current dragging operation that the pointer has moved. This function 03047 is ony called when a drag has been started in CCamView by calling its 03048 StartDrag function and should not be called after EndDrag has been called. 03049 03050 ********************************************************************************************/ 03051 03052 void DocView::DragPointerMove(Operation* pDragOp, OilCoord PointerPos, ClickModifiers Mods) 03053 { 03054 // BOOL bDragSolidly = FALSE; 03055 03056 // Ignore if system is disabled 03057 if (CCamApp::IsDisabled()) 03058 return; // If the system is disabled, ignore 03059 03060 // Find the spread that contains DocPos 03061 Spread *pSpread = FindEnclosingSpread(PointerPos); 03062 03063 // Note GetSelectedSpread is quicker in situations where you know you only have one spread 03064 // but it prevents drags on multiple spread views working properly... 03065 // Spread *pSpread = Document::GetSelectedSpread(); 03066 03067 if (pSpread == NULL) 03068 { 03069 ERROR3("Could not find spread in which the click happened"); 03070 return; // Exit reasonably nicely 03071 } 03072 03073 // Convert the OSRect into document coords 03074 DocCoord DocPos = PointerPos.ToDoc(pSpread, this); 03075 03076 // Convert the coord to spread coords 03077 pSpread->DocCoordToSpreadCoord(&DocPos); 03078 03079 // Store away the WorkCoord version of this click in the DocView for later extraction by 03080 // GetClickWorkCoord(); 03081 LastWorkClick = PointerPos.ToWork( pVState->GetScrollPos() ); 03082 ViewFlags.WorkClickCached = TRUE; // Cached WorkCoord is valid. 03083 03084 // Now call the current tool with the DocCoord click point 03085 ERROR3IF( pDragOp==NULL, "There was not operation in DragPointerMove()" ); 03086 if (pDragOp) 03087 pDragOp->DragPointerMove(DocPos, Mods, pSpread, m_bSolidDrag); 03088 03089 ViewFlags.WorkClickCached = FALSE; // Cached WorkCoord is no longer valid! 03090 } 03091 03092 03093 03094 03095 /******************************************************************************************** 03096 03097 > void DocView::DragPointerIdle(Operation* pDragOp, OilCoord PointerPos, ClickModifiers Mods) 03098 03099 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03100 Created: 2/7/93 03101 Inputs: pDragOp - Pointer to the current drag operation 03102 PointerPos - Coordinate of pointer in OS space 03103 Mods - Click modifiers structure 03104 Purpose: Tell the current dragging operation that the pointer has NOT moved and that 03105 there is idle CPU time to be used. This function is only called when a drag has 03106 been started in CCamView by calling its StartDrag function and should not be 03107 called after EndDrag has been called. 03108 03109 ********************************************************************************************/ 03110 03111 void DocView::DragPointerIdle(Operation* pDragOp, OilCoord PointerPos, ClickModifiers Mods) 03112 { 03113 ERROR3IF(pDragOp == NULL, "Illegal NULL parameter!"); 03114 03115 // Ignore if system is disabled 03116 if (CCamApp::IsDisabled()) 03117 return; // If the system is disabled, ignore 03118 03119 // Find the spread that contains DocPos 03120 Spread *pSpread = FindEnclosingSpread(PointerPos); 03121 03122 // Note GetSelectedSpread is quicker in situations where you know you only have one spread 03123 // but it prevents drags on multiple spread views working properly... 03124 // Spread *pSpread = Document::GetSelectedSpread(); 03125 03126 if (pSpread == NULL) 03127 { 03128 ERROR3("Could not find spread in which the click happened"); 03129 return; // Exit reasonably nicely 03130 } 03131 03132 // First of all convert the OSRect into document coords 03133 DocCoord DocPos = PointerPos.ToDoc(pSpread, this); 03134 03135 // Convert the coord to spread coords 03136 pSpread->DocCoordToSpreadCoord(&DocPos); 03137 03138 // Store away the WorkCoord version of this click in the DocView for later extraction by 03139 // GetClickWorkCoord(); 03140 LastWorkClick = PointerPos.ToWork( pVState->GetScrollPos() ); 03141 ViewFlags.WorkClickCached = TRUE; // Cached WorkCoord is valid. 03142 03143 // Now call the current tool with the DocCoord click point 03144 if (pDragOp != NULL) 03145 pDragOp->DragPointerIdle(DocPos, Mods, pSpread, m_bSolidDrag); 03146 03147 // Cached WorkCoord is no longer valid! 03148 ViewFlags.WorkClickCached = FALSE; 03149 } 03150 03151 03152 03153 03154 /******************************************************************************************** 03155 03156 > void DocView::DragFinished(Operation* pDragOp, OilCoord PointerPos, ClickModifiers Mods, 03157 BOOL Success) 03158 03159 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03160 Created: 2/7/93 03161 Inputs: pDragOp - Pointer to the current drag operation 03162 PointerPos - Coordinate of pointer in OS space 03163 Mods - Click modifiers structure 03164 Success - Flag saying whether drag ended OK or was aborted for some reason 03165 Purpose: Tell the current dragging operation that the drag has ended either because 03166 the pointer buttons have all been released or the drag has been aborted in 03167 some way (Escape was pressed?). 03168 This function is ony called when a drag has been started in CCamView by 03169 calling its StartDrag function and should not be called after EndDrag has been 03170 called. 03171 03172 ********************************************************************************************/ 03173 03174 void DocView::DragFinished(Operation* pDragOp, OilCoord PointerPos, ClickModifiers Mods, 03175 BOOL Success) 03176 { 03177 // Ignore if system is disabled 03178 if (CCamApp::IsDisabled()) 03179 return; // If the system is disabled, ignore 03180 // SHOULD END THE DRAG 03181 03182 // Find the spread that contains DocPos 03183 Spread *pSpread = FindEnclosingSpread(PointerPos); 03184 03185 if (pSpread == NULL) 03186 { 03187 ERROR3("Could not find spread in which the click happened"); 03188 return; // Exit reasonably nicely 03189 } 03190 03191 // First of all convert the OSRect into document coords 03192 DocCoord DocPos = PointerPos.ToDoc( pSpread, this ); 03193 03194 // Convert the coord to spread coords 03195 pSpread->DocCoordToSpreadCoord(&DocPos); 03196 03197 // Store away the WorkCoord version of this click in the DocView for later extraction by 03198 // GetClickWorkCoord(); 03199 LastWorkClick = PointerPos.ToWork( pVState->GetScrollPos() ); 03200 03201 // Cached WorkCoord is valid. 03202 ViewFlags.WorkClickCached = TRUE; 03203 03204 // Broadcast a "starting operation" message to begin with (normally broadcast by 03205 // OpDescriptor::Invoke, but thanks to the brain-damaged Camelot architecture, operations 03206 // which drag do not invoke, and this is the best place to catch them. Go figure.) 03207 BROADCAST_TO_ALL(OpMsg(pDragOp, OpMsg::BEGIN)); 03208 03209 // Now call the current tool with the DocCoord click point 03210 pDragOp->DragFinished(DocPos, Mods, pSpread, Success, m_bSolidDrag); 03211 03212 // Cached WorkCoord is no longer valid! 03213 ViewFlags.WorkClickCached = FALSE; 03214 m_bSolidDrag = FALSE; 03215 } 03216 03217 03218 03219 03220 /******************************************************************************************** 03221 03222 > void DocView::OnClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods) 03223 03224 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03225 Created: 2/7/93 03226 Inputs: PointerPos - Position of click from OS 03227 Click - Type of click (single, double or drag) 03228 Mods - Other inputs which modify the meaning of the click 03229 Purpose: Convert click coordinates into DocCoords and pass them on to the current 03230 tool. 03231 03232 ********************************************************************************************/ 03233 /* Technical notes: 03234 This routine also converts the click position into WorkCoords and keeps it 03235 for those routines which need it. They can get it by calling 03236 GetClickWorkCoord so long as the ViewState hasn't changed in the meantime. 03237 03238 ********************************************************************************************/ 03239 03240 void DocView::OnClick(OilCoord PointerPos, ClickType Click, ClickModifiers Mods) 03241 { 03242 // Ignore if system is disabled 03243 if (CCamApp::IsDisabled()) 03244 return; // If the system is disabled, ignore 03245 03246 // grab the focus if it's stuck in a control somewhere 03247 DialogManager::DefaultKeyboardFocus(); 03248 03249 // Find the spread in which the click happened 03250 Spread *pSpread = FindEnclosingSpread(PointerPos); 03251 03252 if (pSpread == NULL) 03253 { 03254 ERROR3("Could not find spread in which the click happened"); 03255 return; // Exit reasonably nicely 03256 } 03257 03258 // When the user clicks on a spread which is not the selected spread then this spread becomes 03259 // selected and the selection is cleared. 03260 //Document::SetSelectedSpread(pSpread); 03261 Document::SetSelectedViewAndSpread(pDoc, this, pSpread); 03262 03263 //GetApplication()->FindSelection()->SetSelectedSpread(pSpread); 03264 03265 // First of all convert the OilRect into device coords 03266 DocCoord DocPos = PointerPos.ToDoc( pSpread, this ); 03267 03268 // Convert the coord to spread coords 03269 pSpread->DocCoordToSpreadCoord(&DocPos); 03270 03271 03272 // Store away the WorkCoord version of this click in the DocView for later extraction by 03273 // GetClickWorkCoord(); 03274 LastWorkClick = PointerPos.ToWork( pVState->GetScrollPos() ); 03275 ViewFlags.WorkClickCached = TRUE; // Cached WorkCoord is valid. 03276 03277 // Check the click mods to see if they specify an operation which we can do directly here 03278 if (Mods.IsHandledByTool()) 03279 { 03280 // Now call the current tool with the DocCoord click point 03281 // Graham 18/6/96: When one button clicks while another one is dragging 03282 // we call the current drag operation, not the tool 03283 if (Mods.ClickWhileDrag) 03284 { 03285 //First make sure there is a current drag operation 03286 ERROR3IF(Operation::GetCurrentDragOp()==NULL, "DocView::OnClick - no current drag operation"); 03287 03288 //Now call the current drag operation. 03289 //If the current drag operation is not a transform operation, this 03290 //will call the empty virtual function Operator::OnClickWhileDragging. 03291 Operation::GetCurrentDragOp()->OnClickWhileDragging(PointerPos, Click, Mods, m_bSolidDrag); 03292 } 03293 else if (Mods.PushCentreTool) 03294 { 03295 // Matt 16/11/2000 - Use the push tool/auto-screen-centrey-tool when required 03296 OpPush* pOpPush = new OpPush; 03297 ERROR3IF(!pOpPush,"Out of memory in DocView() -> Cannot create PushOp"); 03298 03299 // Matt 12/01/2001 03300 // Change the cursor to show the hand icon 03301 PushToolCursorID = CursorStack::GPush( &m_PushCursor, TRUE ); 03302 03303 // Start the drag operation and pass in the Anchor Point to the push operation 03304 pOpPush -> DoDrag( DocPos ); 03305 } 03306 else 03307 { 03308 Tool* pCurrentTool = Tool::GetCurrent(); 03309 03310 if(pCurrentTool) 03311 { 03312 pCurrentTool->OnClick(DocPos, Click, Mods, pSpread); 03313 } 03314 else 03315 ERROR3("No current tool in DocView::OnClick()!"); 03316 } 03317 03318 // --------------------------------------------------------------------------- 03319 // Do special handling for menu clicks 03320 // Allow the Selector to do it's normal stuff for "Click" events and "Up" events 03321 // So that menu clicks perform selection as required by Windows UI guidelines 03322 // On the up stroke show the context menu 03323 if (Mods.Menu) 03324 { 03325 #ifndef STANDALONE 03326 Tool* pSelector = Tool::FindTool(TOOLID_SELECTOR); 03327 ERROR3IF(pSelector==NULL, "ARGH! No Selector when DocView got a menu click!"); 03328 Tool* pCurrentTool = Tool::GetCurrent(); 03329 if (pSelector!=pCurrentTool && 03330 (Click == CLICKTYPE_SINGLE || Click == CLICKTYPE_UP) && // Don't allow menu drags while selector not current 03331 !Mods.ClickWhileDrag && 03332 Operation::GetCurrentDragOp()==NULL) 03333 { 03334 pSelector->OnClick(DocPos, Click, Mods, pSpread); 03335 } 03336 03337 // On the up stroke 03338 if (Click==CLICKTYPE_UP && !Mods.ClickWhileDrag) 03339 { 03340 #ifdef PHOTOSHOPPLUGINS 03341 // As we are just about to invoke a context menu, check that the plug-in manager has its list 03342 // of available plug-ins otherwise, go and get it now as we are just about to need it. 03343 // Must do it now before even the hint of a context menu is started as the context 03344 // menus stack the automatic menu id and then restore it after they are destroyed. 03345 // This is bad if our main plug in menu ids are in this range! 03346 // We have to do it generally as at this point we don't know whether we are over a node 03347 // such as NodeBitmap which requires it. 03348 PlugInManager* pManager = GetApplication()->GetPlugInManager(); 03349 if (pManager) 03350 pManager->CheckHaveDetailsOnPlugIns(); 03351 #endif // PHOTOSHOPPLUGINS 03352 03353 // Pop up the context sensitive view menu. 03354 ViewContextMenu* pViewPopup = new ViewContextMenu; 03355 pViewPopup->ShowOverView(pSpread, DocPos, Mods); 03356 } 03357 #endif 03358 } 03359 // --------------------------------------------------------------------------- 03360 } 03361 else 03362 { 03363 if (Click==CLICKTYPE_UP) 03364 { 03365 if (Mods.EditObject) 03366 { 03367 // Find the node under the pointer and ask it what its favourite editing 03368 // tool is. 03369 } 03370 03371 else if (Mods.FullScreen) 03372 { 03373 // Use the full screen toggle. 03374 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor( OPTOKEN_VIEWFULLSCREEN ); 03375 if (pOpDesc) pOpDesc->Invoke(); 03376 } 03377 03378 else if (Mods.ZoomIn) 03379 { 03380 // Try to create an instance of the zoom operation. 03381 OpZoom* pZoomOp = new OpZoom; 03382 if (pZoomOp == NULL) 03383 { 03384 // We ran out of memory, so sorry. 03385 InformError(_R(IDE_NOMORE_MEMORY)); 03386 return; 03387 } 03388 03389 // Zoom in or out around the mouse position. 03390 if (Mods.Adjust) 03391 { 03392 pZoomOp->ZoomOut(LastWorkClick); 03393 } 03394 else 03395 { 03396 pZoomOp->ZoomIn(LastWorkClick); 03397 } 03398 } 03399 else if (Mods.PushCentreTool) 03400 { 03401 // Then the user wants us to centre the view about their mouse position 03402 } 03403 03404 } 03405 } 03406 03407 ViewFlags.WorkClickCached = FALSE; // Cached WorkCoord is no longer valid! 03408 } 03409 03410 03411 03412 /******************************************************************************************** 03413 > void DocView::OnMouseMove(OilCoord Pos, ClickModifiers mods) 03414 03415 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> (Updated by Tim & Rik) 03416 Created: 14 Oct 93 03417 Inputs: Pos - The position of the mouse, in OIL layer coordinates. 03418 mods - which buttons/keys are down. 03419 Purpose: Converts the mouse position into document coordinates, then calls the 03420 OnMouseMove() function of the currently selected tool with this 03421 information. 03422 03423 ********************************************************************************************/ 03424 03425 void DocView::OnMouseMove(OilCoord Pos, ClickModifiers mods) 03426 { 03427 // Ignore if system is disabled 03428 if (CCamApp::IsDisabled()) 03429 return; // If the system is disabled, ignore 03430 03431 Spread *pSpread = FindEnclosingSpread(Pos); 03432 if (pSpread != NULL) 03433 { 03434 // Convert from OIL coordinates to document coordinates 03435 DocCoord DocPos = Pos.ToDoc(pSpread, this ); 03436 03437 // Convert the coord to spread coords 03438 pSpread->DocCoordToSpreadCoord(&DocPos); 03439 03440 // Call the currently selected tool. 03441 Tool* pTool = Tool::GetCurrent(); 03442 03443 //Is there a currently selected tool? 03444 if (pTool != NULL) 03445 { 03446 // And pass the mouse move event to the tool. 03447 pTool->OnMouseMove(DocPos, pSpread, mods); 03448 } 03449 else 03450 //No, there's no currently selected tool. We're in Camelot so that's worrying. 03451 //Show an error. 03452 ERROR3("No current tool in DocView::OnMouseMove()!"); 03453 } 03454 } 03455 03456 03457 03458 /******************************************************************************************** 03459 > virtual BOOL DocView::HandleKeyPress(KeyPress* pKeyPress) 03460 03461 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03462 Created: 6/10/94 03463 Inputs: A pointer to the keypress event. 03464 Outputs: - 03465 Returns: TRUE if the event was handled by this function, or a function it called. 03466 Purpose: Passes keystroke events to the current drag op, if dragging, or the 03467 current tool, if not. 03468 Errors: - 03469 SeeAlso: App::OnKeyPress; Tool::OnKeyPress; Operation::DragKeyPress 03470 ********************************************************************************************/ 03471 03472 BOOL DocView::HandleKeyPress(KeyPress* pKeyPress) 03473 { 03474 // Ignore if system is disabled 03475 if (CCamApp::IsDisabled()) 03476 return FALSE; // If the system is disabled, ignore 03477 03478 // If we are dragging then pass the event on to the current drag operation. 03479 if (pCurrentDragOp != NULL) 03480 { 03481 // Handle the TAB key out here on behalf of ALL drag ops 03482 if (m_bSolidDragSupported && pKeyPress->IsPress() && !pKeyPress->IsRepeat()) // I.e. is this a non-auto-repeated key-down event? 03483 { 03484 switch (pKeyPress->GetVirtKey()) 03485 { 03486 // TAB key means "change solid dragging mode" 03487 case CAMKEY(TAB): 03488 { 03489 DocView::SolidDragging = !DocView::SolidDragging; 03490 m_bSolidDrag = (m_bSolidDragSupported && DocView::SolidDragging); 03491 pCurrentDragOp->DragModeChanged(m_bSolidDrag); 03492 03493 // update indicator in StatusLine 03494 DialogBarOp::SetSystemStateChanged(); 03495 break; 03496 } 03497 } 03498 } 03499 03500 return pCurrentDragOp->DragKeyPress(pKeyPress, m_bSolidDrag); 03501 } 03502 03503 // Otherwise give the current tool, if any, the chance to deal with it. 03504 Tool* pTool = Tool::GetCurrent(); 03505 return (pTool != NULL) ? pTool->OnKeyPress(pKeyPress) : FALSE; 03506 } 03507 03508 03509 03510 /******************************************************************************************** 03511 03512 > WorkCoord DocView::GetClickWorkCoord() 03513 03514 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03515 Created: 7/7/93 03516 Returns: The position of the last click in work coords 03517 Purpose: To let people know where the last click was in Work Coordinates 03518 03519 ********************************************************************************************/ 03520 03521 WorkCoord DocView::GetClickWorkCoord() 03522 { 03523 ERROR3IF(!ViewFlags.WorkClickCached, 03524 "DocView::GetClickWorkCoord called when WorkClickCached is FALSE"); 03525 return LastWorkClick; 03526 } 03527 03528 03529 03530 /******************************************************************************************** 03531 03532 > BOOL DocView::StartDrag(Operation* pDragOp, 03533 DragType type, 03534 DocRect* pMoveBBox, 03535 DocCoord* StartPos, 03536 BOOL KeepAccuracy, 03537 BOOL bSolidDragSupported) 03538 03539 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03540 Created: 2/7/93 03541 Inputs: pDragOp - Pointer to the operation 03542 type - the type of drag to do 03543 pMoveBBox - 03544 StartPos - 03545 KeepAccuracy - TRUE if drag is biased towards accurate following of all mouse 03546 movements; 03547 FALSE if drag is biased towards keeping up to date with user. 03548 bSolidDragSupported 03549 - FALSE (default) Do EORed outline dragging 03550 TRUE Update the tree during dragging 03551 Returns: TRUE if all went well 03552 Purpose: Tells the world that a drag is starting 03553 03554 ********************************************************************************************/ 03555 03556 BOOL DocView::StartDrag(Operation* pDragOp, 03557 DragType type, 03558 DocRect* pMoveBBox, 03559 DocCoord* StartPos, 03560 BOOL KeepAccuracy, 03561 BOOL bSolidDragSupported) 03562 { 03563 // Ignore if system is disabled 03564 if (CCamApp::IsDisabled()) 03565 return TRUE; // If the system is disabled, ignore 03566 03567 if (pMoveBBox != NULL) 03568 { 03569 StartDragPos = *StartPos; 03570 if (pMoveBBox->ContainsCoord(StartDragPos)) 03571 { 03572 } 03573 } 03574 03575 // Remember the drag operation (this also serves as a flag to indicate whether we 03576 // are dragging or not). 03577 ERROR3IF(pCurrentDragOp != NULL, "Nested drag in DocView::StartDrag"); 03578 ERROR3IF(pDragOp == NULL, "Null DragOp* in DocView::StartDrag?"); 03579 pCurrentDragOp = pDragOp; 03580 m_bSolidDragSupported = bSolidDragSupported; 03581 m_bSolidDrag = (m_bSolidDragSupported && DocView::SolidDragging); 03582 03583 ERROR3IF(pViewWindow==NULL, "ARGH! DocView is not connected to a window in StartDrag!"); 03584 return pViewWindow->StartDrag(pDragOp, type, KeepAccuracy); 03585 } 03586 03587 03588 03589 03590 /******************************************************************************************** 03591 03592 > BOOL DocView::EndDrag(Operation* pDragOp) 03593 03594 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 03595 Created: 2/7/93 03596 Inputs: pDragOp - The current operation 03597 Returns: TRUE if it workded 03598 Purpose: Tell the oil layer that the drag has finished 03599 03600 ********************************************************************************************/ 03601 03602 BOOL DocView::EndDrag(Operation* pDragOp) 03603 { 03604 ERROR3IF(pViewWindow == NULL, "ARGH! DocView is not connected to a window in EndDrag!"); 03605 // ERROR3IF(pCurrentDragOp == NULL, "Not dragging in DocView::EndDrag?"); 03606 // ERROR3IF(pDragOp != pCurrentDragOp, "DragOp pointer inconsistent in DocView::EndDrag"); 03607 pCurrentDragOp = NULL; 03608 03609 // Matt 12/01/2001 - Restore the cursor if we've changed it earlier to the push tool cursor... 03610 if (PushToolCursorID && (PushToolCursorID != 0)) 03611 { 03612 CursorStack::GPop(PushToolCursorID); 03613 PushToolCursorID = 0; 03614 } 03615 03616 return pViewWindow->EndDrag(pDragOp); 03617 } 03618 03619 03620 03621 /******************************************************************************************** 03622 03623 > BOOL DocView::ChangeDragType(DragType Type) 03624 03625 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 03626 Created: 3/4/95 03627 Inputs: Type - The type of drag to change to 03628 Returns: TRUE if it worked, FALSE if it failed 03629 Purpose: Change the type of drag during the middle of a drag. This can only be called 03630 if there is a drag already happening (ie between calls to StartDrag and 03631 EndDrag). 03632 Errors: ERROR3 if there is no render window or there is no drag happening 03633 SeeAlso: ScreenCamView::ChangeDragType 03634 03635 ********************************************************************************************/ 03636 03637 BOOL DocView::ChangeDragType(DragType Type) 03638 { 03639 TRACE( _T("Warning - DocView::ChangeDragType called\n") ); 03640 // A bit of error checking 03641 ERROR3IF(pViewWindow == NULL, "ARGH! DocView is not connected to a window in ChangeDragType!"); 03642 ERROR3IF(pCurrentDragOp == NULL, "Not dragging in ChangeDragType"); 03643 03644 // Ask the Oil side of things to change the drag 03645 BOOL Result = pViewWindow->ChangeDragType(Type); 03646 return Result; 03647 } 03648 03649 03650 03651 /******************************************************************************************** 03652 03653 > void DocView::RenderSelectBlobs( DocRect Rect ) 03654 03655 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 03656 Created: 16/9/93 03657 Inputs: Rect - The Clipping Rectangle of the bit to draw 03658 Purpose: Renders the Selection blobs of all the currently selected objects. 03659 SeeAlso: DocView::OnDraw 03660 03661 ********************************************************************************************/ 03662 03663 void DocView::RenderSelectBlobs( DocRect Rect, Spread *pSpread ) 03664 { 03665 // TRACEUSER("Gerry", _T("RenderSelectBlobs (%d, %d) - (%d, %d)\n"), Rect.lo.x, Rect.lo.y, Rect.hi.x, Rect.hi.y); 03666 03667 // Only render blobs if there is a selection, and this spread owns it. 03668 SelRange* Selected = GetApplication()->FindSelection(); 03669 03670 // Karim 29/06/2000 03671 // PromoteToParent should never be set TRUE on the selection range, outside 03672 // of code in which its modifications are required. 03673 // I have included a TRACE statement here, as a 'quiet' note to programmers, 03674 // should this occur. 03675 RangeControl rc = Selected->GetRangeControlFlags(); 03676 if (rc.PromoteToParent) 03677 { 03678 TRACE( _T("DocView::RenderSelectBlobs; PromoteToParent is TRUE! Read inline comment for details.\n") ); 03679 rc.PromoteToParent = FALSE; 03680 Selected->Range::SetRangeControl(rc); 03681 } 03682 03683 //PostProcessorStack* pStack = Selected->GetPostProcessorStack(); 03684 //ListRange* pLevel = pStack->GetNewLevelRange(FALSE); 03685 03686 Node* pNode = Selected->FindFirst(); 03687 //Node* pNode = pLevel->FindFirst(); 03688 if ((pNode == NULL) || ( pNode->FindParentSpread() != pSpread)) 03689 // This spread does not own selection 03690 return; 03691 03692 // Go find the blob manager 03693 BlobManager* BlobMgr = GetApplication()->GetBlobManager(); 03694 ERROR3IF( BlobMgr == NULL, "BlobManager unexpectedly turned out NULL!"); 03695 03696 // Go and render the blobs 03697 RenderRegion* pRender = DocView::RenderOnTop( &Rect, pSpread, ClippedEOR ); 03698 while (pRender) 03699 { 03700 pNode = Selected->FindFirst(); 03701 //pNode = pLevel->FindFirst(); 03702 while (pNode != NULL) 03703 { 03704 ERROR3IF(!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), 03705 "Selected node is not a NodeRenderableInk in DocView::RenderSelectBlobs()"); 03706 03707 // Make sure that the nodes bounding box overlaps the redraw box 03708 //if ( Rect.IsIntersectedWith(((NodeRenderableInk*)pNode)->GetBlobBoundingRect())) 03709 // tell the node to draw in its selection blobs 03710 // ((NodeRenderableInk*)pNode)->RenderSelectBlobs(); 03711 03712 // Render those blobs 03713 BlobMgr->RenderMyBlobs(&Rect, pSpread, (NodeRenderable*)pNode); 03714 03715 // Find the next selected node to render 03716 pNode = Selected->FindNext(pNode); 03717 //pNode = pLevel->FindNext(pNode); 03718 } 03719 03720 // Get the next render region 03721 pRender = DocView::GetNextOnTop(&Rect); 03722 } 03723 //delete pLevel; 03724 03725 // Bodge to stop fill meshes EOR each other out. 03726 AttrFillGeometry::LastRenderedMesh = NULL; 03727 } 03728 03729 03730 03731 /******************************************************************************************** 03732 03733 > BOOL DocView::IsMouseMoved() 03734 03735 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 03736 Created: 23/11/94 03737 Returns: TRUE if the mouse has moved, FALSE if not 03738 Purpose: This function finds out if the mouse has moved yet. This is only really 03739 useful if you are doing some processing as a result of a mouse move 03740 event. If, in the middle of your processing, you discover that the mouse 03741 has moved again, you may be able to stop processing immediatly and wait 03742 for the next mouse event to arrive in the not too distant future. 03743 SeeAlso: CCamView::IsWaitingMouseMove 03744 03745 ********************************************************************************************/ 03746 03747 BOOL DocView::IsMouseMoved() 03748 { 03749 PORTNOTETRACE("other","DocView::IsMouseMoved - do nothing"); 03750 #ifndef EXCLUDE_FROM_XARALX 03751 // If there is a Cam View about, ask it to see if there are more ouse messages 03752 // kicking about 03753 if (pViewWindow!=NULL) 03754 return pViewWindow->IsWaitingMouseMove(); 03755 #endif 03756 // there was no CamView, so no mouse messages 03757 return FALSE; 03758 } 03759 03760 03761 03762 /******************************************************************************************** 03763 > static BOOL DocView::GetCurrentMousePos(Spread** ppSpread, DocCoord* pdcMousePos) 03764 03765 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 03766 Created: 12/10/94 03767 Inputs: - 03768 Outputs: ppSpread pointer to a Spread pointer that will hold the spread 03769 containing the mouse 03770 pdcMousePos pointer to a DocCoord that will hold the coordinates of 03771 the mouse 03772 Returns: TRUE if the mouse is within the "selected" DocView, FALSE otherwise. 03773 Purpose: Reports the position of the mouse if it is within the "selected" DocView. 03774 It position is "returned" in Spread coordinates. 03775 Errors: - 03776 SeeAlso: CCamView::GetCurrentMousePos 03777 ********************************************************************************************/ 03778 03779 BOOL DocView::GetCurrentMousePos(Spread** ppSpread, DocCoord* pdcMousePos) 03780 { 03781 // Valid output arguments must be provided. 03782 ERROR3IF(ppSpread == NULL, "Null Spread** in DocView::GetCurrentMousePos"); 03783 ERROR3IF(pdcMousePos == NULL, "Null DocCoord* in DocView::GetCurrentMousePos"); 03784 03785 // Check if there is a "selected" DocView. 03786 if (Selected == NULL) return FALSE; 03787 03788 // Ask the CCamView attached to the selected DocView to report the mouse position. 03789 OilCoord pt; 03790 if (!Selected->pViewWindow->GetCurrentMousePos(&pt)) return FALSE; 03791 03792 // Convert the OIL coordinate to spread / doccoords. 03793 Spread* pSpread = Selected->FindEnclosingSpread(pt); 03794 if (pSpread == NULL) 03795 { 03796 ERROR3("Couldn't find a spread containing mouse position in DocView::GetCurrentMousePos"); 03797 return FALSE; 03798 } 03799 03800 // Convert the OSRect into document coords 03801 DocCoord dc = pt.ToDoc(pSpread, Selected ); 03802 03803 // Convert the coord to spread coords 03804 pSpread->DocCoordToSpreadCoord(&dc); 03805 03806 // Return result and success code to caller. 03807 *ppSpread = pSpread; 03808 *pdcMousePos = dc; 03809 return TRUE; 03810 } 03811 03812 03813 03814 03815 /******************************************************************************************** 03816 03817 > RenderRegion* DocView::GetFirstRenderRegion(const DocRect& ClipRect, Spread* pSpread, 03818 OnTopCode Reason ) 03819 03820 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 03821 Created: 23/8/93 03822 Inputs: ClipRect - The Rectangle to clip to 03823 pSpread - The Spread that the render region is for 03824 Reason - the kind of rendering needed 03825 Returns: A Ptr to a RenderRegion to render into. 03826 Purpose: RenderRegion's cannt span Spreads, because different Matrices are needed 03827 for the Coordinate transforms. This Function (Along with GetNext...) is 03828 used to Split a DocRect area into a number of RenderRegions depending on 03829 the number of spreads the DocRect spans. 03830 First call this function to return the first RenderRegion (there will always 03831 be at least one for a valid DocRect), and then call GetNextRenderRegion until 03832 it returns NULL (which may be immediately). Repeat the Rendering process for 03833 each RenderRegion returned. 03834 You do NOT need to call Init/Exit Render as they will be set up for 03835 Immediate rendering. 03836 SeeAlso: DocView::GetNextRenderRegion() 03837 03838 ********************************************************************************************/ 03839 03840 RenderRegion* DocView::GetFirstRenderRegion(DocRect& ClipRect, Spread *pSpread, OnTopCode Reason) 03841 { 03842 // Construct the transformation matrix for the spread. 03843 Matrix RenderMatrix = ConstructRenderingMatrix(pSpread); 03844 03845 // Make render region for intersection between spread and cliprect. 03846 // (Cliprect is still d) 03847 DocRect SpreadClipRect = pSpread->GetWidePasteboard(this); 03848 03849 // Convert the coord to spread coords 03850 pSpread->DocCoordToSpreadCoord(&SpreadClipRect); 03851 03852 // Clip to spread rectangle, if required 03853 if (Reason == ClippedEOR) 03854 SpreadClipRect = SpreadClipRect.Intersection(ClipRect); 03855 else 03856 SpreadClipRect = ClipRect; 03857 03858 // Make sure that the clip region is valid after the intersection 03859 if ( (SpreadClipRect.IsValid()) && (!SpreadClipRect.IsEmpty()) ) 03860 { 03861 RenderType rType = RENDERTYPE_NONE; // Initialise it! Mark H 03862 03863 switch (Reason) 03864 { 03865 case CLICKBITMAP: rType = RENDERTYPE_HITDETECT; break; 03866 case COLOURBITMAP: rType = RENDERTYPE_COLOURBITMAP; break; 03867 case Normal: rType = RENDERTYPE_SCREEN; 03868 default: rType = RENDERTYPE_SCREENXOR; break; 03869 } 03870 03871 CNativeDC* pDC = pViewWindow->GetRenderDC(); 03872 ERROR3IF(!pDC, "No allocated DC"); 03873 03874 RenderRegion *NewRegion = View::NewRenderRegion(SpreadClipRect, RenderMatrix, 03875 pDC, pSpread, rType); 03876 03877 if (NewRegion == NULL) 03878 TRACEALL( _T("Not enough memory to create render region\n") ); 03879 else 03880 NewRegion->ImmediateRender(); 03881 03882 return NewRegion; 03883 } 03884 03885 // No render region could be created as the spread clip rect was empty or invalid 03886 return NULL; 03887 } 03888 03889 03890 03891 /******************************************************************************************** 03892 03893 > RenderRegion* DocView::GetNextRenderRegion(const DocRect& ClipRect, Spread* pSpread, 03894 OnTopCode Reason) 03895 03896 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 03897 Created: 23/8/93 03898 Inputs: ClipRect - The Rectangle to clip to 03899 pSpread - The Spread that the render region is for 03900 Reason - the kind of rendering needed 03901 Returns: A Ptr to a RenderRegion to render into. 03902 Purpose: Used to split a DocRect to be redrawn into one or more RenderRegions. 03903 See DocView::GetFirstRenderRegion(DocRect& ClipRect) for more details. 03904 SeeAlso: DocView::GetFirstRenderRegion() 03905 03906 ********************************************************************************************/ 03907 03908 RenderRegion* DocView::GetNextRenderRegion(DocRect& ClipRect, Spread *pSpread, OnTopCode Reason) 03909 { 03910 // This needs to be expanded! 03911 // It's ok for Windows, but maybe not for other platforms... 03912 return NULL; 03913 } 03914 03915 03916 03917 /******************************************************************************************** 03918 03919 > RenderRegion* DocView::RenderOnTop( DocRect* Rect, OnTopCode Reason ) 03920 03921 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 03922 Created: 18/8/93 03923 Inputs: Rect - The DocRect of the area that needs to be redrawn 03924 Reason - EOR or Normal or CLICKBITMAP 03925 Returns: A pointer to a render region, or NULL if a valid RRegion could not 03926 be generated (or there were none to make in the first place 03927 Purpose: Marks the start of an 'On Top' rendering loop. On Top simply means that 03928 the rendering will be done directly over the top of anything else that 03929 happens to be there, without causeing a redraw from the bottom of the tree. 03930 This functions main use is drawing on the EOR blobs that show selection, are 03931 part of a tool or are there to show a drag is in progress. This function could 03932 also be used to draw objects that we know will be placed on top of all other 03933 objects (ie a new object, being drawn for the first time). 03934 You should always use a loop like the one below :- 03935 MonoOn 03936 RenderRegion* pRegion = DocView::RenderOnTop( MyRect, EOR ); 03937 while ( pRegion ) 03938 { 03939 // Do your EOR rendering in here 03940 pRegion = DocView::GetNextOnTop( MyRect ); 03941 } 03942 MonoOff 03943 This bit of code will loop through all the invalid regions that the OS needs 03944 redrawing as well as all the rectangles that Camelot splits a region into 03945 itself. 03946 IMPORTANT : Because this is a loop, you should not change the state of any 03947 data within it, because it will then be different the second time the code 03948 in the loop is executed. 03949 SeeAlso: DocView::GetNextOnTop 03950 03951 ********************************************************************************************/ 03952 03953 RenderRegion* DocView::RenderOnTop( DocRect* Rect, Spread *pSpread, OnTopCode Reason ) 03954 { 03955 RenderRegion* pRender = NULL; //RenderRegion::GetCurrent(); 03956 03957 if ( OnTopCount == 0 ) 03958 { 03959 // Find out about the current view 03960 DocView* pCurrentView = GetSelected(); 03961 03962 // If there is no current view, then return NULL 03963 if (pCurrentView==NULL) 03964 return NULL; 03965 03966 // We should only hand out render regions if the view is not in the process of dying 03967 if (pCurrentView->IsViewDying) 03968 return NULL; 03969 03970 // if the spread is NULL then this is bad 03971 if (pSpread==NULL) 03972 return NULL; 03973 03974 // Find the first rectangle or region that needs redrawing and make 03975 // a render region for it. 03976 DocRect ClipRect; 03977 if (Rect == NULL) 03978 { 03979 // Get the DocView's viewport, in Spread Coords 03980 ClipRect = pCurrentView->GetDocViewRect(pSpread); 03981 pSpread->DocCoordToSpreadCoord(&ClipRect); 03982 } 03983 else 03984 ClipRect = *Rect; 03985 03986 // Make sure that the clip rect is valid 03987 if (!ClipRect.IsValid()) 03988 { 03989 // The Clip rect was not a valid rectangle 03990 ERROR3("RenderOnTop was asked to render to an invalid rect."); 03991 return NULL; 03992 } 03993 03994 // Go and get a render region based on all this info 03995 pRender = pCurrentView->GetFirstRenderRegion(ClipRect, pSpread, Reason); 03996 03997 // stop now if we did not get one 03998 if ( !pRender ) 03999 return NULL; 04000 04001 // Set the static Reason code so that all future calls to RenderOnTop and 04002 // GetNextOnTop will do the same thing 04003 OnTopReason = Reason; 04004 OnTopSpread = pSpread; 04005 OnTopRenderRegion = pRender; 04006 04007 // Turn on EORing for the RenderRegion if needed 04008 if (( OnTopReason == UnclippedEOR ) || (OnTopReason == ClippedEOR)) 04009 pRender -> SetDrawingMode( DM_EORPEN ); 04010 04011 // Increment the Static Counter so that we know how many times this 04012 // function has been called 04013 OnTopCount++; 04014 04015 // return the render region 04016 return pRender; 04017 } 04018 else 04019 { 04020 // Get the current RenderOnTop RenderRegion 04021 pRender = OnTopRenderRegion; 04022 04023 // If there is no current render region, then we had better stop now 04024 if (!pRender) 04025 return NULL; 04026 04027 // Increment the Static Counter so that we know how many times this 04028 // function has been nested through 04029 OnTopCount++; 04030 04031 // if we want to be EORing, then make sure that EORing has been switched on 04032 if (( OnTopReason == UnclippedEOR ) || (OnTopReason == ClippedEOR)) 04033 pRender -> SetDrawingMode( DM_EORPEN ); 04034 04035 // return the current render region 04036 return pRender; 04037 } 04038 } 04039 04040 04041 04042 04043 04044 /******************************************************************************************** 04045 04046 > RenderRegion* DocView::GetNextOnTop(DocRect* Rect) 04047 04048 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 04049 Created: 18/8/93 04050 Inputs: Rect - A pointer to the DocRect that the Rendering is to be clipped to 04051 Returns: A RenderRegion if there is another valid one to be rendered into, or 04052 NULL if there is not 04053 Purpose: This function continues the RenderOnTop loop, returning the next 04054 RenderRegion to be considered. If we are not in the outer most 04055 rendering loop then this function will return NULL, as it will be 04056 up to the top level to re-call everyone with the next render region. 04057 It should always be used as part of a rendering loop as described in 04058 DocView::RenderOnTop. 04059 SeeAlso: DocView::RenderOnTop 04060 04061 ********************************************************************************************/ 04062 04063 RenderRegion* DocView::GetNextOnTop( DocRect* Rect ) 04064 { 04065 ERROR3IF( OnTopCount <= 0, "GetNextOnTop was called before RenderOnTop was called\n" ); 04066 04067 RenderRegion* pRender = OnTopRenderRegion; 04068 04069 if (OnTopCount == 1) 04070 { 04071 // Delete the old render region that is no longer needed 04072 if (pRender!=NULL) 04073 { 04074 pRender->StopRender(); 04075 04076 if (( OnTopReason == UnclippedEOR ) || (OnTopReason == ClippedEOR)) 04077 { 04078 // Detach the Static OnTopRegion 04079 View::DeInitOnTopRegion(); 04080 } 04081 else 04082 { 04083 delete pRender; 04084 } 04085 04086 pRender = NULL; 04087 OnTopRenderRegion = NULL; 04088 } 04089 04090 // Find the current view 04091 DocView* pView = GetSelected(); 04092 if (pView==NULL) 04093 return NULL; 04094 04095 // Get the next rectangle or region and make a RenderRegion 04096 DocRect ClipRect; 04097 if (Rect == NULL) 04098 { 04099 // Get the DocView's viewport and convert it from document coords to 04100 // spread coords 04101 ClipRect = pView->GetDocViewRect(OnTopSpread); 04102 OnTopSpread->DocCoordToSpreadCoord(&ClipRect); 04103 } 04104 else 04105 ClipRect = *Rect; 04106 04107 // Go and build a new render region 04108 pRender = pView->GetNextRenderRegion(ClipRect, OnTopSpread, OnTopReason); 04109 OnTopRenderRegion = pRender; 04110 04111 // See if we got one 04112 if (!pRender) 04113 { 04114 // There were no more render regions, so decrement the call count and 04115 // return NULL 04116 OnTopCount--; 04117 return NULL; 04118 } 04119 04120 // Turn on EORing for the RenderRegion if needed 04121 if ((OnTopReason == UnclippedEOR) || (OnTopReason == ClippedEOR)) 04122 pRender->SetDrawingMode(DM_EORPEN); 04123 04124 // return the render region 04125 return pRender; 04126 } 04127 else 04128 { 04129 // It is not up to this level to try and find more RenderRegions 04130 // so decrement the counter 04131 OnTopCount--; 04132 04133 // No more RenderRegions here, so return NULL 04134 return NULL; 04135 } 04136 04137 return NULL; 04138 } 04139 04140 04141 04142 04143 /******************************************************************************************** 04144 04145 > Spread* DocView::OilToSpreadCoord(OilCoord oilpos, DocCoord* pdocpos) 04146 04147 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 04148 Created: 22/11/94 04149 Inputs: oilpos - OilCoord to find spread and DocCoord for. 04150 Outputs: pdocpos - Pointer to DocCoord to receive DocCoord. 04151 Returns: Spread* - Pointer to spread in which pdocpos is valid. 04152 Purpose: Combines the functions of FindEnclosingSpread and OilCoord::ToDoc. 04153 Finds which spread an OilCoord is in and then computes the DocCoord of 04154 that position within the spread. 04155 04156 ********************************************************************************************/ 04157 04158 Spread* DocView::OilToSpreadCoord(OilCoord oilpos, DocCoord* pdocpos) 04159 { 04160 // Preconditions 04161 ERROR2IF(this==NULL,NULL,"DocView::OilToDoc called on NULL pointer"); 04162 04163 // Clear the destination DocCoord in case it all goes horribly wrong... 04164 *pdocpos = DocCoord(0,0); 04165 04166 // Find the spread that contains DocPos, if none then return NULL immediately... 04167 Spread *pSpread = FindEnclosingSpread(oilpos); 04168 if (pSpread != NULL) 04169 { 04170 // Convert the OilCoord into document coords... 04171 *pdocpos = oilpos.ToDoc(pSpread, this); 04172 04173 // and then into Spread coords... 04174 pSpread->DocCoordToSpreadCoord(pdocpos); 04175 } 04176 04177 // Return pointer to enclosing spread to caller. 04178 return pSpread; 04179 } 04180 04181 04182 04183 /******************************************************************************************** 04184 04185 > Spread *DocView::FindEnclosingSpread(OilCoord Pos) 04186 04187 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 04188 Created: 15/12/93 04189 Inputs: Pos - the coord to look for. 04190 Returns: The spread that contains the coordinate, or NULL if such a spread does not 04191 exist. 04192 Purpose: Given a chapter and an OilCoord, finds the spread that contains the 04193 coordinate. 04194 04195 ********************************************************************************************/ 04196 04197 Spread *DocView::FindEnclosingSpread(OilCoord Pos) 04198 { 04199 // Find first spread in chapter 04200 Chapter* pChapter = Node::FindFirstChapter(pDoc); 04201 if (pChapter==NULL) 04202 { 04203 ERROR3( "There was no chapter in this document"); 04204 return NULL; 04205 } 04206 04207 Spread* pSpread = (Spread*)pChapter->FindFirstChild(); 04208 ERROR3IF((pSpread == NULL) || !pSpread->IsSpread(), "Chapter has no spreads"); 04209 04210 // Optimisation for simple documents: 04211 // If only one chapter containing only one spread then that must be the 04212 // enclosing spread! 04213 if (pSpread && (pSpread->FindNext()==NULL || !pSpread->FindNext()->IsSpread()) && pChapter->FindNext()==NULL) 04214 return pSpread; 04215 04216 // If the cursor was above the top of the document, then return the first spread 04217 // if there is one 04218 if (Pos.y >= 0) 04219 return pSpread; 04220 04221 // Find this position in 64-bit work coords 04222 WorkCoord WorkPos = Pos.ToWork( pVState->GetScrollPos() ); 04223 04224 do 04225 { 04226 pSpread = (Spread *) pChapter->FindFirstChild(); 04227 ERROR3IF((pSpread == NULL) || !pSpread->IsSpread(), 04228 "Chapter has no spreads"); 04229 04230 do 04231 { 04232 // Convert spread bounding box to logical coords 04233 DocRect PhysSpreadRect = pSpread->GetWidePasteboard(this); 04234 WorkRect LogSpreadRect; 04235 LogSpreadRect.lo = PhysSpreadRect.lo.ToWork(pSpread, this); 04236 LogSpreadRect.hi = PhysSpreadRect.hi.ToWork(pSpread, this); 04237 04238 // Check if spread intersects the clipping rect 04239 if ((WorkPos.y <= LogSpreadRect.hi.y) && 04240 (WorkPos.y >= LogSpreadRect.lo.y)) 04241 { 04242 // Found the correct spread so stop looking. 04243 return pSpread; 04244 } 04245 04246 // try next spread 04247 pSpread = (Spread *) pSpread->FindNext(); 04248 ERROR3IF((pSpread != NULL) && !(pSpread->IsSpread()), 04249 "Spread is not a Spread!"); 04250 04251 } while (pSpread != NULL); 04252 04253 // Was not in that chapter, so try the next one 04254 pChapter = (Chapter*) pChapter->FindNext(); 04255 ERROR3IF( (pChapter!=NULL) && !(pChapter->IsKindOf(CC_RUNTIME_CLASS(Chapter))), 04256 "Chapter is not a Chapter!" ); 04257 04258 } while (pChapter != NULL); 04259 04260 04261 ERROR3IF( pSpread == NULL, "Could not find spread in which the click happened"); 04262 04263 return pSpread; 04264 } 04265 04266 //---------------------------------------------------------------------------- 04267 //---------------------------------------------------------------------------- 04268 //---------------------------------------------------------------------------- 04269 //---------------------------------------------------------------------------- 04270 04271 /******************************************************************************************** 04272 04273 > BOOL DocView::Snap(Spread* pSpread,DocCoord* pDocCoord, 04274 BOOL TryMagSnap = TRUE, 04275 BOOL TryGridSnap = TRUE) 04276 04277 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04278 Created: 14/2/94 (modified 20/9/94) 04279 Inputs: pSpread = a ptr to a spread node 04280 pDocCoord = a coord relative to the given spread 04281 Returns: TRUE - The coord has been snapped to something 04282 FALSE - The coord is untouched by man and beast 04283 Purpose: Allows you to easily snap a coord to something relevant in the given spread 04284 (e.g. to a grid, magnetic object, etc). 04285 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04286 04287 ********************************************************************************************/ 04288 04289 BOOL DocView::Snap(Spread* pSpread,DocCoord* pDocCoord, 04290 BOOL TryMagSnap, 04291 BOOL TryGridSnap) 04292 { 04293 BOOL Snapped = FALSE; 04294 04295 if (pCSnap == NULL) 04296 pCSnap = new CSnap(this,pSpread); 04297 04298 if (pCSnap != NULL) 04299 { 04300 pCSnap->SetSpread(pSpread); 04301 Snapped = pCSnap->Snap(pDocCoord,TryMagSnap,TryGridSnap); 04302 } 04303 04304 return (Snapped); 04305 } 04306 04307 /******************************************************************************************** 04308 04309 > BOOL DocView::Snap(Spread* pSpread,DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 04310 04311 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04312 Created: 14/2/94 (modified 20/9/94) 04313 Inputs: pSpread = a ptr to a spread node 04314 pDocRect = a rectangle relative to the given spread 04315 PrevCoord = Used to determine how rect is snapped 04316 CurCoord = As above 04317 Returns: TRUE - The rect has been snapped to something 04318 FALSE - The rect is untouched by man and beast 04319 Purpose: Allows you to easily snap a rectangle to something relevant in the given spread 04320 (e.g. to a grid, magnetic object, etc). 04321 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04322 04323 ********************************************************************************************/ 04324 04325 BOOL DocView::Snap(Spread* pSpread,DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 04326 { 04327 BOOL Snapped = FALSE; 04328 04329 if (pCSnap == NULL) 04330 pCSnap = new CSnap(this,pSpread); 04331 04332 if (pCSnap != NULL) 04333 { 04334 pCSnap->SetSpread(pSpread); 04335 Snapped = pCSnap->Snap(pDocRect,PrevCoord,CurCoord); 04336 } 04337 04338 return (Snapped); 04339 } 04340 04341 /******************************************************************************************** 04342 04343 > static BOOL DocView::ForceSnapToGuides(Spread* pSpread, DocCoord* pDocCoord, GuidelineType Type) 04344 04345 Author: Martin Wuerthner <xara@mw-software.com> 04346 Created: 24/08/06 04347 Inputs: pSpread Pointer to spread on which node exists 04348 pDocCoord A coordinate to test magnetically against the node 04349 Returns: TRUE - The coord has been snapped to something 04350 FALSE - The coord is untouched by man and beast 04351 Purpose: Calls guideline snapper ignoring enabling flags. 04352 Errors: Will error in debug builds if there is no selected DocView 04353 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04354 04355 ********************************************************************************************/ 04356 04357 BOOL DocView::ForceSnapToGuides(Spread* pSpread, DocCoord* pDocCoord, GuidelineType Type) 04358 { 04359 ERROR3IF(Selected == NULL,"DocView::ForceSnapToGuides called when no selected DocView"); 04360 04361 if (Selected != NULL) 04362 { 04363 BOOL Snapped = FALSE; 04364 04365 if (Selected->pCSnap == NULL) 04366 Selected->pCSnap = new CSnap(Selected,pSpread); 04367 04368 if (Selected->pCSnap != NULL) 04369 { 04370 Selected->pCSnap->SetSpread(pSpread); 04371 Snapped = Selected->pCSnap->SnapToGuidelines(pDocCoord, Type); 04372 } 04373 04374 return (Snapped); 04375 } 04376 else 04377 return (FALSE); 04378 } 04379 04380 /******************************************************************************************** 04381 04382 > BOOL DocView::SnapSelected(Spread* pSpread,DocCoord* pDocCoord, 04383 BOOL TryMagSnap = TRUE, 04384 BOOL TryGridSnap = TRUE) 04385 04386 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04387 Created: 14/2/94 04388 Inputs: pSpread = a ptr to a spread node 04389 pDocCoord = a coord relative to the given spread 04390 Returns: TRUE - The coord has been snapped to something 04391 FALSE - The coord is untouched by man and beast 04392 Purpose: Calls the Snap(pSpread,pDocCoord) function of the selected DocView. 04393 Errors: Will error in debug builds if there is no selected DocView 04394 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04395 04396 ********************************************************************************************/ 04397 04398 BOOL DocView::SnapSelected(Spread* pSpread,DocCoord* pDocCoord, 04399 BOOL TryMagSnap, 04400 BOOL TryGridSnap) 04401 { 04402 ERROR3IF(Selected == NULL,"DocView::SnapSelected called when no selected DocView"); 04403 04404 if (Selected != NULL) 04405 return (Selected->Snap(pSpread,pDocCoord,TryMagSnap,TryGridSnap)); 04406 else 04407 return (FALSE); 04408 } 04409 04410 /******************************************************************************************** 04411 04412 > static BOOL DocView::SnapToMagneticNode(Spread* pSpread, Node* pNode, DocCoord* pDocCoord) 04413 04414 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 04415 Created: 25/3/94 04416 Inputs: pSpread Pointer to spread on which node exists 04417 pNode Pointer to node to test magnetically 04418 pDocCoord A coordinate to test magnetically against the node 04419 Returns: TRUE - The coord has been snapped to something 04420 FALSE - The coord is untouched by man and beast 04421 Purpose: Calls magnetic snapping functions taking into acount the control flags 04422 held in this DocView. 04423 Errors: Will error in debug builds if there is no selected DocView 04424 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04425 04426 ********************************************************************************************/ 04427 04428 BOOL DocView::SnapToMagneticNode(Spread* pSpread, Node* pNode, DocCoord* pDocCoord) 04429 { 04430 ERROR3IF(Selected == NULL,"DocView::SnapSelected called when no selected DocView"); 04431 04432 if (Selected != NULL) 04433 { 04434 BOOL Snapped = FALSE; 04435 04436 if (Selected->pCSnap == NULL) 04437 Selected->pCSnap = new CSnap(Selected,pSpread); 04438 04439 if (Selected->pCSnap != NULL) 04440 { 04441 Selected->pCSnap->SetSpread(pSpread); 04442 Snapped = Selected->pCSnap->TryToSnapToObject(pNode, pDocCoord); 04443 } 04444 04445 return (Snapped); 04446 } 04447 else 04448 return (FALSE); 04449 } 04450 04451 /******************************************************************************************** 04452 04453 > static BOOL DocView::ForceSnapToGrid(Spread* pSpread, DocCoord* pDocCoord) 04454 04455 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 04456 Created: 28/3/94 04457 Inputs: pSpread Pointer to spread on which node exists 04458 pDocCoord A coordinate to test magnetically against the node 04459 Returns: TRUE - The coord has been snapped to something 04460 FALSE - The coord is untouched by man and beast 04461 Purpose: Calls grid snapper ignoring enabling flags. 04462 Errors: Will error in debug builds if there is no selected DocView 04463 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04464 04465 ********************************************************************************************/ 04466 04467 BOOL DocView::ForceSnapToGrid(Spread* pSpread, DocCoord* pDocCoord) 04468 { 04469 ERROR3IF(Selected == NULL,"DocView::SnapSelected called when no selected DocView"); 04470 04471 if (Selected != NULL) 04472 { 04473 BOOL Snapped = FALSE; 04474 04475 if (Selected->pCSnap == NULL) 04476 Selected->pCSnap = new CSnap(Selected,pSpread); 04477 04478 if (Selected->pCSnap != NULL) 04479 { 04480 Selected->pCSnap->SetSpread(pSpread); 04481 Snapped = Selected->pCSnap->SnapToGrids(pDocCoord); 04482 } 04483 04484 return (Snapped); 04485 } 04486 else 04487 return (FALSE); 04488 } 04489 04490 /******************************************************************************************** 04491 04492 > BOOL DocView::SnapSelected(Spread* pSpread,DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 04493 04494 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04495 Created: 14/2/94 04496 Inputs: pSpread = a ptr to a spread node 04497 pDocRect = a rectangle relative to the given spread 04498 PrevCoord = Used to determine how rect is snapped 04499 CurCoord = As above 04500 Returns: TRUE - The rect has been snapped to something 04501 FALSE - The rect is untouched by man and beast 04502 Purpose: Calls the Snap(pSpread,pDocRect,PrevCoord,CurCoord) function of the selected DocView. 04503 Errors: Will error in debug builds if there is no selected DocView 04504 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04505 04506 ********************************************************************************************/ 04507 04508 BOOL DocView::SnapSelected(Spread* pSpread,DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 04509 { 04510 ERROR3IF(Selected == NULL,"DocView::SnapSelected called when no selected DocView"); 04511 04512 if (Selected != NULL) 04513 return (Selected->Snap(pSpread,pDocRect,PrevCoord,CurCoord)); 04514 else 04515 return (FALSE); 04516 } 04517 04518 /******************************************************************************************** 04519 04520 > BOOL DocView::SnapCurrent(Spread* pSpread,DocCoord* pDocCoord, 04521 BOOL TryMagSnap = TRUE, 04522 BOOL TryGridSnap = TRUE) 04523 04524 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04525 Created: 14/2/94 04526 Inputs: pSpread = a ptr to a spread node 04527 pDocCoord = a coord relative to the given spread 04528 Returns: TRUE - The coord has been snapped to something 04529 FALSE - The coord is untouched by man and beast 04530 Purpose: Calls the Snap(pSpread,pDocCoord) function of the Current DocView. 04531 Errors: Will error in debug builds if there is no Current DocView 04532 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04533 04534 ********************************************************************************************/ 04535 04536 BOOL DocView::SnapCurrent(Spread* pSpread,DocCoord* pDocCoord, 04537 BOOL TryMagSnap, 04538 BOOL TryGridSnap) 04539 { 04540 ERROR3IF(Current == NULL,"DocView::SnapCurrent called when no Current DocView"); 04541 04542 DocView *pCurrent = GetCurrent(); 04543 04544 if (pCurrent != NULL) 04545 return (pCurrent->Snap(pSpread,pDocCoord,TryMagSnap,TryGridSnap)); 04546 else 04547 return (FALSE); 04548 } 04549 04550 /******************************************************************************************** 04551 04552 > BOOL DocView::SnapCurrent(Spread* pSpread,DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 04553 04554 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04555 Created: 14/2/94 04556 Inputs: pSpread = a ptr to a spread node 04557 pDocRect = a rectangle relative to the given spread 04558 PrevCoord = Used to determine how rect is snapped 04559 CurCoord = As above 04560 Returns: TRUE - The rect has been snapped to something 04561 FALSE - The rect is untouched by man and beast 04562 Purpose: Calls the Snap(pSpread,pDocRect,PrevCoord,CurCoord) function of the Current DocView. 04563 Errors: Will error in debug builds if there is no Current DocView 04564 SeeAlso: All Snap member functions of all classes derived from NodeRenderableBounded. 04565 04566 ********************************************************************************************/ 04567 04568 BOOL DocView::SnapCurrent(Spread* pSpread,DocRect* pDocRect,const DocCoord& PrevCoord,const DocCoord& CurCoord) 04569 { 04570 ERROR3IF(Current == NULL,"DocView::SnapCurrent called when no Current DocView"); 04571 04572 DocView *pCurrent = GetCurrent(); 04573 04574 if (pCurrent != NULL) 04575 return (pCurrent->Snap(pSpread,pDocRect,PrevCoord,CurCoord)); 04576 else 04577 return (FALSE); 04578 } 04579 04580 //---------------------------------------------------------------------------- 04581 04582 /******************************************************************************************** 04583 04584 > void DocView::SetSnapToGridState(BOOL SnapToGrid) 04585 04586 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04587 Created: 14/2/94 04588 Inputs: SnapToGrid - A bool used to set the snap status of grids in the view 04589 Returns: - 04590 Purpose: Allow you to change the "snap to grid" state of a DocView. 04591 SeeAlso: 04592 04593 ********************************************************************************************/ 04594 04595 void DocView::SetSnapToGridState(BOOL SnapToGrid) 04596 { 04597 ViewFlags.GridSnap = SnapToGrid; 04598 } 04599 04600 /******************************************************************************************** 04601 04602 > BOOL DocView::GetSnapToGridState() 04603 04604 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04605 Created: 14/2/94 04606 Inputs: - 04607 Returns: TRUE - snap to grids in the doc view 04608 FALSE - don't snap to grids in the doc view 04609 Purpose: To find the "Snap to grid" state of a DocView 04610 SeeAlso: 04611 04612 ********************************************************************************************/ 04613 04614 BOOL DocView::GetSnapToGridState() 04615 { 04616 return (ViewFlags.GridSnap); 04617 } 04618 04619 /******************************************************************************************** 04620 04621 > void DocView::SetSnapToObjectsState(BOOL SnapToObjects) 04622 04623 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04624 Created: 20/9/94 04625 Inputs: SnapToObjects - A bool used to set the snap status of all objects in the view 04626 Returns: - 04627 Purpose: Allow you to change the "snap to all objects" state of a DocView. 04628 SeeAlso: 04629 04630 ********************************************************************************************/ 04631 04632 void DocView::SetSnapToObjectsState(BOOL SnapToObjects) 04633 { 04634 ViewFlags.ObjectsSnap = SnapToObjects; 04635 } 04636 04637 /******************************************************************************************** 04638 04639 > BOOL DocView::GetSnapToObjectsState() 04640 04641 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04642 Created: 20/9/94 04643 Inputs: - 04644 Returns: TRUE - snap to objects in the doc view 04645 FALSE - don't snap to objects in the doc view 04646 Purpose: To find the "Snap to all objects" state of a DocView 04647 SeeAlso: 04648 04649 ********************************************************************************************/ 04650 04651 BOOL DocView::GetSnapToObjectsState() 04652 { 04653 return (ViewFlags.ObjectsSnap); 04654 } 04655 04656 /******************************************************************************************** 04657 04658 > void DocView::SetSnapToMagObjectsState(BOOL SnapToMagObjects) 04659 04660 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04661 Created: 20/9/94 04662 Inputs: SnapToMagObjects - A bool used to set the snap status of magnetic objects in the view 04663 Returns: - 04664 Purpose: Allow you to change the "snap to magnetic objects" state of a DocView. 04665 SeeAlso: 04666 04667 ********************************************************************************************/ 04668 04669 void DocView::SetSnapToMagObjectsState(BOOL SnapToMagObjects) 04670 { 04671 ViewFlags.MagObjectsSnap = SnapToMagObjects; 04672 } 04673 04674 /******************************************************************************************** 04675 04676 > BOOL DocView::GetSnapToMagObjectsState() 04677 04678 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04679 Created: 20/9/94 04680 Inputs: - 04681 Returns: TRUE - snap to magnetic objects in the doc view 04682 FALSE - don't snap to magnetic objects in the doc view 04683 Purpose: To find the "Snap to magnetic objects" state of a DocView 04684 SeeAlso: 04685 04686 ********************************************************************************************/ 04687 04688 BOOL DocView::GetSnapToMagObjectsState() 04689 { 04690 return (ViewFlags.MagObjectsSnap); 04691 } 04692 04693 /******************************************************************************************** 04694 04695 > void DocView::SetShowGridState(BOOL ShowGrid) 04696 04697 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04698 Created: 14/2/94 04699 Inputs: ShowGrid - A bool used to set the visible status of grids in the view 04700 Returns: - 04701 Purpose: Allow you to change the "show grid" state of a DocView. 04702 SeeAlso: 04703 04704 ********************************************************************************************/ 04705 04706 void DocView::SetShowGridState(BOOL ShowGrid) 04707 { 04708 ViewFlags.GridShow = ShowGrid; 04709 } 04710 04711 /******************************************************************************************** 04712 04713 > BOOL DocView::GetShowGridState() 04714 04715 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 04716 Created: 14/2/94 04717 Inputs: - 04718 Returns: TRUE - grids are visible in the doc view 04719 FALSE - grids are not visible in the doc view 04720 Purpose: To find the "Show grid" state of a DocView 04721 SeeAlso: 04722 04723 ********************************************************************************************/ 04724 04725 BOOL DocView::GetShowGridState() 04726 { 04727 return (ViewFlags.GridShow); 04728 } 04729 04730 04731 //---------------------------------------------------------------------------- 04732 //---------------------------------------------------------------------------- 04733 //---------------------------------------------------------------------------- 04734 //---------------------------------------------------------------------------- 04735 //---------------------------------------------------------------------------- 04736 04737 04738 04739 04740 /******************************************************************************************** 04741 04742 > static void DocView::ConstrainToAngle(DocCoord& Centre, DocCoord* CurCoord, 04743 double Constrain = 0.0) 04744 04745 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 04746 Created: 14/7/94 04747 Inputs: Centre - The point that all the constrain rays come from 04748 Constrain - The constrain angle in Radians. You should not pass in this 04749 param except in very special circumstances. When this param is left out 04750 the constrain angle from the users preferences is used, which should be 04751 the way it is done in almost all circumstances. 04752 Outputs: CurCoord - contains the mouse coord on entry and contains the constrained 04753 mouse coord afterwards 04754 Purpose: Constrains the mouse movement to rays coming out from a central point. This 04755 is ideal for rotation etc. You should use this version of the function as 04756 the other verison of the function is being phased out right now. 04757 04758 ********************************************************************************************/ 04759 04760 void DocView::ConstrainToAngle(DocCoord& Centre, DocCoord* CurCoord, double Constrain) 04761 { 04762 if (Constrain==0.0) 04763 { 04764 // Use the angle found in the preferences 04765 Constrain = DefaultConstrainAngle; 04766 } 04767 04768 // Find out which of the 2 axis are the most significant 04769 double dx = CurCoord->x - Centre.x; 04770 double dy = CurCoord->y - Centre.y; 04771 04772 // make sure that the cursor is not over the origin 04773 if ((dx==0) && (dy==0)) 04774 return; 04775 04776 // Find the square of the length of the ray 04777 double RayLength = sqrt((dy*dy) + (dx*dx)); 04778 04779 // Find the angle that this coord is around a circle 04780 double Angle = atan2(dy, dx); 04781 04782 // constrain the angle to the nearest band 04783 double SnapAngle = (Angle + (Constrain/2)) / Constrain; 04784 SnapAngle = floor(SnapAngle); 04785 SnapAngle *= Constrain; 04786 04787 // recalculate the new coordinate for the cursor 04788 dx = (INT32)(RayLength * cos(SnapAngle)); 04789 dy = (INT32)(RayLength * sin(SnapAngle)); 04790 04791 // Calculate the new position for the cursor 04792 CurCoord->x = (INT32)(Centre.x + dx); 04793 CurCoord->y = (INT32)(Centre.y + dy); 04794 } 04795 04796 04797 /******************************************************************************************** 04798 04799 > void DocView::ConstrainToAngle(DocCoord& Centre, double Constrain, DocCoord* CurCoord) 04800 04801 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 04802 Created: 14/7/94 04803 Inputs: Centre - The point that all the constrain rays come from 04804 Constrain - The constrain angle in Radians 04805 Outputs: CurCoord - contains the mouse coord on entry and contains the constrained 04806 mouse coord afterwards 04807 Purpose: Constrains the mouse movement to rays coming out from a central point. This 04808 is ideal for rotation etc. 04809 DO NOT USE THIS VERSION OF THE FUNCTION. There is a newer version that 04810 makes use of the constrain angle in the preferences and should be used 04811 instead of this version. 04812 04813 ********************************************************************************************/ 04814 04815 void DocView::ConstrainToAngle(DocCoord& Centre, double Constrain, DocCoord* CurCoord) 04816 { 04817 // Just call the new version of the function 04818 ConstrainToAngle(Centre, CurCoord, Constrain); 04819 } 04820 04821 04822 /******************************************************************************************** 04823 04824 > void DocView::ConstrainToAspect(DocCoord& FixedCoord, FIXED16& AspectLock, DocCoord* CurCoord) 04825 04826 Author: Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com> 04827 Created: 14/7/94 04828 Inputs: FixedCoord - a fixed reference point, usually the opposite corner of the 04829 bounding rectangle to be constrained 04830 AspectLock - The aspect ratio to maintain (1 is square) 04831 Outputs: CurCoord - This coordinate will be modified so that it forms a rectangle of 04832 the correct aspect ratio from the fixed corner. 04833 Purpose: Forces the supplied coordinate to be constrained to positions that force 04834 the aspect ratio from the fixed corner to be the one supplied. It should be 04835 called by the tools to 'snap' the coordinates from a drag to positions 04836 where the shape is not deformed. 04837 NOT FINISHED 04838 SeeAlso: DocView::ConstrainToAngle() 04839 04840 ********************************************************************************************/ 04841 04842 void DocView::ConstrainToAspect(DocCoord& FixedCoord, FIXED16& AspectLock, DocCoord* CurCoord) 04843 { 04844 // Get something to avoid all the rampant *s in my code 04845 DocCoord& DiffCoord = *CurCoord; 04846 04847 // Find out which of the 2 axis are the most significant 04848 INT32 dx = DiffCoord.x - FixedCoord.x; 04849 INT32 dy = DiffCoord.y - FixedCoord.y; 04850 double dAspect = AspectLock.MakeDouble(); 04851 04852 if (abs(dx)>abs(dy)) 04853 { 04854 // The x coord is the most significant, so change the y coord to match 04855 // First work out the magnitude of the change and correct it for sign 04856 INT32 NewOffset = (INT32)(abs(dx) / dAspect); 04857 if (dy<0) 04858 NewOffset = -NewOffset; 04859 04860 // add in the difference 04861 DiffCoord.y = FixedCoord.y + NewOffset; 04862 } 04863 else 04864 { 04865 // The y coord is the most significant, so chnage the x coord to match 04866 // First work out the magnitude of the change and correct it for sign 04867 INT32 NewOffset = (INT32)(abs(dy) * dAspect); 04868 if (dx<0) 04869 NewOffset = -NewOffset; 04870 04871 // add in the difference 04872 DiffCoord.x = FixedCoord.x + NewOffset; 04873 } 04874 } 04875 04876 04877 04878 04879 /******************************************************************************************** 04880 04881 > Spread* DocView::GetVisibleSpread() 04882 04883 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 04884 Created: 18/5/94 04885 Returns: A pointer to a Spread, or NULL. 04886 Purpose: Compares the bounding rectangles of Spreads in this view's document with 04887 the section of the document currently visible in the view, looking for 04888 the largest spread object that is within the view. If none are visible 04889 then the function returns NULL. 04890 04891 NB. hacked to simply return the first spread for the v1 release. 04892 Errors: - 04893 SeeAlso: DocView::GetFirstSelectedSpread 04894 04895 d********************************************************************************************/ 04896 04897 Spread* DocView::GetVisibleSpread() 04898 { 04899 // Initially we have no visible spread, which has zero area (of course). 04900 Spread* pCandidateSpread = NULL; 04901 // XLONG xlCandidateArea = 0; 04902 04903 // Begin by finding the extent of the viewport. 04904 WorkRect wrViewPort = GetViewRect(); 04905 04906 // Check that we have a document. 04907 if (pDoc == NULL) 04908 return NULL; 04909 04910 // Find the first node in the document's tree. 04911 Node* pNode = pDoc->GetFirstNode(); 04912 if (pNode == NULL) 04913 return NULL; 04914 04915 // Find its first sibling, which should be a NodeDocument. 04916 pNode = pNode->FindNext(); 04917 if (pNode == NULL) 04918 return NULL; 04919 04920 ERROR3IF(!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeDocument)), 04921 "Can't find a NodeDocument in DocView::GetVisibleSpread"); 04922 04923 // Find the first child node of the NodeDocument. 04924 pNode = pNode->FindFirstChild(); 04925 if (pNode == NULL) return NULL; 04926 04927 // Check if it's a chapter, skip it if it isn't. 04928 if (pNode->GetRuntimeClass() != CC_RUNTIME_CLASS(Chapter)) 04929 { 04930 pNode = pNode->FindNext(CC_RUNTIME_CLASS(Chapter)); 04931 if (pNode == NULL) return NULL; 04932 } 04933 04934 // We've found a chapter. 04935 Chapter* pChapter = (Chapter*) pNode; 04936 // do { 04937 // Find the first child of the chapter. 04938 pNode = pChapter->FindFirstChild(); 04939 if (pNode == NULL) return NULL; 04940 04941 // If it isn't a spread then skip it. 04942 if (pNode->GetRuntimeClass() != CC_RUNTIME_CLASS(Spread)) 04943 { 04944 pNode = pNode->FindNext(CC_RUNTIME_CLASS(Spread)); 04945 if (pNode == NULL) return NULL; 04946 } 04947 04948 // Now check all sibling spreads. 04949 Spread* pSpread = (Spread*) pNode; 04950 /* do { 04951 // At last, we found a spread! Get its bounding rectangle in 04952 // document coordinates. 04953 DocRect drBound = pSpread->GetPageBounds(); 04954 04955 // Convert to work coordinates. 04956 WorkRect wrBound(drBound.lo.ToWork(pSpread, this), 04957 drBound.hi.ToWork(pSpread, this)); 04958 04959 // If it intersects with the current viewport then we check if it is 04960 // the largest considered so far. 04961 WorkRect wrIntersect = wrBound.Intersection(wrViewPort); 04962 if (wrIntersect.IsValid() && !wrIntersect.IsEmpty()) 04963 { 04964 XLONG xlArea = wrIntersect.Width() * wrIntersect.Height(); 04965 if (xlArea > xlCandidateArea) 04966 { 04967 */ // It is the largest so far, so remember it. 04968 pCandidateSpread = pSpread; 04969 /* xlCandidateArea = xlArea; 04970 } 04971 } 04972 04973 // Find the next sibling spread, if any. 04974 pSpread = (Spread*) pSpread->FindNext(CC_RUNTIME_CLASS(Spread)); 04975 } 04976 while (pSpread != NULL); 04977 04978 // Find the next sibling chapter, if any. 04979 pChapter = (Chapter*) pChapter->FindNext(CC_RUNTIME_CLASS(Chapter)); 04980 } while (pChapter != NULL); 04981 */ 04982 // If we get here we couldn't find anything! 04983 return pCandidateSpread; 04984 } 04985 04986 04987 04988 /******************************************************************************************** 04989 04990 > Spread* DocView::GetFirstSelectedSpread() 04991 04992 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 04993 Created: 18/5/94 04994 Inputs: - 04995 Outputs: - 04996 Returns: A pointer to a Spread node in this view's document, or NULL. 04997 Purpose: Searches for a selected object in the document, and returns a pointer to 04998 the spread containing said object. If there are no selected objects then 04999 it returns NULL. 05000 Errors: - 05001 SeeAlso: DocView::GetVisibleSpread 05002 05003 ********************************************************************************************/ 05004 05005 Spread* DocView::GetFirstSelectedSpread() 05006 { 05007 // Obtain the current selection, if any. 05008 //GetApplication()->UpdateSelection(); 05009 SelRange* pSel = GetApplication()->FindSelection(); 05010 if (pSel == NULL) return NULL; 05011 05012 // Find the first selected object. 05013 Node* pFirstSelectedNode = pSel->FindFirst(); 05014 05015 // If there isn't one, then there is no spread with sel objects. 05016 // Otherwise get the selected object's parent spread. 05017 return (pFirstSelectedNode != NULL) 05018 ? (Spread*) pFirstSelectedNode->FindParent(CC_RUNTIME_CLASS(Spread)) 05019 : NULL; 05020 } 05021 05022 05023 05024 /*********************************************************************************************** 05025 05026 > BOOL DocView::IsSingleClickReallyTriple() const 05027 05028 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 05029 Created: 22/12/95 05030 Inputs: - 05031 Outputs: - 05032 Returns: TRUE if the last click event was a triple click. FALSE if not, or the attached 05033 oil view is not a screen view. 05034 Purpose: For determining wether the current single click event is really a triple click 05035 It only makes sense to call this when you are processing a click event! 05036 SeeAlso: DocView::IsSingleClickReallyQuad() 05037 05038 *********************************************************************************************/ 05039 05040 BOOL DocView::IsSingleClickReallyTriple() const 05041 { 05042 // Salary check 05043 if (pViewWindow == NULL) 05044 { 05045 ERROR3("No attached oil view"); 05046 return FALSE; 05047 } 05048 05049 return pViewWindow->IsSingleClickReallyTriple(); 05050 } 05051 05052 05053 05054 /*********************************************************************************************** 05055 05056 > BOOL DocView::IsSingleClickReallyQuad() const 05057 05058 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 05059 Created: 22/12/95 05060 Inputs: - 05061 Outputs: - 05062 Returns: TRUE if the last click event was a quad click. FALSE if not, or the attached 05063 oil view is not a screen view. 05064 Purpose: For determining wether the current single click event is really a quad click 05065 It only makes sense to call this when you are processing a click event! 05066 SeeAlso: DocView::IsSingleClickReallyTriple() 05067 05068 *********************************************************************************************/ 05069 05070 BOOL DocView::IsSingleClickReallyQuad() const 05071 { 05072 // Salary check 05073 if (pViewWindow == NULL) 05074 { 05075 ERROR3("No attached oil view"); 05076 return FALSE; 05077 } 05078 05079 return pViewWindow->IsSingleClickReallyQuad(); 05080 } 05081 05082 05083 05084 05085 /*********************************************************************************************** 05086 05087 > void DocView::ShowViewScrollers(BOOL fIsVisible) 05088 05089 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 05090 Created: 2/11/94 05091 Inputs: - 05092 Outputs: - 05093 Returns: - 05094 Purpose: Pass on Show Hide Scrollers Message to CamView 05095 SeeAlso: - 05096 05097 *********************************************************************************************/ 05098 05099 void DocView::ShowViewScrollers(BOOL fIsVisible) 05100 { 05101 PORTNOTETRACE("other","DocView::ShowViewScrollers - do nothing"); 05102 #ifndef EXCLUDE_FROM_XARALX 05103 pViewWindow->ShowScrollers(fIsVisible); 05104 #endif 05105 } 05106 05107 /*********************************************************************************************** 05108 05109 > void DocView::ShowViewRulers(BOOL fIsVisible) 05110 05111 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 05112 Created: 2/11/94 05113 Inputs: - 05114 Outputs: - 05115 Returns: - 05116 Purpose: Pass on Show Hide Rulers Message to CamView 05117 SeeAlso: - 05118 05119 *********************************************************************************************/ 05120 05121 void DocView::ShowViewRulers(BOOL fIsVisible) 05122 { 05123 pViewWindow->ShowRulers(fIsVisible); 05124 } 05125 05126 05127 /*********************************************************************************************** 05128 05129 > BOOL DocView::AreRulersVisible() 05130 05131 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 05132 Created: 2/11/94 05133 Inputs: - 05134 Outputs: - 05135 Returns: Are Rulers Visible on this view 05136 Purpose: - 05137 SeeAlso: - 05138 05139 *********************************************************************************************/ 05140 05141 BOOL DocView::AreRulersVisible() 05142 { 05143 return pViewWindow->AreRulersVisible( ); 05144 } 05145 05146 05147 /*********************************************************************************************** 05148 05149 > BOOL DocView::AreScrollersVisible() 05150 05151 Author: Chris_Snook (Xara Group Ltd) <camelotdev@xara.com> 05152 Created: 2/11/94 05153 Inputs: - 05154 Outputs: - 05155 Returns: Are Rulers Visible on this view 05156 Purpose: - 05157 SeeAlso: - 05158 05159 *********************************************************************************************/ 05160 05161 BOOL DocView::AreScrollersVisible() 05162 { 05163 return pViewWindow->AreScrollersVisible( ); 05164 } 05165 05166 /******************************************************************************************** 05167 05168 > CDC *DocView::GetRenderDC() 05169 05170 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 05171 Created: 02/09/95 05172 Purpose: Access function for the device context of this kernel view object. 05173 SeeAlso: PrintView; View 05174 05175 ********************************************************************************************/ 05176 05177 CNativeDC *DocView::GetRenderDC() 05178 { 05179 // Ask our CCamView to give us its DC and return that. 05180 return pViewWindow->GetRenderDC(); 05181 } 05182 05183 05184 /******************************************************************************************** 05185 05186 > virtual void DocView::RenderPageMarks(Spread *pSpread, 05187 DocRect ClipRect, 05188 CDC *pDevContext, 05189 Matrix& RenderMatrix 05190 RenderType rType) 05191 05192 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05193 Created: 08/08/96 05194 Inputs: pSpread - pointer to the spread concerned 05195 ClipRect - Rectangle to create region from 05196 pDevContect - pointer to the device context for this region (may be NULL 05197 if PaintPaper == FALSE) 05198 RenderMatrix- the render matrix to use. 05199 rType - the type of render to give the region 05200 05201 Outputs: - 05202 Returns: - 05203 Purpose: Performs the rendering of page marks, ie crop marks, registration marks etc 05204 to the screen and printer. This base class version does nothing. All 05205 mark rendering technology is held in DocView and PrintView. 05206 SeeAlso: View, PrintView 05207 05208 ********************************************************************************************/ 05209 05210 /* 05211 void DocView::RenderPageMarks(Spread *pSpread, DocRect ClipRect, CDC *pDevContext, Matrix& RenderMatrix, RenderType rType) 05212 { 05213 #ifndef STANDALONE 05214 // No paper rendering region - get a new render region 05215 OSRenderRegion* pPageMarksRegion = (OSRenderRegion *) NewRenderRegion(ClipRect, RenderMatrix, pDevContext, pSpread, rType); 05216 if (!pPageMarksRegion) 05217 return; 05218 05219 // We save the context here, so that PaperRenderRegion::DetachDevice() can 05220 // throw away all the attributes. We only need to do it here because 05221 // PaperRenderRegion::AttachDevice() (see 2 inches below) calls SaveContext() 05222 // automagically. 05223 pPageMarksRegion->SaveContext(); 05224 05225 // Set up the rendering system. 05226 if (!pPageMarksRegion->StartRender()) 05227 { 05228 TRACEALL( _T("StartRender failed during View::RenderPageMarks\n")); 05229 pPageMarksRegion->RestoreContext(); 05230 delete pPageMarksRegion; 05231 return; 05232 } 05233 05234 // Render the page mark objects using the permanent PageMarks render region. 05235 pPageMarksRegion->SaveContext(); 05236 RenderPageMarks(pPageMarksRegion, pSpread); 05237 pPageMarksRegion->RestoreContext(); 05238 pPageMarksRegion->StopRender(); 05239 05240 delete pPageMarksRegion; 05241 #endif 05242 } 05243 */ 05244 05245 /******************************************************************************************** 05246 05247 > virtual void DocView::RenderPageMarks(RenderRegion *pRRegion, 05248 Matrix &ViewTrans, 05249 ClipRect &ClipRect 05250 Spread *pSpread) 05251 05252 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 05253 Created: 08/08/96 05254 Inputs: pSpread - pointer to the spread concerned 05255 pRRegion - pointer to the render region to use. 05256 Outputs: - 05257 Returns: - 05258 Purpose: Performs the rendering of page marks, ie crop marks, registration marks etc 05259 to the screen and printer. This base class version does nothing. All 05260 mark rendering technology is held in DocView and PrintView. 05261 SeeAlso: View, PrintView 05262 05263 ********************************************************************************************/ 05264 05265 BOOL DocView::RenderPageMarks(RenderRegion *pCurrRegion, Matrix &ViewTrans, DocRect &ClipRect, Spread *pSpread) 05266 { 05267 return TRUE; 05268 } 05269 05270 /******************************************************************************************** 05271 05272 > DocCoord DocView::GetCentreCoord() const 05273 05274 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05275 Created: 14/7/97 05276 Inputs: - 05277 Outputs: - 05278 Returns: The DocCoord for the centre of the view 05279 Purpose: Gets a DocCoord for the centre of the view 05280 Errors: - 05281 SeeAlso: - 05282 05283 ********************************************************************************************/ 05284 05285 DocCoord DocView::GetCentreCoord() 05286 { 05287 //First get the document associated with this view 05288 Document* pDocument=GetDoc(); 05289 05290 //And find the first spread in that document 05291 PORTNOTE("spread", "Multi-spread warning!") 05292 Spread* pSpread=pDocument->FindFirstSpread(); 05293 05294 //Check we got both of those 05295 ERROR2IF(pDocument==NULL || pSpread==NULL, DocCoord(0,0), "DocView::GetCentreImportPosition - no document or spread"); 05296 05297 //So get the view rectangle 05298 DocRect rectView = GetDocViewRect(pSpread); 05299 05300 //And find the middle of that rectangle 05301 DocCoord dcCentre; 05302 dcCentre.x = rectView.lo.x / 2 + rectView.hi.x / 2; 05303 dcCentre.y = rectView.lo.y / 2 + rectView.hi.y / 2; 05304 05305 //Now make that into a spread coordinate 05306 DocRect rectSpread = pSpread->GetPasteboardRect(); 05307 05308 DocCoord dcToReturn; 05309 05310 dcToReturn.x = dcCentre.x - rectSpread.lo.x; 05311 dcToReturn.y = dcCentre.y - rectSpread.lo.y; 05312 05313 //And return that DocCoord 05314 return dcToReturn; 05315 } 05316 05317 /******************************************************************************************** 05318 05319 > ImportPosition DocView::GetCentreImportPosition() const 05320 05321 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05322 Created: 14/7/97 05323 Inputs: - 05324 Outputs: - 05325 Returns: The import position for the centre of the view 05326 Purpose: Gets an import position for the centre of the view 05327 Errors: - 05328 SeeAlso: - 05329 05330 ********************************************************************************************/ 05331 05332 ImportPosition DocView::GetCentreImportPosition() 05333 { 05334 //First get the document associated with this view 05335 Document* pDocument=GetDoc(); 05336 05337 //And find the first spread in that document 05338 PORTNOTE("spread", "Multi-spread warning!") 05339 Spread* pSpread=pDocument->FindFirstSpread(); 05340 05341 //Now get the DocCoord in the centre of the view 05342 DocCoord dcToReturn=GetCentreCoord(); 05343 05344 //Put all those values into an ImportPosition structure 05345 ImportPosition posToReturn; 05346 05347 posToReturn.pSpread=pSpread; 05348 posToReturn.Position=dcToReturn; 05349 05350 //And return that ImportPosition 05351 return posToReturn; 05352 05353 } 05354 05355 /******************************************************************************************** 05356 05357 > DocCoord DocView::GetTopLeftCoord() 05358 05359 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05360 Created: 14/7/97 05361 Inputs: - 05362 Outputs: - 05363 Returns: The DocCoord for the top left of the view 05364 Purpose: Gets a DocCoord for the top left of the view 05365 Errors: - 05366 SeeAlso: - 05367 05368 ********************************************************************************************/ 05369 05370 DocCoord DocView::GetTopLeftCoord() 05371 { 05372 //First get the document associated with this view 05373 Document* pDocument=GetDoc(); 05374 05375 //And find the first spread in that document 05376 PORTNOTE("spread", "Multi-spread warning!") 05377 Spread* pSpread=pDocument->FindFirstSpread(); 05378 05379 //Check we got both of those 05380 ERROR2IF(pDocument==NULL || pSpread==NULL, DocCoord(0,0), "DocView::GetCentreImportPosition - no document or spread"); 05381 05382 //So get the view rectangle 05383 DocRect rectView = GetDocViewRect(pSpread); 05384 05385 //And find the top left of that rectangle 05386 DocCoord dcTopLeft(rectView.lo.x, rectView.hi.y); 05387 05388 //Now make that into a spread coordinate 05389 DocRect rectSpread = pSpread->GetPasteboardRect(); 05390 05391 DocCoord dcToReturn; 05392 05393 dcToReturn.x = dcTopLeft.x - rectSpread.lo.x; 05394 dcToReturn.y = dcTopLeft.y - rectSpread.lo.y; 05395 05396 TRACEUSER( "luke", _T("rcToReturn (%x, %x), dcTopLeft (%x, %x), rectSpead (%x, %x)"), 05397 dcToReturn.x, dcToReturn.y, dcTopLeft.x, dcTopLeft.y, rectSpread.lo.x, rectSpread.lo.y ); 05398 05399 //And return that DocCoord 05400 return dcToReturn; 05401 } 05402 05403 /******************************************************************************************** 05404 05405 > ImportPosition DocView::GetTopLeftImportPosition() const 05406 05407 Author: Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com> 05408 Created: 14/7/97 05409 Inputs: - 05410 Outputs: - 05411 Returns: The import position for the top left of the view 05412 Purpose: Gets an import position for the top left of the view 05413 Errors: - 05414 SeeAlso: - 05415 05416 ********************************************************************************************/ 05417 05418 ImportPosition DocView::GetTopLeftImportPosition() 05419 { 05420 //First get the document associated with this view 05421 Document* pDocument=GetDoc(); 05422 05423 //And find the first spread in that document 05424 PORTNOTE("spread", "Multi-spread warning!") 05425 Spread* pSpread=pDocument->FindFirstSpread(); 05426 05427 //Now get the DocCoord in the top left of the view 05428 DocCoord dcToReturn=GetTopLeftCoord(); 05429 05430 //Put all those values into an ImportPosition structure 05431 ImportPosition posToReturn; 05432 05433 posToReturn.pSpread=pSpread; 05434 posToReturn.Position=dcToReturn; 05435 05436 //And return that ImportPosition 05437 return posToReturn; 05438 05439 } 05440 05441 05442 05443 /******************************************************************************************** 05444 05445 > double DocView::GetZoomFactor() const 05446 05447 Author: Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com> 05448 Created: 17 February 2000 05449 Returns: The current zoom factor for this document view. 05450 Purpose: Obtain the current zoom factor for this document view. 05451 Errors: 05452 See also: GetScaledPixelWidth(), GetPixelWidth(). 05453 05454 ********************************************************************************************/ 05455 double DocView::GetZoomFactor() 05456 { 05457 return GetScaledPixelWidth().MakeDouble() / GetPixelWidth().MakeDouble(); 05458 } 05459 05460 05461 /******************************************************************************************** 05462 05463 > void DocView::SetPreventRenderView(BOOL Value) 05464 05465 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 05466 Created: 10/5/2000 05467 Inputs: Value to set 05468 Returns: - 05469 Purpose: To set our member variable that will prevent rendering of the view. As you might 05470 imagine this is something to be careful about 05471 Errors: 05472 See also: 05473 05474 ********************************************************************************************/ 05475 05476 void DocView::SetPreventRenderView(BOOL Value) 05477 { 05478 m_bPreventRenderView = Value; 05479 } 05480 05481 05482 /******************************************************************************************** 05483 05484 > BOOL DocView::GetPreventRenderView() 05485 05486 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 05487 Created: 10/5/2000 05488 Returns: The state of our flag which prevents the view from rendering 05489 Purpose: As above 05490 Errors: 05491 See also: 05492 05493 ********************************************************************************************/ 05494 05495 BOOL DocView::GetPreventRenderView() 05496 { 05497 return m_bPreventRenderView; 05498 } 05499 05500 05501 /******************************************************************************************** 05502 05503 > void DocView::ClearClickState() 05504 05505 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05506 Created: 26/02/2004 05507 Returns: - 05508 Purpose: Allows click handlers to reset the click logic if they are doing things 05509 that would break it. 05510 Errors: 05511 See also: 05512 05513 ********************************************************************************************/ 05514 05515 void DocView::ClearClickState() 05516 { 05517 PORTNOTETRACE("other","DocView::ClearClickState - do nothing"); 05518 #ifndef EXCLUDE_FROM_XARALX 05519 if (pViewWindow) 05520 { 05521 pViewWindow->ClearClickState(); 05522 } 05523 #endif 05524 } 05525 05526 05527 /******************************************************************************************** 05528 TOGGLE FORE/BACKGROUND RENDERING OPERATION 05529 */ 05530 /******************************************************************************************** 05531 05532 > OpToggleFore::OpToggleFore() : Operation() 05533 05534 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05535 Created: 9/7/93 05536 Inputs: - 05537 Outputs: - 05538 Returns: - 05539 Purpose: Constructs an OpToggleFore object. 05540 Errors: - 05541 SeeAlso: - 05542 05543 ********************************************************************************************/ 05544 05545 OpToggleFore::OpToggleFore() : Operation() 05546 { 05547 05548 } 05549 05550 05551 05552 /******************************************************************************************** 05553 05554 > OpToggleFore::~OpToggleFore() 05555 05556 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05557 Created: 9/7/93 05558 Inputs: - 05559 Outputs: - 05560 Returns: - 05561 Purpose: Destructs an OpToggleFore object. 05562 Errors: - 05563 SeeAlso: - 05564 05565 ********************************************************************************************/ 05566 05567 OpToggleFore::~OpToggleFore() 05568 { 05569 // Empty 05570 } 05571 05572 05573 05574 /******************************************************************************************** 05575 05576 > void OpToggleFore::Do(OpDescriptor*) 05577 05578 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05579 Created: 9/7/93 05580 Inputs: Pointer to Operation Descriptor 05581 Outputs: - 05582 Returns: - 05583 Purpose: Actually "DO" a ToggleFore operation. 05584 Errors: - 05585 SeeAlso: - 05586 05587 ********************************************************************************************/ 05588 05589 void OpToggleFore::Do(OpDescriptor*) 05590 { 05591 if (DocView::GetSelected() != NULL) 05592 DocView::GetSelected()->SetForeBackMode(!DocView::GetSelected()->GetForeBackMode()); 05593 End(); 05594 } 05595 05596 05597 05598 /******************************************************************************************** 05599 05600 > OpState OpToggleFore::GetState(String_256* UIDescription, OpDescriptor*) 05601 05602 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05603 Created: 9/7/93 05604 Inputs: Pointer to Operation Descriptor 05605 Text Description 05606 Outputs: - 05607 Returns: - 05608 Purpose: Find the state of the OpToggleFore operation. 05609 Errors: - 05610 SeeAlso: - 05611 05612 ********************************************************************************************/ 05613 05614 OpState OpToggleFore::GetState(String_256* UIDescription, OpDescriptor*) 05615 { 05616 // Default to !ticked and greyed 05617 OpState blobby(FALSE, TRUE); 05618 if (DocView::GetSelected() != NULL) 05619 { 05620 // If we have a selected view then get the state and ungrey 05621 blobby.Ticked = DocView::GetSelected()->GetForeBackMode(); 05622 blobby.Greyed = FALSE; 05623 } 05624 return(blobby); 05625 } 05626 05627 05628 05629 /******************************************************************************************** 05630 05631 > BOOL OpToggleFore::Init() 05632 05633 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05634 Created: 9/7/93 05635 Inputs: - 05636 Outputs: - 05637 Returns: - 05638 Purpose: Create an OpDescriptor for the ToggleFore operation 05639 Errors: - 05640 SeeAlso: - 05641 05642 ********************************************************************************************/ 05643 05644 BOOL OpToggleFore::Init() 05645 { 05646 return Operation::RegisterOpDescriptor( 05647 0, 05648 _R(IDS_TOGGLE_FORE_BACK), 05649 CC_RUNTIME_CLASS(OpToggleFore), 05650 OPTOKEN_TOGGLEFORE, 05651 OpToggleFore::GetState, 05652 0, // help ID 05653 0,// _R(IDBBL_FOREBACKGRNDOP), 05654 0, // bitmap ID 05655 0, // control ID 05656 SYSTEMBAR_ILLEGAL, // group bar ID 05657 TRUE, 05658 FALSE, 05659 TRUE, 05660 NULL, 05661 0, 05662 0, 05663 TRUE 05664 ); 05665 } 05666 05667 05668 /******************************************************************************************** 05669 TOGGLE PROPORTIONAL SCROLL BARS OPERATION 05670 */ 05671 /******************************************************************************************** 05672 05673 > OpToggleScroll::OpToggleScroll() : Operation() 05674 05675 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05676 Created: 9/7/93 05677 Inputs: - 05678 Outputs: - 05679 Returns: - 05680 Purpose: Constructs an OpToggleScroll object. 05681 Errors: - 05682 SeeAlso: - 05683 05684 ********************************************************************************************/ 05685 05686 OpToggleScroll::OpToggleScroll() 05687 : Operation() 05688 { 05689 // Empty 05690 } 05691 05692 05693 05694 05695 /******************************************************************************************** 05696 05697 > OpToggleScroll::~OpToggleScroll() 05698 05699 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05700 Created: 9/7/93 05701 Inputs: - 05702 Outputs: - 05703 Returns: - 05704 Purpose: Destructs an OpToggleScroll object. 05705 Errors: - 05706 SeeAlso: - 05707 05708 ********************************************************************************************/ 05709 05710 OpToggleScroll::~OpToggleScroll() 05711 { 05712 } 05713 05714 05715 05716 05717 /******************************************************************************************** 05718 05719 > void OpToggleScroll::Do(OpDescriptor*) 05720 05721 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05722 Created: 9/7/93 05723 Inputs: Pointer to an operation descriptor 05724 Outputs: - 05725 Returns: - 05726 Purpose: Actually "DO" a ToggleScroll operation. 05727 Errors: - 05728 SeeAlso: - 05729 05730 ********************************************************************************************/ 05731 05732 void OpToggleScroll::Do(OpDescriptor*) 05733 { 05734 PORTNOTE("other","OpToggleScroll::Do - do nothing") 05735 #ifndef EXCLUDE_FROM_XARALX 05736 CCamView *pView = DocView::GetSelected()->GetConnectionToOilView(); 05737 BOOL Prop = pView->GetScrollerStyle(); 05738 pView->SetScrollerStyle(!Prop); 05739 End(); 05740 #endif 05741 } 05742 05743 05744 05745 /******************************************************************************************** 05746 05747 > OpState OpToggleScroll::GetState(String_256* UIDescription, OpDescriptor*) 05748 05749 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05750 Created: 9/7/93 05751 Inputs: A Pointer to an operation description 05752 Text Description 05753 Outputs: - 05754 Returns: - 05755 Purpose: Find the state of the OpToggleScroll operation. 05756 Errors: - 05757 SeeAlso: - 05758 05759 ********************************************************************************************/ 05760 05761 OpState OpToggleScroll::GetState(String_256* UIDescription, OpDescriptor*) 05762 { 05763 PORTNOTETRACE("other","OpToggleScroll::Do - do nothing"); 05764 #ifndef EXCLUDE_FROM_XARALX 05765 CCamView *pView = DocView::GetSelected()->GetConnectionToOilView(); 05766 OpState blobby; 05767 blobby.Ticked = pView->GetScrollerStyle(); 05768 blobby.Greyed = FALSE; 05769 return blobby; 05770 #else 05771 return OpState(); 05772 #endif 05773 } 05774 05775 05776 05777 05778 /******************************************************************************************** 05779 05780 > BOOL OpToggleScroll::Init() 05781 05782 Author: Phil_Martin (Xara Group Ltd) <camelotdev@xara.com> 05783 Created: 9/7/93 05784 Inputs: - 05785 Outputs: - 05786 Returns: - 05787 Purpose: Create an OpDescriptor for the ToggleScroll operation 05788 Errors: - 05789 SeeAlso: - 05790 05791 ********************************************************************************************/ 05792 05793 BOOL OpToggleScroll::Init() 05794 { 05795 PORTNOTETRACE("other","OpToggleScroll::Init - do nothing"); 05796 #ifndef EXCLUDE_FROM_XARALX 05797 return Operation::RegisterOpDescriptor(0, 05798 _R(IDS_TOGGLE_SCROLLBARS), 05799 CC_RUNTIME_CLASS(OpToggleScroll), 05800 OPTOKEN_TOGGLESCROLL, 05801 OpToggleScroll::GetState, 05802 0, // help ID 05803 _R(IDBBL_PROPSCROLLERSOP), // bubble ID 05804 0, // bitmap ID 05805 0, // control ID 05806 SYSTEMBAR_ILLEGAL, // group bar ID 05807 TRUE, 05808 FALSE, 05809 TRUE, 05810 NULL, 05811 0, 05812 0, 05813 TRUE 05814 ); 05815 #else 05816 return FALSE; 05817 #endif 05818 } 05819 05820 /******************************************************************************************** 05821 05822 > OpToggleSolidDrag::OpToggleSolidDrag() : Operation() 05823 05824 Author: Alex Bligh <alex@alex.org.uk> 05825 Created: 14 Mar 2006 05826 Inputs: - 05827 Outputs: - 05828 Returns: - 05829 Purpose: Constructs an OpToggleSolidDrag object. 05830 Errors: - 05831 SeeAlso: - 05832 05833 ********************************************************************************************/ 05834 05835 OpToggleSolidDrag::OpToggleSolidDrag() : Operation() 05836 { 05837 05838 } 05839 05840 05841 05842 /******************************************************************************************** 05843 05844 > OpToggleSolidDrag::~OpToggleSolidDrag() 05845 05846 Author: Alex Bligh <alex@alex.org.uk> 05847 Created: 14 Mar 2006 05848 Inputs: - 05849 Outputs: - 05850 Returns: - 05851 Purpose: Destructs an OpToggleSolidDrag object. 05852 Errors: - 05853 SeeAlso: - 05854 05855 ********************************************************************************************/ 05856 05857 OpToggleSolidDrag::~OpToggleSolidDrag() 05858 { 05859 // Empty 05860 } 05861 05862 05863 05864 /******************************************************************************************** 05865 05866 > void OpToggleSolidDrag::Do(OpDescriptor*) 05867 05868 Author: Alex Bligh <alex@alex.org.uk> 05869 Created: 14 Mar 2006 05870 Inputs: Pointer to Operation Descriptor 05871 Outputs: - 05872 Returns: - 05873 Purpose: Actually "DO" a ToggleFore operation. 05874 Errors: - 05875 SeeAlso: - 05876 05877 ********************************************************************************************/ 05878 05879 void OpToggleSolidDrag::Do(OpDescriptor*) 05880 { 05881 DocView::SolidDragging=!DocView::SolidDragging; 05882 End(); 05883 } 05884 05885 05886 05887 /******************************************************************************************** 05888 05889 > OpState OpToggleSolidDrag::GetState(String_256* UIDescription, OpDescriptor*) 05890 05891 Author: Alex Bligh <alex@alex.org.uk> 05892 Created: 14 Mar 2006 05893 Inputs: Pointer to Operation Descriptor 05894 Text Description 05895 Outputs: - 05896 Returns: - 05897 Purpose: Find the state of the OpToggleSolidDrag operation. 05898 Errors: - 05899 SeeAlso: - 05900 05901 ********************************************************************************************/ 05902 05903 OpState OpToggleSolidDrag::GetState(String_256* UIDescription, OpDescriptor*) 05904 { 05905 // Default to !ticked and greyed 05906 OpState blobby(FALSE, TRUE); 05907 blobby.Ticked = DocView::SolidDragging; 05908 blobby.Greyed = FALSE; 05909 return(blobby); 05910 } 05911 05912 05913 /******************************************************************************************** 05914 05915 > BOOL OpToggleSolidDrag::Init() 05916 05917 Author: Alex Bligh <alex@alex.org.uk> 05918 Created: 14 Mar 2006 05919 Inputs: - 05920 Outputs: - 05921 Returns: - 05922 Purpose: Create an OpDescriptor for the OpToggleSolidDrag operation 05923 Errors: - 05924 SeeAlso: - 05925 05926 ********************************************************************************************/ 05927 05928 BOOL OpToggleSolidDrag::Init() 05929 { 05930 return Operation::RegisterOpDescriptor( 05931 0, 05932 _R(IDS_TOGGLE_SOLIDDRAG), 05933 CC_RUNTIME_CLASS(OpToggleSolidDrag), 05934 OPTOKEN_TOGGLESOLIDDRAG, 05935 OpToggleSolidDrag::GetState, 05936 0, // help ID 05937 0,// _R(IDBBL_FOREBACKGRNDOP), 05938 0, // bitmap ID 05939 0, // control ID 05940 SYSTEMBAR_ILLEGAL, // group bar ID 05941 TRUE, 05942 FALSE, 05943 TRUE, 05944 NULL, 05945 0, 05946 0, 05947 TRUE 05948 ); 05949 }