00001 // $Id: moldtool.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 // Implementation of the mould tool 00099 00100 /* 00101 */ 00102 00103 #include "camtypes.h" 00104 //#include "resource.h" 00105 #include "oilfiles.h" 00106 #include "csrstack.h" 00107 //#include "viewrc.h" 00108 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00110 //#include "markn.h" 00111 //#include "mike.h" 00112 #include "moldtool.h" 00113 #include "osrndrgn.h" 00114 #include "nodeshap.h" 00115 //#include "opdesc.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 //#include "paths.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 #include "moldpers.h" 00118 #include "moldenv.h" 00119 #include "moldedit.h" 00120 //#include "mouldbar.h" 00121 #include "progress.h" 00122 #include "blobs.h" 00123 #include "ndmldpth.h" 00124 #include "clipint.h" 00125 #include "layer.h" 00126 #include "objchge.h" 00127 #include "keypress.h" 00128 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00129 #include "attrmap.h" 00130 #include "ophist.h" 00131 00132 //#include "will2.h" 00133 00134 //class NodeRenderableInk; 00135 00136 DECLARE_SOURCE( "$Revision: 1282 $" ); 00137 00138 CC_IMPLEMENT_MEMDUMP( MouldTool,Tool_v1 ) 00139 CC_IMPLEMENT_MEMDUMP( CreateMouldParam, OpParam ) 00140 CC_IMPLEMENT_DYNCREATE( MouldInfoBarOp,InformationBarOp ) 00141 CC_IMPLEMENT_DYNCREATE( OpCreateNewMould, OpMouldLibSel ) 00142 CC_IMPLEMENT_DYNCREATE( OpRectangularEnvelope, OpMouldLibSel ) 00143 CC_IMPLEMENT_DYNCREATE( OpRectangularPerspective, OpMouldLibSel ) 00144 CC_IMPLEMENT_DYNCREATE( OpRemoveMould, OpMouldLibSel ) 00145 CC_IMPLEMENT_DYNCREATE( OpCopyMouldShape, OpMouldLibSel ) 00146 CC_IMPLEMENT_DYNCREATE( OpPasteMouldShape, OpMouldLibSel ) 00147 CC_IMPLEMENT_DYNCREATE( OpPasteEnvelope, OpPasteMouldShape ) 00148 CC_IMPLEMENT_DYNCREATE( OpPastePerspective, OpPasteMouldShape ) 00149 CC_IMPLEMENT_DYNCREATE( OpToggleMouldGrid, Operation ) 00150 CC_IMPLEMENT_DYNCREATE( OpDetachMould, UndoableOperation ) 00151 CC_IMPLEMENT_DYNCREATE( OpRotateMould, OpMouldLib ) 00152 CC_IMPLEMENT_MEMDUMP( MouldBecomeA, BecomeA ) 00153 00154 // Must come after the last CC_IMPLEMENT.. macro 00155 #define new CAM_DEBUG_NEW 00156 00157 // These are still char* while we wait for resource technology to be developed for modules 00158 TCHAR* MouldTool::FamilyName = _T("Mould Tools"); 00159 TCHAR* MouldTool::ToolName = _T("Mould Tool"); 00160 TCHAR* MouldTool::Purpose = _T("Mould manipulation"); 00161 TCHAR* MouldTool::Author = _T("Mike"); 00162 00163 // Init those other useful static vars 00164 BOOL MouldTool::CurrentTool = FALSE; 00165 MouldInfoBarOp* MouldTool::pMouldInfoBarOp = NULL; 00166 00167 00168 00169 /******************************************************************************************** 00170 00171 > MouldTool::MouldTool() 00172 00173 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00174 Created: 30/11/94 00175 Purpose: Default Constructor. 00176 Other initialisation is done in MouldTool::Init which is called by the Tool Manager 00177 SeeAlso: MouldTool::Init 00178 00179 ********************************************************************************************/ 00180 00181 MouldTool::MouldTool() 00182 { 00183 pcCurrentCursor = NULL; 00184 } 00185 00186 /******************************************************************************************** 00187 00188 > MouldTool::~MouldTool() 00189 00190 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00191 Created: 30/11/94 00192 Purpose: Destructor (Virtual). Does nothing. 00193 00194 ********************************************************************************************/ 00195 00196 MouldTool::~MouldTool() 00197 { 00198 } 00199 00200 00201 /******************************************************************************************** 00202 00203 > BOOL MouldTool::Init( INT32 Pass ) 00204 00205 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00206 Created: 30/11/94 00207 Returns: FALSE if it does not want to be created, TRUE otherwise 00208 Purpose: Used to check if the Tool was properly constructed 00209 SeeAlso: MouldTool::MouldTool 00210 00211 ********************************************************************************************/ 00212 00213 BOOL MouldTool::Init() 00214 { 00215 // Declare all your ops here and only succeed if all declarations succeed 00216 00217 BOOL ok = TRUE; 00218 00219 // register our mould tool operations 00220 ok = OpCreateNewMould::Init(); 00221 if (ok) ok = OpRemoveMould::Init(); 00222 if (ok) ok = OpCopyMouldShape::Init(); 00223 if (ok) ok = OpPasteEnvelope::Init(); 00224 if (ok) ok = OpPastePerspective::Init(); 00225 if (ok) ok = OpToggleMouldGrid::Init(); 00226 if (ok) ok = OpDetachMould::Init(); 00227 if (ok) ok = OpRotateMould::Init(); 00228 if (ok) ok = OpRectangularEnvelope::Init(); 00229 if (ok) ok = OpRectangularPerspective::Init(); 00230 00231 #if 0 00232 if (ok) 00233 { 00234 // This section reads in the infobar definition and creates an instance of 00235 // MouldInfoBarOp. Also pMouldInfoBarOp, the ptr to the tool's infobar, is set up 00236 // after the infobar is successfully read and created. 00237 CCResTextFile file; // Resource File 00238 MouldInfoBarOpCreate BarCreate; // Object that creates MouldInfoBarOp objects 00239 00240 ok = file.open(_R(IDM_MOULDTOOL_BAR), _R(IDT_INFO_BAR_RES)); // Open resource 00241 if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate); // Read and create info bar 00242 if (ok) file.close(); // Close resource 00243 00244 ENSURE(ok,"Unable to load mouldbar.ini from resource\n"); 00245 } 00246 00247 if (ok) 00248 { 00249 // Info bar now exists. Now get a pointer to it 00250 String_32 str = String_32(_R(IDS_MOLDTOOL_INFOBARNAME)); 00251 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str); 00252 00253 00254 ok = (pDialogBarOp != NULL); 00255 if (ok) ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(MouldInfoBarOp)); 00256 if (ok) pMouldInfoBarOp = (MouldInfoBarOp*)pDialogBarOp; 00257 if (ok) pMouldInfoBarOp->SetTool(this); // Set a pointer from the op to this tool 00258 00259 ENSURE(ok,"Error finding the mould tool info bar"); 00260 } 00261 #endif 00262 00263 if (ok) 00264 { 00265 pMouldInfoBarOp = new MouldInfoBarOp(); 00266 ok = (pMouldInfoBarOp != NULL); 00267 00268 if (ok) pMouldInfoBarOp->SetTool(this); // Set a pointer from the op to this tool 00269 } 00270 00271 return (ok); 00272 } 00273 00274 00275 /******************************************************************************************** 00276 00277 > void MouldTool::Describe(void *InfoPtr) 00278 00279 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00280 Created: 30/11/94 00281 Inputs: InfoPtr - A pointer to a tool info block. It is passed cast to void* as 00282 the version of the tool is unknown at this point. Later versions 00283 of the Tool class may have more items in this block, that this 00284 tool will not use 00285 Outputs: InfoPtr - The structure pointed to by InfoPtr will have had all the info 00286 that this version of the Tool knows about 00287 Purpose: Allows the tool manager to extract information about the tool 00288 00289 ********************************************************************************************/ 00290 00291 void MouldTool::Describe(void *InfoPtr) 00292 { 00293 // Cast structure into the latest one we understand. 00294 ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr; 00295 00296 Info->InfoVersion = 1; 00297 00298 Info->InterfaceVersion = GetToolInterfaceVersion(); // You should always have this line. 00299 00300 // These are all arbitrary at present. 00301 Info->Version = 1; 00302 Info->ID = GetID(); 00303 Info->TextID = _R(IDS_MOULD_TOOL); 00304 00305 Info->Family = FamilyName; 00306 Info->Name = ToolName; 00307 Info->Purpose = Purpose; 00308 Info->Author = Author; 00309 00310 Info->BubbleID = _R(IDBBL_MOULD_TOOL); 00311 } 00312 00313 /******************************************************************************************** 00314 00315 > virtual void MouldTool::SelectChange(BOOL isSelected) 00316 00317 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00318 Created: 30/11/94 00319 Inputs: isSelected - TRUE = tool has been selected 00320 - FALSE = tool has been deselected 00321 Outputs: - 00322 Returns: - 00323 Purpose: Starts up and closes down the mould tool 00324 Errors: Debug warning if creating the cursor fails. 00325 SeeAlso: - 00326 00327 ********************************************************************************************/ 00328 00329 void MouldTool::SelectChange(BOOL isSelected) 00330 { 00331 if (isSelected) 00332 { 00333 // This tool has just been selected. Create an appropriate cursor, and push it 00334 // onto the top of the cursor stack so it'll appear when the pointer moves into 00335 // our window. 00336 00337 if (!CreateCursors()) return; 00338 00339 // Push cursor but don't display now 00340 CurrentCursorID = CursorStack::GPush(pcNormalMouldCursor, FALSE); 00341 pcCurrentCursor = pcNormalMouldCursor; 00342 00343 // This tool is now the current one 00344 MouldTool::CurrentTool = TRUE; 00345 00346 // Create and display the tool's info bar 00347 if (pMouldInfoBarOp != NULL) 00348 pMouldInfoBarOp->Create(); 00349 00350 // Which blobs do I want displayed 00351 BlobManager* BlobMgr = GetApplication()->GetBlobManager(); 00352 if (BlobMgr != NULL) 00353 { 00354 // Decide which blobs we will display 00355 BlobStyle MyBlobs; 00356 MyBlobs.Object = TRUE; 00357 00358 // Tell the blob manager 00359 BlobMgr->ToolInterest(MyBlobs); 00360 } 00361 00362 00363 } 00364 else 00365 { 00366 // Deselection - destroy the tool's cursors, if they exist. 00367 if (pcCurrentCursor != NULL) 00368 { 00369 CursorStack::GPop(CurrentCursorID); 00370 pcCurrentCursor = NULL; 00371 CurrentCursorID = 0; 00372 } 00373 DestroyCursors(); 00374 00375 // Remove the info bar from view by deleting the actual underlying window 00376 if (pMouldInfoBarOp != NULL) 00377 pMouldInfoBarOp->Delete(); 00378 00379 // ensure any tool object blobs are removed. 00380 BlobManager* BlobMgr = GetApplication()->GetBlobManager(); 00381 if (BlobMgr != NULL) 00382 { 00383 BlobStyle bsRemoves; 00384 bsRemoves.ToolObject = TRUE; 00385 BlobMgr->RemoveInterest(bsRemoves); 00386 } 00387 00388 // We're no longer the current tool 00389 MouldTool::CurrentTool = FALSE; 00390 } 00391 } 00392 00393 /******************************************************************************************** 00394 00395 > BOOL MouldTool::CreateCursors() 00396 00397 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00398 Created: 30/11/94 00399 Inputs: - 00400 Outputs: - 00401 Returns: TRUE if all the mould tool cursors have been successfully created 00402 Purpose: Creates all the mould tool cursors 00403 SeeAlso: - 00404 00405 ********************************************************************************************/ 00406 00407 BOOL MouldTool::CreateCursors() 00408 { 00409 // This tool has just been selected. Create the cursors. 00410 pcNormalMouldCursor = new Cursor(this, _R(IDC_MOULDDEFAULTCURSOR)); // _R(IDCSR_SEL_NORMAL) 00411 pcTransCoordCursor = new Cursor(this, _R(IDC_MOVEMOULDCURSOR)); 00412 pcTransOriginCursor = new Cursor(this, _R(IDCSR_SEL_GRADPOINT)); 00413 00414 if ( pcNormalMouldCursor==NULL ) goto bincursors; 00415 if ( pcTransCoordCursor==NULL) goto bincursors; 00416 if ( pcTransOriginCursor==NULL ) goto bincursors; 00417 00418 if (!pcNormalMouldCursor->IsValid()) goto bincursors; 00419 if (!pcTransCoordCursor->IsValid()) goto bincursors; 00420 if (!pcTransOriginCursor->IsValid()) goto bincursors; 00421 00422 return TRUE; 00423 00424 bincursors: 00425 DestroyCursors(); 00426 return FALSE; 00427 } 00428 00429 /******************************************************************************************** 00430 00431 > void MouldTool::DestroyCursors() 00432 00433 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00434 Created: 30/11/94 00435 Inputs: - 00436 Outputs: - 00437 Returns: - 00438 Purpose: Destroys all the mould tool cursors 00439 SeeAlso: - 00440 00441 ********************************************************************************************/ 00442 00443 void MouldTool::DestroyCursors() 00444 { 00445 if (pcNormalMouldCursor != NULL) delete pcNormalMouldCursor; 00446 if (pcTransCoordCursor != NULL) delete pcTransCoordCursor; 00447 if (pcTransOriginCursor != NULL) delete pcTransOriginCursor; 00448 00449 pcNormalMouldCursor = NULL; 00450 pcTransCoordCursor = NULL; 00451 pcTransOriginCursor = NULL; 00452 } 00453 00454 00455 00456 /******************************************************************************************** 00457 00458 > void MouldTool::ChooseCursor(INT32 ctype) 00459 00460 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00461 Created: 07/02/95 00462 Inputs: Mould cursor ID of the cursor you want to flip to 00463 Outputs: - 00464 Returns: - 00465 Purpose: Returns a pointer to the correct cursor given a mould cursor type 00466 00467 ********************************************************************************************/ 00468 00469 Cursor* MouldTool::ChooseCursor(INT32 ctype) 00470 { 00471 switch (ctype) 00472 { 00473 case 1: 00474 return pcNormalMouldCursor; 00475 break; 00476 case 2: 00477 return pcTransOriginCursor; 00478 break; 00479 case 3: 00480 return pcTransCoordCursor; 00481 break; 00482 } 00483 return pcNormalMouldCursor; 00484 } 00485 00486 00487 /******************************************************************************************** 00488 00489 > void MouldTool::ChangeCursor(Cursor* cursor) 00490 00491 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00492 Created: 30/11/94 00493 Inputs: ID of the cursor you want to flip to 00494 Outputs: - 00495 Returns: - 00496 Purpose: Changes to the specified cursor. Will only change the cursor if it isn't 00497 already this cursor, so it doesn't flicker. 00498 Errors: can fail if the cursor cannot be created - the cursor code will fail. 00499 SeeAlso: - 00500 00501 ********************************************************************************************/ 00502 00503 void MouldTool::ChangeCursor(Cursor* cursor) 00504 { 00505 // only change if this cursor is different from the current cursor 00506 if (cursor != pcCurrentCursor) 00507 { 00508 // set this cursor as the current cursor and immediately display it 00509 CursorStack::GSetTop(cursor, CurrentCursorID); 00510 // remember this is our current cursor 00511 pcCurrentCursor = cursor; 00512 } 00513 } 00514 00515 00516 00517 00518 /******************************************************************************************** 00519 00520 > void MouldTool::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods, 00521 Spread* pSpread ) 00522 00523 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00524 Created: 30/11/94 00525 Inputs: PointerPos - The DocCoord of the point where the mouse button was clicked 00526 Click - Describes the type of click that was detected. 00527 ClickMods - Indicates which buttons caused the click and which modifers were 00528 pressed at the same time 00529 pSpread - The spread in which the click happened 00530 Returns: - 00531 Purpose: To handle a Mouse Click event for the Mould Tool. 00532 SeeAlso: Tool::MouseClick; ClickType; ClickModifiers 00533 00534 ********************************************************************************************/ 00535 00536 void MouldTool::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods, 00537 Spread* pSpread ) 00538 { 00539 if (ClickMods.Menu) return; // Don't do anything if the user clicked the Menu button 00540 00541 // Now scan through the selected paths, and see if we've clicked on any moulds 00542 DocView* pDocView = DocView::GetCurrent(); 00543 ENSURE( pDocView != NULL, "MouldTool::BroadcastClick() Can't find current DocView"); 00544 if (pDocView==NULL) 00545 return; 00546 00547 // Find the selected range of objects 00548 SelRange* Selected = GetApplication()->FindSelection(); 00549 Node* pNode = Selected->FindFirst(); 00550 Node* pNext; 00551 BOOL claimed = FALSE; 00552 00553 while ((pNode != NULL) && (!claimed)) 00554 { 00555 // Find the next selected node 00556 pNext = Selected->FindNext(pNode); 00557 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 00558 claimed = ((NodeMould*)pNode)->OnClick(PointerPos, Click, ClickMods, pSpread); 00559 pNode = pNext; 00560 } 00561 00562 if (!claimed) 00563 { 00564 // call the base class .... 00565 00566 DragTool::OnClick (PointerPos, Click, ClickMods, pSpread); 00567 } 00568 } 00569 00570 00571 00572 /******************************************************************************************** 00573 00574 > void MouldTool::OnMouseMove( DocCoord PointerPos,Spread* pSpread, ClickModifiers ClickMod ) 00575 00576 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00577 Created: 30/11/94 00578 Inputs: PointerPos - The DocCoord of the point where the mouse has moved to 00579 pSpread - The spread in which the move occurred 00580 ClickMods - The state of the various modifiers at the time of the mouse move 00581 Returns: TRUE if it handled the Click, FALSE otherwise 00582 Purpose: To handle a Mouse Move event for the Mould Tool. 00583 SeeAlso: Tool::MouseClick; ClickType; ClickModifiers 00584 00585 ********************************************************************************************/ 00586 00587 void MouldTool::OnMouseMove(DocCoord PointerPos,Spread* pSpread,ClickModifiers ClickMods) 00588 { 00589 // Now scan through the selected moulds, and pass the move on 00590 DocView* pDocView = DocView::GetSelected(); 00591 ENSURE( pDocView != NULL, "MouldTool::OnMouseMove() Can't find selected DocView"); 00592 if (pDocView==NULL) 00593 return; 00594 00595 INT32 ctype,msgres; 00596 00597 BOOL claimed = DetermineClickEffect(PointerPos, pSpread, ClickMods, &ctype, &msgres); 00598 00599 if (!claimed) 00600 { 00601 ctype=1; 00602 msgres=1; 00603 } 00604 00605 // update the cursor if someones changed it 00606 Cursor* pCursor = ChooseCursor(ctype); 00607 if (pCursor!=NULL) 00608 ChangeCursor(pCursor); 00609 00610 String_256 StatusMsg(""); 00611 GenerateStatusLineText(msgres, &StatusMsg); 00612 GetApplication()->UpdateStatusBarText(&StatusMsg); 00613 } 00614 00615 00616 /************************************************************************************************************** 00617 00618 > BOOL MouldTool::DetermineClickEffect(DocCoord PointerPos, Spread* pSpread,ClickModifiers ClickMods, INT32* ctype, INT32* msgres) 00619 00620 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00621 Created: 07/02/95 00622 Inputs: PointerPos is the mouse position 00623 pSpread is a pointer to the spread containing the mouse position 00624 Outputs: ctype = an INT32 value indicating what resource cursor to use. 00625 msgres = an INT32 value indicating what resource message to use. 00626 Returns: TRUE if 00627 Purpose: Used when single clicking. This routine determines what effect a click will have. 00628 In this tool, clicking will add a segment to the end of a line, adjust the last element of 00629 a path or start a new path entirely. 00630 00631 ***************************************************************************************************************/ 00632 00633 BOOL MouldTool::DetermineClickEffect(DocCoord PointerPos,Spread* pSpread,ClickModifiers ClickMods, INT32* ctype, INT32* msgres) 00634 { 00635 // Find the selected range of objects 00636 SelRange* Selected = GetApplication()->FindSelection(); 00637 Node* pNode = Selected->FindFirst(); 00638 Node* pNext; 00639 BOOL claimed = FALSE; 00640 00641 // Set up a default value first 00642 (*msgres)=0; 00643 00644 while ((pNode != NULL) && (!claimed)) 00645 { 00646 // Find the next selected node 00647 pNext = Selected->FindNext(pNode); 00648 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 00649 claimed = ((NodeMould*)pNode)->OnMouseMove(PointerPos, pSpread, ClickMods, ctype, msgres); 00650 pNode = pNext; 00651 } 00652 00653 return claimed; 00654 } 00655 00656 00657 00658 00659 /******************************************************************************************** 00660 00661 > virtual BOOL MouldTool::GetStatusLineText(String_256* ptext, 00662 Spread* pSpread, 00663 DocCoord DocPos, 00664 ClickModifiers ClickMods) 00665 00666 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00667 Created: 07/02/95 00668 Inputs: pSpread - pointer to spread under mouse (else NULL) 00669 DocPos - position of mouse in doc (in spread coords) 00670 ClickMods - mouse click modifiers 00671 Outputs: ptext - text for status line 00672 Returns: TRUE if outputting valid text 00673 Purpose: generate up-to-date text for the status line (called on idles) 00674 Errors: ERROR1 if ptext is NULL 00675 00676 ********************************************************************************************/ 00677 00678 BOOL MouldTool::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord coord, ClickModifiers mods) 00679 { 00680 ERROR2IF(ptext==NULL,FALSE,"MouldTool::GetStatusLineText() passed a NULL text buffer"); 00681 00682 *ptext = ""; 00683 00684 // find what type of click we will generate 00685 INT32 ctype,msgres; 00686 DetermineClickEffect(coord, pSpread, mods, &ctype, &msgres); 00687 GenerateStatusLineText(msgres, ptext); 00688 00689 return TRUE; 00690 } 00691 00692 00693 00694 00695 /******************************************************************************************** 00696 00697 > void MouldTool::GenerateStatusLineText(INT32 msgres, String_256* pStatusMsg) 00698 00699 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00700 Created: 07/02/95 00701 Inputs: msgres = identifier of message resource 00702 pStatusMsg = pointer to a 256 character text buffer 00703 00704 Outputs: pStatusMsg - holds a text string 00705 Returns: - 00706 Purpose: Loads up an appropriate help string into the text buffer 00707 pointed to by pStatusMsg, using the msgres resource identifier 00708 Errors: - 00709 00710 ********************************************************************************************/ 00711 00712 void MouldTool::GenerateStatusLineText(INT32 msgres, String_256* pStatusMsg) 00713 { 00714 switch (msgres) 00715 { 00716 case 2: 00717 pStatusMsg->Load(_R(IDS_DRAGVPOINT), Tool::GetModuleID(GetID())); 00718 return; 00719 break; 00720 case 3: 00721 pStatusMsg->Load(_R(IDS_DRAGCOORD), Tool::GetModuleID(GetID())); 00722 return; 00723 break; 00724 00725 default: 00726 pStatusMsg->Load(_R(IDS_MOULDDEFAULT), Tool::GetModuleID(GetID())); 00727 return; 00728 break; 00729 } 00730 } 00731 00732 00733 00734 00735 00736 00737 /******************************************************************************************** 00738 00739 > void MouldTool::RenderToolBlobs(Spread* pSpread,DocRect* pDocRect) 00740 00741 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00742 Created: 30/11/94 00743 Inputs: pSpread = ptr to a spread 00744 pDocRect = ptr to DocRect of spread to render in 00745 Returns: - 00746 Purpose: Handles the RenderToolBlobs method. 00747 Renders the tool's blobs into the current doc view. 00748 SeeAlso: 00749 00750 ********************************************************************************************/ 00751 00752 void MouldTool::RenderToolBlobs(Spread* pSpread,DocRect* pDocRect) 00753 { 00754 // Render into the selected doc view 00755 DocView* pDocView = DocView::GetSelected(); 00756 if (pDocView != NULL) 00757 { 00758 // render you tool's blobs (if any) here 00759 } 00760 } 00761 00762 00763 /******************************************************************************************** 00764 00765 > static void MouldTool::DisplayStatusBarHelp(UINT32 StatusID) 00766 00767 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00768 Created: 30/11/94 00769 Inputs: StatusID = ID of status help string 00770 Outputs: - 00771 Returns: - 00772 Purpose: Displays the given status help string in the status bar 00773 SeeAlso: - 00774 00775 ********************************************************************************************/ 00776 00777 void MouldTool::DisplayStatusBarHelp(UINT32 StatusID) 00778 { 00779 String_256 StatusMsg(""); 00780 StatusMsg.Load(StatusID); 00781 GetApplication()->UpdateStatusBarText(&StatusMsg); 00782 } 00783 00784 00785 /******************************************************************************************** 00786 00787 > void MouldTool::CreateEnvelope(EnvelopeType EnvType) 00788 00789 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00790 Created: 12/12/94 00791 Purpose: Calls the CREATENEWMOULD operation with a default rectangular envelope 00792 shape 00793 00794 ********************************************************************************************/ 00795 00796 void MouldTool::CreateEnvelope(EnvelopeType EnvType) 00797 { 00798 // Make sure we have the operation ready 00799 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CREATENEWMOULD); 00800 if (pOpDesc) 00801 { 00802 // Create a manifold to use 00803 Path* pDefShape = new Path; 00804 if (pDefShape!=NULL) 00805 { 00806 BOOL LockAspect = FALSE; 00807 00808 if (pDefShape->Initialise(12,12)) 00809 { 00810 BOOL ok = FALSE; 00811 00812 switch (EnvType) 00813 { 00814 case ENV_DEFAULT: 00815 ok = EnvelopeShapes::Rectangular(pDefShape); 00816 break; 00817 00818 case ENV_CIRCULAR: 00819 ok = EnvelopeShapes::Circular(pDefShape); 00820 LockAspect = TRUE; 00821 break; 00822 00823 case ENV_ELLIPTICAL: 00824 ok = EnvelopeShapes::Circular(pDefShape); 00825 break; 00826 00827 case ENV_CONCAVE: 00828 ok = EnvelopeShapes::Concave(pDefShape); 00829 break; 00830 00831 case ENV_BANNER: 00832 ok = EnvelopeShapes::Banner(pDefShape); 00833 break; 00834 } 00835 00836 if (ok) 00837 { 00838 // now build the correct mould parameter and invoke the operation 00839 CreateMouldParam Param(pDefShape,MOULDSPACE_ENVELOPE,TRUE,LockAspect); 00840 pOpDesc->Invoke(&Param); 00841 } 00842 } 00843 } 00844 delete pDefShape; 00845 } 00846 } 00847 00848 /******************************************************************************************** 00849 00850 > void MouldTool::CreateEnvelope2x2(EnvelopeType EnvType) 00851 00852 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00853 Created: 12/12/94 00854 Purpose: Calls the CREATENEWMOULD operation with a default rectangular envelope 00855 shape 00856 00857 ********************************************************************************************/ 00858 00859 void MouldTool::CreateEnvelope2x2(EnvelopeType EnvType) 00860 { 00861 // Make sure we have the operation ready 00862 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CREATENEWMOULD); 00863 if (pOpDesc) 00864 { 00865 // Create a manifold to use 00866 Path* pDefShape = new Path; 00867 if (pDefShape!=NULL) 00868 { 00869 BOOL LockAspect = FALSE; 00870 00871 if (pDefShape->Initialise(12,12)) 00872 { 00873 BOOL ok = FALSE; 00874 00875 switch (EnvType) 00876 { 00877 case ENV_DEFAULT: 00878 ok = EnvelopeShapes::Rectangular2x2(pDefShape); 00879 break; 00880 00881 default: 00882 break; 00883 } 00884 00885 if (ok) 00886 { 00887 // now build the correct mould parameter and invoke the operation 00888 CreateMouldParam Param(pDefShape,MOULDSPACE_ENVELOPE2X2,TRUE,LockAspect); 00889 pOpDesc->Invoke(&Param); 00890 } 00891 } 00892 } 00893 delete pDefShape; 00894 } 00895 } 00896 00897 00898 /******************************************************************************************** 00899 00900 > void MouldTool::CreatePerspective(PerspectiveType PerType) 00901 00902 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00903 Created: 12/12/94 00904 Purpose: Calls the CREATENEWMOULD operation with a default rectangular perspective 00905 shape 00906 00907 ********************************************************************************************/ 00908 00909 void MouldTool::CreatePerspective(PerspectiveType PerType) 00910 { 00911 // Make sure we have the operation ready 00912 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CREATENEWMOULD); 00913 if (pOpDesc) 00914 { 00915 // Create a manifold to use 00916 Path* pDefShape = new Path; 00917 if (pDefShape!=NULL) 00918 { 00919 BOOL LockAspect = FALSE; 00920 00921 if (pDefShape->Initialise(12,12)) 00922 { 00923 BOOL ok = FALSE; 00924 00925 switch (PerType) 00926 { 00927 case PER_DEFAULT: 00928 ok = PerspectiveShapes::Rectangular(pDefShape); 00929 break; 00930 case PER_LEFT: 00931 ok = PerspectiveShapes::LeftWall(pDefShape); 00932 break; 00933 case PER_RIGHT: 00934 ok = PerspectiveShapes::RightWall(pDefShape); 00935 break; 00936 case PER_FLOOR: 00937 ok = PerspectiveShapes::Floor(pDefShape); 00938 break; 00939 case PER_ROOF: 00940 ok = PerspectiveShapes::Ceiling(pDefShape); 00941 break; 00942 } 00943 00944 if (ok) 00945 { 00946 // now build the correct mould parameter and invoke the operation 00947 CreateMouldParam Param(pDefShape,MOULDSPACE_PERSPECTIVE,TRUE,LockAspect); 00948 pOpDesc->Invoke(&Param); 00949 } 00950 } 00951 } 00952 delete pDefShape; 00953 } 00954 } 00955 00956 00957 00958 /******************************************************************************************** 00959 00960 > MouldInfoBarOp::MouldInfoBarOp() 00961 00962 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00963 Created: 13/01/96 00964 Inputs: - 00965 Outputs: - 00966 Returns: - 00967 Purpose: Constructor for the mould tool information bar operation. 00968 00969 ********************************************************************************************/ 00970 00971 MouldInfoBarOp::MouldInfoBarOp() 00972 { 00973 DlgResID = _R(IDD_MOULDTOOLBAR); 00974 DetachState=FALSE; 00975 } 00976 00977 00978 /******************************************************************************************** 00979 00980 > void MouldInfoBarOp::SetTool(MouldTool* pTool) 00981 00982 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00983 Created: 12/12/94 00984 Inputs: pTool, the pointer to the mould tool instance 00985 Outputs: - 00986 Returns: - 00987 Purpose: Sets the mould info bar tool pointer private variable 00988 00989 ********************************************************************************************/ 00990 00991 void MouldInfoBarOp::SetTool(MouldTool* pTool) 00992 { 00993 pMouldTool = pTool; 00994 } 00995 00996 00997 /******************************************************************************************** 00998 00999 > MsgResult MouldInfoBarOp::Message(Msg* Message) 01000 01001 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01002 Created: 30/11/94 01003 Inputs: Message = The message to handle 01004 Outputs: - 01005 Returns: - 01006 Purpose: Mould info bar dialog message handler 01007 Errors: - 01008 SeeAlso: - 01009 01010 ********************************************************************************************/ 01011 01012 MsgResult MouldInfoBarOp::Message(Msg* Message) 01013 { 01014 if (IS_OUR_DIALOG_MSG(Message)) 01015 { 01016 DialogMsg* Msg = (DialogMsg*)Message; 01017 01018 // Check if the message is a CANCEL 01019 switch (Msg->DlgMsg) 01020 { 01021 case DIM_CANCEL: 01022 Close(); // Close the dialog 01023 break; 01024 01025 case DIM_CREATE: 01026 // Initialise the infobar controls here 01027 // This is sent when you create the infobar in your tool startup code 01028 break; 01029 01030 case DIM_LFT_BN_CLICKED: 01031 { 01032 if (pMouldTool !=NULL) 01033 { 01034 if (FALSE) {} 01035 else if (Msg->GadgetID == _R(IDC_BTN_DEFAULTENVELOPE)) 01036 { 01037 pMouldTool->CreateEnvelope(ENV_DEFAULT); 01038 //pMouldTool->CreateEnvelope2x2(ENV_DEFAULT); 01039 } 01040 else if (Msg->GadgetID == _R(IDC_BTN_CIRCULARENVELOPE)) 01041 { 01042 pMouldTool->CreateEnvelope(ENV_CIRCULAR); 01043 } 01044 else if (Msg->GadgetID == _R(IDC_BTN_ELLIPTICENVELOPE)) 01045 { 01046 pMouldTool->CreateEnvelope(ENV_ELLIPTICAL); 01047 } 01048 else if (Msg->GadgetID == _R(IDC_BTN_CONCAVEENVELOPE)) 01049 { 01050 pMouldTool->CreateEnvelope(ENV_CONCAVE); 01051 } 01052 else if (Msg->GadgetID == _R(IDC_BTN_BANNERENVELOPE)) 01053 { 01054 pMouldTool->CreateEnvelope(ENV_BANNER); 01055 } 01056 else if (Msg->GadgetID == _R(IDC_BTN_DEFAULTPERSPECTIVE)) 01057 { 01058 pMouldTool->CreatePerspective(PER_DEFAULT); 01059 } 01060 else if (Msg->GadgetID == _R(IDC_BTN_LEFTPERSPECTIVE)) 01061 { 01062 pMouldTool->CreatePerspective(PER_LEFT); 01063 } 01064 else if (Msg->GadgetID == _R(IDC_BTN_RIGHTPERSPECTIVE)) 01065 { 01066 pMouldTool->CreatePerspective(PER_RIGHT); 01067 } 01068 else if (Msg->GadgetID == _R(IDC_BTN_FLOORPERSPECTIVE)) 01069 { 01070 pMouldTool->CreatePerspective(PER_FLOOR); 01071 } 01072 else if (Msg->GadgetID == _R(IDC_BTN_ROOFPERSPECTIVE)) 01073 { 01074 pMouldTool->CreatePerspective(PER_ROOF); 01075 } 01076 else if (Msg->GadgetID ==_R(IDC_BTN_DETACHMOULD)) 01077 { 01078 OpDetachMould* pOpDetachMould = new OpDetachMould; 01079 if (pOpDetachMould) 01080 pOpDetachMould->Do(NULL); 01081 SetDetachState(!DetachState); 01082 } 01083 01084 } 01085 } 01086 break; 01087 01088 case DIM_SELECTION_CHANGED: 01089 { 01090 } 01091 break; 01092 01093 default: 01094 break; 01095 } 01096 } 01097 // Pass the message on to the immediate mould class 01098 return (DialogBarOp::Message(Message)); 01099 } 01100 01101 01102 01103 /******************************************************************************************** 01104 01105 > virtual void MouldInfoBarOp::UpdateState() 01106 01107 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01108 Created: 12/11/94 01109 Purpose: Overrides the empty UpdateState function provided by InformationBarOp 01110 making a call to the function in DialogBarOp. 01111 01112 *********************************************************************************************/ 01113 01114 void MouldInfoBarOp::UpdateState() 01115 { 01116 // check that our tool is enabled and is current 01117 if (!pMouldTool) return; 01118 if (!pMouldTool->IsCurrent()) return; 01119 01120 DialogBarOp::UpdateState(); 01121 BOOL Selection = CheckSelection(); 01122 UpdateDefEnvButton(Selection); 01123 UpdateDefPerButton(Selection); 01124 UpdateDetachButton(Selection); 01125 } 01126 01127 01128 01129 /******************************************************************************************** 01130 01131 > void MouldInfoBarOp::UpdateDefEnvButton(BOOL Selection) 01132 01133 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01134 Created: 12/11/94 01135 Inputs: - 01136 Purpose: Sets the grey and select status of the default envelope button 01137 on the infobar. 01138 01139 ********************************************************************************************/ 01140 01141 void MouldInfoBarOp::UpdateDefEnvButton(BOOL Selection) 01142 { 01143 // Check for the existance of an info bar first 01144 if (WindowID) 01145 { 01146 if (!CanMouldSelection()) 01147 { 01148 // if we can't mould the selection, then disable all gadgets 01149 Selection = FALSE; 01150 } 01151 01152 EnableGadget(_R(IDC_BTN_DEFAULTENVELOPE), Selection); 01153 EnableGadget(_R(IDC_BTN_CIRCULARENVELOPE), Selection); 01154 EnableGadget(_R(IDC_BTN_ELLIPTICENVELOPE), Selection); 01155 EnableGadget(_R(IDC_BTN_CONCAVEENVELOPE), Selection); 01156 EnableGadget(_R(IDC_BTN_BANNERENVELOPE), Selection); 01157 01158 // if we have NOT enabled any of the above, then we should NOT allow you to paste a mould either! 01159 // This is a BODGE - that works! There is basically something wrong with the AllowOp mechanism, 01160 // and I do not have enough time to fix it .... 01161 01162 if (!Selection) 01163 { 01164 EnableGadget(_R(IDC_BTN_PASTEENVELOPE), Selection); 01165 } 01166 else 01167 { 01168 String_256 Desc; 01169 OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor (CC_RUNTIME_CLASS (OpPasteEnvelope)); 01170 01171 if (OpDesc != NULL) 01172 { 01173 OpState NewState = OpDesc->GetOpsState(&Desc); 01174 01175 if (NewState.Greyed == FALSE) 01176 { 01177 EnableGadget(_R(IDC_BTN_PASTEENVELOPE), Selection); 01178 } 01179 } 01180 } 01181 } 01182 } 01183 01184 /******************************************************************************************** 01185 01186 > BOOL MouldInfoBarOp::CanMouldSelection() 01187 01188 Author: David_McClarnon (Xara Group Ltd) <camelotdev@xara.com> 01189 Created: 30/7/99 01190 Inputs: - 01191 Returns: TRUE for the selection being able to be moulded, FALSE otherwise 01192 Purpose: Tests the selection to see if all nodes can be moulded 01193 Mainly tests for NeedsParent() nodes - if any exist in the selection, then 01194 we can't mould ! 01195 01196 ********************************************************************************************/ 01197 BOOL MouldInfoBarOp::CanMouldSelection() 01198 { 01199 Range * pRng = GetApplication()->FindSelection(); 01200 01201 Node * pParent = NULL; 01202 Node * pNode = pRng->FindFirst(FALSE); 01203 Node * pChild = NULL; 01204 01205 while (pNode) 01206 { 01207 pParent = pNode->FindParent(); 01208 01209 if (pParent) 01210 { 01211 if (pNode->NeedsParent(pParent)) 01212 { 01213 return FALSE; 01214 } 01215 } 01216 01217 // check for any needs parent nodes in the node's child list 01218 pChild = pNode->FindFirstDepthFirst(); 01219 01220 while (pChild) 01221 { 01222 if (pChild->NeedsParent(NULL)) 01223 { 01224 return FALSE; 01225 } 01226 01227 pChild = pChild->FindNextDepthFirst(pNode); 01228 } 01229 01230 pNode = pRng->FindNext(pNode, FALSE); 01231 } 01232 01233 return TRUE; 01234 } 01235 01236 /******************************************************************************************** 01237 01238 > void MouldInfoBarOp::UpdateDefPerButton() 01239 01240 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01241 Created: 12/11/94 01242 Inputs: - 01243 Purpose: Sets the grey and select status of the default perspective button 01244 on the infobar. 01245 01246 ********************************************************************************************/ 01247 01248 void MouldInfoBarOp::UpdateDefPerButton(BOOL Selection) 01249 { 01250 // Check for the existance of an info bar first 01251 if (WindowID) 01252 { 01253 if (!CanMouldSelection()) 01254 { 01255 // if we can't mould the selection, then disable all gadgets 01256 Selection = FALSE; 01257 } 01258 01259 EnableGadget(_R(IDC_BTN_DEFAULTPERSPECTIVE), Selection); 01260 EnableGadget(_R(IDC_BTN_LEFTPERSPECTIVE), Selection); 01261 EnableGadget(_R(IDC_BTN_RIGHTPERSPECTIVE), Selection); 01262 EnableGadget(_R(IDC_BTN_FLOORPERSPECTIVE), Selection); 01263 EnableGadget(_R(IDC_BTN_ROOFPERSPECTIVE), Selection); 01264 01265 // if we have NOT enabled any of the above, then we should NOT allow you to paste a mould either! 01266 // This is a BODGE - that works! There is basically something wrong with the AllowOp mechanism, 01267 // and I do not have enough time to fix it .... 01268 01269 if (!Selection) 01270 { 01271 EnableGadget(_R(IDC_BTN_PASTEPERSPECTIVE), Selection); 01272 } 01273 else 01274 { 01275 String_256 Desc; 01276 OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor (CC_RUNTIME_CLASS (OpPastePerspective)); 01277 01278 if (OpDesc != NULL) 01279 { 01280 OpState NewState = OpDesc->GetOpsState(&Desc); 01281 01282 if (NewState.Greyed == FALSE) 01283 { 01284 EnableGadget(_R(IDC_BTN_PASTEPERSPECTIVE), Selection); 01285 } 01286 } 01287 } 01288 } 01289 } 01290 01291 01292 /******************************************************************************************** 01293 01294 > void MouldInfoBarOp::UpdateDetachButton() 01295 01296 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01297 Created: 20/03/95 01298 Inputs: - 01299 Purpose: Sets the grey and select status of the detach button on the infobar. 01300 01301 ********************************************************************************************/ 01302 01303 void MouldInfoBarOp::UpdateDetachButton(BOOL Selection) 01304 { 01305 if (WindowID!=NULL) 01306 { 01307 if (!CanMouldSelection()) 01308 { 01309 // if we can't mould the selection, then disable all gadgets 01310 Selection = FALSE; 01311 } 01312 01313 EnableGadget(_R(IDC_BTN_DETACHMOULD), Selection); 01314 // if the button is enabled then set its state 01315 if (Selection) 01316 { 01317 NodeMould* pLastMould; 01318 INT32 nmoulds = SelInfo(&pLastMould); 01319 01320 // Set the detach button dependent on how many moulds are selected. 01321 BOOL Enabled = (nmoulds>0); 01322 BOOL PressedIn = ((nmoulds==1) && pLastMould->IsDetached()); 01323 01324 EnableGadget(_R(IDC_BTN_DETACHMOULD), Enabled); 01325 SetDetachState(PressedIn); 01326 } 01327 } 01328 } 01329 01330 /******************************************************************************************** 01331 01332 > void MouldInfoBarOp::SetDetachState() 01333 01334 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01335 Created: 20/03/95 01336 Inputs: - 01337 Purpose: Sets the detach button state. As we have no sensible button that clicks 01338 down then 01339 01340 ********************************************************************************************/ 01341 01342 void MouldInfoBarOp::SetDetachState(BOOL state) 01343 { 01344 // Is it down or up? 01345 SetLongGadgetValue(_R(IDC_BTN_DETACHMOULD), state); 01346 DetachState = state; 01347 } 01348 01349 01350 01351 /******************************************************************************************** 01352 01353 > INT32 MouldInfoBarOp::SelInfo(NodeMould** pMould) 01354 01355 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01356 Created: 20/03/95 01357 Inputs: pMould = a pointer to a mould object pointer to be used as a return parameter 01358 Outputs: pMould = a pointer to the last selected mould object 01359 Returns: The number of mould objects selected 01360 Purpose: Find out how many moulds are selected and return a pointer to the last 01361 selected mould. 01362 01363 ********************************************************************************************/ 01364 01365 INT32 MouldInfoBarOp::SelInfo(NodeMould** pMould) 01366 { 01367 SelRange* Selection = GetApplication()->FindSelection(); 01368 Node* pNode = Selection->FindFirst(); 01369 NodeMould* pLastMould=NULL; 01370 01371 INT32 num = 0; 01372 while (pNode!=NULL) 01373 { 01374 if (IS_A(pNode, NodeMould) && pNode->IsSelected()) 01375 { 01376 num++; 01377 pLastMould = (NodeMould*)pNode; 01378 } 01379 pNode = Selection->FindNext(pNode); 01380 } 01381 01382 (*pMould)=pLastMould; 01383 return num; 01384 } 01385 01386 01387 /******************************************************************************************** 01388 01389 > void MouldInfoBarOp::CheckSelection() 01390 01391 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01392 Created: 12/11/94 01393 Inputs: - 01394 Returns: TRUE if there are selected objects in the current document 01395 FALSE if nothing is selected 01396 Purpose: Checks for selected objects in the current document and returns whether 01397 there are any or not 01398 01399 ********************************************************************************************/ 01400 01401 BOOL MouldInfoBarOp::CheckSelection() 01402 { 01403 BOOL Enabled = FALSE; 01404 01405 /* 01406 if (Document::GetCurrent() != NULL) 01407 { 01408 SelRange* Selected = GetApplication()->FindSelection(); 01409 Node* pNode = Selected->FindFirst(); 01410 Enabled = (pNode!=NULL); 01411 } 01412 */ 01413 01414 // Get the selection and the number of selected objects 01415 SelRange* Selected = GetApplication()->FindSelection(); 01416 INT32 Count = 0; 01417 if (Document::GetSelected() != NULL) 01418 Count = Selected->Count(); 01419 01420 // Are there any selected objects? 01421 if (Count > 0) 01422 { 01423 ObjChangeFlags cFlags; 01424 01425 // If only one node selected, then it will just be replaced in the tree with another NodeRenderableInk node 01426 // Otherwise, the selected node could be moved, and if the node is a child of another node, effectively 01427 // delete a child node of a parent. 01428 /* 01429 if (Count == 1) 01430 cFlags.ReplaceNode = TRUE; 01431 else 01432 cFlags.DeleteNode = TRUE; 01433 */ 01434 // **** Above code commented out due to imcomplete implementation 01435 // 01436 // For now, just pretend that the op is as severe as deleting to get the mould tool buttons to grey out 01437 // when the mould is selected inside the blend. (Haven't got time to do this properly at the moment) 01438 cFlags.MultiReplaceNode = TRUE; 01439 01440 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); 01441 01442 Node* pNode = Selected->FindFirst(); 01443 01444 Enabled = TRUE; 01445 while (pNode != NULL && Enabled) 01446 { 01447 Enabled = pNode->AllowOp(&ObjChange,FALSE); 01448 pNode = Selected->FindNext(pNode); 01449 } 01450 } 01451 01452 return Enabled; 01453 } 01454 01455 01456 01457 /******************************************************************************************** 01458 01459 > OpCreateNewMould::OpCreateNewMould() 01460 01461 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01462 Created: 11/12/94 01463 Purpose: OpCreateNewMould() constructor 01464 SeeAlso: - 01465 01466 ********************************************************************************************/ 01467 01468 OpCreateNewMould::OpCreateNewMould() 01469 { 01470 m_space = MOULDSPACE_UNDEFINED; 01471 } 01472 01473 01474 01475 01476 /******************************************************************************************** 01477 01478 > BOOL OpCreateNewMould::Init() 01479 01480 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01481 Created: 11/12/94 01482 Inputs: - 01483 Outputs: - 01484 Returns: TRUE if the operation could be successfully initialised 01485 FALSE if no more memory could be allocated 01486 01487 Purpose: OpDeletePoints initialiser method 01488 Errors: ERROR will be called if there was insufficient memory to allocate the 01489 operation. 01490 SeeAlso: - 01491 01492 ********************************************************************************************/ 01493 01494 BOOL OpCreateNewMould::Init() 01495 { 01496 return (RegisterOpDescriptor(0, // tool ID 01497 _R(IDS_CREATENEWMOULD), // string resource ID 01498 CC_RUNTIME_CLASS(OpCreateNewMould), // runtime class for Op 01499 OPTOKEN_CREATENEWMOULD, // Ptr to token string 01500 OpCreateNewMould::GetState, // GetState function 01501 0, // help ID 01502 _R(IDBBL_CREATENEWMOULD), // bubble help ID 01503 0 // resource ID 01504 )); 01505 01506 } 01507 01508 01509 /******************************************************************************************** 01510 01511 > void OpCreateNewMould::GetOpName(String_256* OpName) 01512 01513 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01514 Created: 11/12/94 01515 Inputs: - 01516 Outputs: The undo string for the operation 01517 Returns: 01518 Purpose: The GetOpName fn is overridden so that we return back a description 01519 appropriate to the type of attribute that the operation applies. 01520 01521 Errors: - 01522 SeeAlso: - 01523 01524 ********************************************************************************************/ 01525 01526 void OpCreateNewMould::GetOpName(String_256* OpName) 01527 { 01528 switch (m_space) 01529 { 01530 case MOULDSPACE_ENVELOPE: 01531 *OpName = String_256(_R(IDS_UNDO_ENVELOPE)); 01532 break; 01533 case MOULDSPACE_ENVELOPE2X2: 01534 *OpName = String_256(_R(IDS_UNDO_ENVELOPE)); 01535 break; 01536 case MOULDSPACE_PERSPECTIVE: 01537 *OpName = String_256(_R(IDS_UNDO_PERSPECTIVE)); 01538 break; 01539 default: 01540 *OpName = String_256(_R(IDS_UNDO_CREATENEWMOULD)); 01541 break; 01542 } 01543 } 01544 01545 01546 /******************************************************************************************** 01547 01548 > OpState OpCreateNewMould::GetState(String_256*, OpDescriptor*) 01549 01550 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01551 Created: 11/12/94 01552 Inputs: - 01553 Outputs: - 01554 Returns: The state of the OpCreateNewMould 01555 Purpose: For finding the OpCreateNewMould state. 01556 01557 ********************************************************************************************/ 01558 01559 OpState OpCreateNewMould::GetState(String_256* UIDescription, OpDescriptor*) 01560 { 01561 OpState OpSt; 01562 OpSt.Greyed = TRUE; 01563 01564 // only ungrey if we have a selection 01565 SelRange* pSelRange = GetApplication()->FindSelection(); 01566 if (pSelRange && pSelRange->FindFirst() != NULL) 01567 OpSt.Greyed=FALSE; 01568 01569 return OpSt; 01570 } 01571 01572 01573 /******************************************************************************************** 01574 01575 > void OpCreateNewMould::DoWithParam(OpDescriptor* pOpDescr, OpParam* pOpParam) 01576 01577 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01578 Created: 11/12/94 01579 Inputs: pOpDescr = pointer to an OpDescriptor (unused) 01580 pOpParam = pointer to an OpParam 01581 Outputs: - 01582 Returns: - 01583 Purpose: This operation will create a new mould object, and thus start off quite 01584 a complicated chain of events. 01585 First off, a mouldgroup node is created and all objects are moved into it as 01586 children, along with any inherited attributes. 01587 Secondly a mould object is created and initialise with the shape passed to 01588 this do function. 01589 The mouldgroup node is now added to the mould node as a first child. 01590 A moulder object is then created and added as the last child of the mould 01591 node. It is not added to the next object of the mouldgroup, as there may be 01592 more than one moulder object. 01593 The moulder object is then asked to initialise itself. In doing so it will 01594 scan the mould group children and ask them to make shapes of themselves. 01595 These shapes are stored in a list within the moulder class, (not in the tree). 01596 Having constructed the moulder, a mould operation is triggered, whence all current 01597 moulder list objects are mangled by the mould shape class functions (held 01598 within the mould parent class). These mangled objects are added as children 01599 of the moulder object. 01600 Having done all this without running out of memory, the mouldgroup object is 01601 hidden. 01602 01603 Errors: failandexecute will be called if the operation fails in some way, most 01604 likely when no memory is available. 01605 01606 ********************************************************************************************/ 01607 01608 void OpCreateNewMould::DoWithParam(OpDescriptor* pOpDescr, OpParam* pParam) 01609 { 01610 ERROR3IF(pParam == NULL, "OpCreateNewMould::DoWithParam - NULL Param passed in"); 01611 01612 BeginSlowJob(); 01613 01614 // Initialise ourselves from the supplied parameters 01615 CreateMouldParam* CreateMould = (CreateMouldParam*)pParam; 01616 01617 if (!CreateNewMould(CreateMould->ParamShape, 01618 CreateMould->ParamSpace, 01619 CreateMould->FitSelection, 01620 CreateMould->LockAspect)) 01621 FailAndExecute(); 01622 01623 End(); 01624 } 01625 01626 01627 01628 01629 /******************************************************************************************** 01630 01631 > OpRemoveMould::OpRemoveMould() 01632 01633 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01634 Created: 18/01/95 01635 Purpose: Constructor for remove mould shape operation 01636 SeeAlso: - 01637 01638 ********************************************************************************************/ 01639 01640 OpRemoveMould::OpRemoveMould() 01641 { 01642 // Dummy constructor 01643 } 01644 01645 01646 01647 /******************************************************************************************** 01648 01649 > BOOL OpRemoveMould::Init() 01650 01651 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01652 Created: 18/01/95 01653 Inputs: - 01654 Outputs: - 01655 Returns: TRUE if the operation could be successfully initialised 01656 FALSE if no more memory could be allocated 01657 Purpose: Initialise the remove mould operation so that it can be accessed from the 01658 interface. 01659 01660 Errors: ERROR will be called if there was insufficient memory to allocate the 01661 operation. 01662 SeeAlso: - 01663 01664 ********************************************************************************************/ 01665 01666 BOOL OpRemoveMould::Init() 01667 { 01668 return (RegisterOpDescriptor(0, // tool ID 01669 _R(IDS_REMOVEMOULD), // string resource ID 01670 CC_RUNTIME_CLASS(OpRemoveMould), // runtime class for Op 01671 OPTOKEN_REMOVEMOULD, // Ptr to token string 01672 OpRemoveMould::GetState, // GetState function 01673 0, // help ID 01674 _R(IDBBL_REMOVEMOULD), // bubble help ID 01675 _R(IDC_REMOVEMOULD), // resource ID 01676 _R(IDC_REMOVEMOULD) // control ID 01677 )); 01678 } 01679 01680 01681 /******************************************************************************************** 01682 01683 > OpState OpRemoveMould::GetState(String_256*, OpDescriptor*) 01684 01685 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01686 Created: 18/01/95 01687 Inputs: - 01688 Outputs: - 01689 Returns: The state of the OpRemoveMould 01690 Purpose: For finding the OpRemoveMould state. 01691 01692 ********************************************************************************************/ 01693 01694 OpState OpRemoveMould::GetState(String_256* UIDescription, OpDescriptor*) 01695 { 01696 OpState OpSt; 01697 String_256 DisableReason; 01698 OpSt.Greyed = TRUE; 01699 01700 // if (!IsAMouldSelected(NULL)) 01701 // OpSt.Greyed=TRUE; 01702 01703 ObjChangeFlags cFlags; 01704 cFlags.MultiReplaceNode = TRUE; 01705 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); 01706 01707 SelRange* pSelRange = GetApplication()->FindSelection(); 01708 Node* pNode = pSelRange->FindFirst(); 01709 01710 while (pNode != NULL && OpSt.Greyed) 01711 { 01712 if (IS_A(pNode,NodeMould)) 01713 OpSt.Greyed = !(pNode->AllowOp(&ObjChange,FALSE)); 01714 01715 pNode = pSelRange->FindNext(pNode); 01716 } 01717 01718 return (OpSt); 01719 } 01720 01721 01722 01723 /******************************************************************************************** 01724 01725 > void OpRemoveMould::GetOpName(String_256* OpName) 01726 01727 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01728 Created: 18/01/95 01729 Inputs: - 01730 Outputs: The undo string for the operation 01731 Returns: 01732 Purpose: The GetOpName fn is overridden so that we return back a description 01733 appropriate to the type of attribute that the operation applies. 01734 01735 ********************************************************************************************/ 01736 01737 void OpRemoveMould::GetOpName(String_256* OpName) 01738 { 01739 *OpName = String_256(_R(IDS_UNDO_REMOVEMOULD)); 01740 } 01741 01742 01743 01744 01745 01746 01747 /******************************************************************************************** 01748 01749 > void OpRemoveMould::Do(OpDescriptor* opDesc) 01750 01751 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01752 Created: 18/01/95 01753 Inputs: pointer to an OpDescriptor (unused) 01754 Outputs: - 01755 Returns: - 01756 Purpose: 01757 Errors: failandexecute will be called if the operation fails in some way, most 01758 likely when no memory is available. 01759 01760 ********************************************************************************************/ 01761 01762 void OpRemoveMould::Do(OpDescriptor*) 01763 { 01764 BeginSlowJob(); 01765 01766 // remember the selection before the operation 01767 if (DoStartSelOp(FALSE,FALSE)) 01768 { 01769 // Obtain the current selections 01770 SelRange* Selected = GetApplication()->FindSelection(); 01771 if (Selected) 01772 { 01773 // compile a list of the selected objects 01774 DocRect Bounds = Selected->GetBoundingRect(); 01775 List* pNodeList = Selected->MakeListOfNodes(); 01776 01777 // remove all mould objects in the list 01778 BOOL success = DoRemoveAllMoulds(pNodeList); 01779 01780 // delete all elements in our compiled list 01781 while (!pNodeList->IsEmpty()) 01782 delete (NodeListItem*)(pNodeList->RemoveHead()); 01783 delete pNodeList; 01784 01785 // update the selection 01786 if (success) 01787 { 01788 // Update all the changed parents. 01789 ObjChangeFlags cFlags; 01790 cFlags.MultiReplaceNode = TRUE; 01791 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this); 01792 if (!UpdateChangedNodes(&ObjChange)) 01793 FailAndExecute(); 01794 } 01795 else 01796 FailAndExecute(); 01797 } 01798 else 01799 FailAndExecute(); 01800 } 01801 else 01802 FailAndExecute(); 01803 01804 End(); 01805 } 01806 01807 01808 01809 01810 01811 01812 /******************************************************************************************** 01813 01814 > OpCopyMouldShape::OpCopyMouldShape() 01815 01816 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01817 Created: 18/01/95 01818 Purpose: Constructor for copy mould shape operation 01819 SeeAlso: - 01820 01821 ********************************************************************************************/ 01822 01823 OpCopyMouldShape::OpCopyMouldShape() 01824 { 01825 // Dummy constructor 01826 } 01827 01828 01829 01830 /******************************************************************************************** 01831 01832 > BOOL OpCopyMouldShape::Init() 01833 01834 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01835 Created: 18/01/95 01836 Inputs: - 01837 Outputs: - 01838 Returns: TRUE if the operation could be successfully initialised 01839 FALSE if no more memory could be allocated 01840 Purpose: Initialise the copy mould operation so that it can be accessed from the 01841 interface. 01842 01843 Errors: ERROR will be called if there was insufficient memory to allocate the 01844 operation. 01845 SeeAlso: - 01846 01847 ********************************************************************************************/ 01848 01849 BOOL OpCopyMouldShape::Init() 01850 { 01851 return (RegisterOpDescriptor(0, // tool ID 01852 _R(IDS_COPYMOULD), // string resource ID 01853 CC_RUNTIME_CLASS(OpCopyMouldShape), // runtime class for Op 01854 OPTOKEN_COPYMOULD, // Ptr to token string 01855 OpCopyMouldShape::GetState, // GetState function 01856 0, // help ID 01857 _R(IDBBL_COPYMOULD), // bubble help ID 01858 _R(IDD_MOULDTOOLBAR), // resource ID 01859 _R(IDC_BTN_COPYMOULD), // control ID 01860 SYSTEMBAR_EDIT, // Group bar ID 01861 TRUE, // Receive messages 01862 FALSE, // Smart 01863 FALSE, // Clean 01864 0, // One open Instance ID 01865 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION) 01866 )); 01867 01868 } 01869 01870 01871 /******************************************************************************************** 01872 01873 > OpState OpCopyMouldShape::GetState(String_256*, OpDescriptor*) 01874 01875 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01876 Created: 18/01/95 01877 Inputs: - 01878 Outputs: - 01879 Returns: The state of the OpCopyMouldShape 01880 Purpose: For finding the OpCopyMouldShape state. 01881 01882 ********************************************************************************************/ 01883 01884 OpState OpCopyMouldShape::GetState(String_256* UIDescription, OpDescriptor*) 01885 { 01886 OpState OpSt; 01887 String_256 DisableReason; 01888 OpSt.Greyed = FALSE; 01889 01890 if (!IsAMouldSelected(NULL)) 01891 OpSt.Greyed=TRUE; 01892 01893 return (OpSt); 01894 } 01895 01896 01897 01898 /******************************************************************************************** 01899 01900 > void OpCopyMouldShape::GetOpName(String_256* OpName) 01901 01902 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01903 Created: 18/01/95 01904 Inputs: - 01905 Outputs: The undo string for the operation 01906 Returns: 01907 Purpose: The GetOpName fn is overridden so that we return back a description 01908 appropriate to the type of attribute that the operation applies. 01909 01910 ********************************************************************************************/ 01911 01912 void OpCopyMouldShape::GetOpName(String_256* OpName) 01913 { 01914 *OpName = String_256(_R(IDS_UNDO_COPYMOULD)); 01915 } 01916 01917 01918 01919 01920 01921 01922 /******************************************************************************************** 01923 01924 > void OpCopyMouldShape::Do(OpDescriptor* opDesc) 01925 01926 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01927 Created: 18/01/95 01928 Inputs: pointer to an OpDescriptor (unused) 01929 Outputs: - 01930 Returns: - 01931 Purpose: Copies the mould node path to the clipboard so it can be used as a template 01932 object for further moulds. 01933 Errors: failandexecute will be called if the operation fails in some way, most 01934 likely when no memory is available. 01935 01936 ********************************************************************************************/ 01937 01938 void OpCopyMouldShape::Do(OpDescriptor*) 01939 { 01940 NodeMould* pNodeMould; 01941 NodeMouldPath* pMouldPath; 01942 01943 if (!DoStartSelOp(TRUE,TRUE)) 01944 goto Failed; 01945 01946 if (IsAMouldSelected(&pNodeMould)) 01947 { 01948 // find the actual shape we need to copy. 01949 pMouldPath = pNodeMould->GetPathShape(); 01950 if (pMouldPath==NULL) 01951 goto Failed; 01952 01953 // RangeControl Cntrl = Selected + Unselected + don't cross layers 01954 Range CopyRange(pMouldPath,pMouldPath,RangeControl(TRUE,TRUE,FALSE)); 01955 if (!DoCopyNodesToClipboard(CopyRange)) 01956 goto Failed; 01957 } 01958 End(); 01959 return; 01960 01961 Failed: 01962 FailAndExecute(); 01963 End(); 01964 return; 01965 } 01966 01967 01968 01969 01970 /******************************************************************************************** 01971 01972 > OpPasteMouldShape::OpPasteMouldShape() 01973 01974 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01975 Created: 18/01/95 01976 Purpose: Constructor for paste mould shape operation 01977 SeeAlso: - 01978 01979 ********************************************************************************************/ 01980 01981 OpPasteMouldShape::OpPasteMouldShape() 01982 { 01983 // Dummy constructor 01984 } 01985 01986 /******************************************************************************************** 01987 01988 > BOOL OpPasteMouldShape::FindPasteObject(Node** pReturnNode) 01989 01990 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 01991 Created: 09/02/95 01992 Inputs: pReturnNode, a pointer to a pointer, which can be null if no return 01993 node is required. 01994 Outputs: pReturnNode holds a pointer to the node to be pasted, if a suitable node 01995 has been found and the pointer pointer is none null on entry 01996 Returns: TRUE if a suitable paste object has been found 01997 FALSE if none 01998 Purpose: This function scans for objects on the clipboard. It tries to find the 01999 first object which 02000 Is a NodeRenderableInk 02001 Can become a nodepath 02002 If there is such an object the function will return true, and set the 02003 return pointer to point at the object if the return pointer exists ie is 02004 a none null receptor. 02005 02006 ********************************************************************************************/ 02007 02008 BOOL OpPasteMouldShape::FindPasteObject(Node** pReturnNode) 02009 { 02010 BOOL found=FALSE; 02011 02012 // find the first object 02013 Node* pNode = InternalClipboard::GetInsertionLayer()->FindFirstChild(); 02014 while (pNode && !found) 02015 { 02016 // ok lets check what we've got here 02017 BecomeA TestBecomeAPath(BECOMEA_TEST, CC_RUNTIME_CLASS(NodePath)); 02018 if ((pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk))) && 02019 (pNode->CanBecomeA(&TestBecomeAPath)) 02020 ) 02021 found=TRUE; 02022 else 02023 pNode=pNode->FindNext(); 02024 } 02025 02026 if (found && pReturnNode) 02027 *pReturnNode=pNode; 02028 02029 return found; 02030 } 02031 02032 02033 02034 /******************************************************************************************** 02035 02036 > void OpPasteMouldShape::Do(MouldSpace mSpace) 02037 02038 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02039 Created: 18/01/95 02040 Inputs: mSpace = the mould space to paste as 02041 Outputs: - 02042 Returns: - 02043 Purpose: Take the contents of the clipboard and try to use whatever shape exists 02044 there as a mould shape. The mould space type is passed to this function 02045 as a parameter. The function will find the first renderable object on the 02046 clipboard, try to make shapes of it and use the first shape returned as 02047 the mould space object. 02048 Errors: failandexecute will be called if the operation fails in some way, most 02049 likely when no memory is available. 02050 02051 ********************************************************************************************/ 02052 02053 void OpPasteMouldShape::Do(MouldSpace mSpace) 02054 { 02055 BeginSlowJob(); 02056 02057 Node* pPasteNode; 02058 BOOL Constrain=KeyPress::IsConstrainPressed(); 02059 02060 // Obtain the current selections 02061 SelRange* Selected = GetApplication()->FindSelection(); 02062 if (!Selected) 02063 { 02064 FailAndExecute(); End(); return; 02065 } 02066 02067 // is there a suitable object on the clipboard? 02068 if (!FindPasteObject(&pPasteNode)) 02069 { 02070 FailAndExecute(); End(); return; 02071 } 02072 02073 // HERE 02074 02075 // If so lets force the object to become a nodepath 02076 // Do this none undoably because we are doing things on the clipboard. 02077 // If we DoBecomeA passback on a perspectivised filled object, it hides 02078 // the original? 02079 MouldBecomeA ParamBecomeA( BECOMEA_PASSBACK, 02080 CC_RUNTIME_CLASS(NodePath), 02081 NULL); 02082 02083 // Get pNode to generate its paths for us 02084 BOOL ok = pPasteNode->DoBecomeA(&ParamBecomeA); 02085 // whip the resulting mould path out of the do becomea param class 02086 NodePath* pNodePath = ParamBecomeA.GetMouldPath(); 02087 if ((!ok) || pNodePath==NULL) 02088 { 02089 FailAndExecute(); End(); return; 02090 } 02091 02092 // remember the selection before the operation 02093 if (!DoStartSelOp(TRUE,TRUE)) 02094 { 02095 FailAndExecute(); End(); return; 02096 } 02097 02098 ObjChangeFlags cFlags; 02099 cFlags.DeleteNode = TRUE; 02100 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); 02101 02102 if (!Selected->AllowOp(&ObjChange)) 02103 { 02104 ERROR3("AllowOp() returned FALSE, i.e. op should have been greyed out"); 02105 FailAndExecute(); End(); return; 02106 } 02107 02108 // Trash the selection bounds 02109 Range Rnge = (*Selected); 02110 if (!DoInvalidateNodesRegions(Rnge,TRUE,TRUE)) 02111 { 02112 FailAndExecute(); End(); return; 02113 } 02114 02115 // Calculate the destination paste position 02116 DocRect Bounds = Selected->GetBoundingRect(); 02117 DocRect sBounds = pNodePath->GetBoundingRect(); 02118 02119 Node* pNode = Selected->FindFirst(); 02120 if (pNode==NULL) 02121 { 02122 FailAndExecute(); End(); return; 02123 } 02124 02125 if (!Constrain) 02126 { 02127 // If we're not constraining, then we might have to force constrain 02128 // on to ensure the object pastes within the bounds of the spread. 02129 // We'll try to expand the pasteboard, and if that fails, we'll 02130 // turn constrain on 02131 02132 // find the spread of the destination selected node (fix to Jason bug) 02133 Spread *pSpread = pNode->FindParentSpread(); 02134 if (pSpread == NULL || !pSpread->ExpandPasteboardToInclude(sBounds)) 02135 Constrain=TRUE; 02136 } 02137 02138 if (Constrain) 02139 { 02140 // if 'control' constrain is pressed then paste the mould 02141 // shape centred over the selection otherwise leave it where 02142 // it is. 02143 INT32 tx = (Bounds.lo.x+Bounds.hi.x)/2 - (sBounds.lo.x+sBounds.hi.x)/2; 02144 INT32 ty = (Bounds.lo.y+Bounds.hi.y)/2 - (sBounds.lo.y+sBounds.hi.y)/2; 02145 Trans2DMatrix trans(tx,ty); 02146 pNodePath->Transform(trans); 02147 } 02148 02149 // Grab the ink path from its node 02150 Path* pShape = &(pNodePath->InkPath); 02151 02152 // using this list create or replace the mould bits 02153 ok = DoCreateOrReplaceMould(Selected, pShape, mSpace, TRUE, FALSE); 02154 if (!ok) 02155 FailAndExecute(); 02156 02157 // Update all the changed nodes, i.e. tell all the parents of the children that have been effected 02158 ObjChange.Define (OBJCHANGE_FINISHED,cFlags,NULL,this); 02159 UpdateChangedNodes(&ObjChange); 02160 02161 End(); 02162 } 02163 02164 02165 /******************************************************************************************** 02166 02167 > MouldBecomeA::~MouldBecomeA() 02168 02169 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02170 Created: 25/09/96 02171 Purpose: Destructor for the MouldBecomeA parameter 02172 SeeAlso: - 02173 02174 ********************************************************************************************/ 02175 02176 MouldBecomeA::~MouldBecomeA() 02177 { 02178 Destroy(); 02179 } 02180 02181 02182 /*********************************************************************************************** 02183 02184 > virtual BOOL MouldBecomeA::PassBack(NodeRenderableInk* pNewNode, 02185 NodeRenderableInk* pCreatedByNode, 02186 CCAttrMap* pAttrMap) 02187 02188 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02189 Created: 09/02/95 02190 Inputs: pNewNode = ptr to Node that been generated by a node via its 02191 DoBecomeA() method 02192 pCreatedByNode = ptr to the node that created pNewNode 02193 Outputs: - 02194 Returns: TRUE if Successful, FALSE otherwise 02195 02196 Purpose: From the call ProducerObj->DoBecomeA( MouldBecomeA(ObjectType) ) 02197 this function being a member of MouldBecomeA will be passed objects of ObjectType 02198 created by ProducerObj. We store the first object passed to us and ignore the 02199 rest as we really can only use one thanks very much. Most simple producers will 02200 probably return single objects anyway. 02201 02202 ***********************************************************************************************/ 02203 02204 BOOL MouldBecomeA::PassBack(NodeRenderableInk* pNewNode, 02205 NodeRenderableInk* pCreatedByNode, 02206 CCAttrMap* pAttrMap) 02207 { 02208 if ( (MouldBecomeA::pNodePath==NULL) && (pNewNode->IsKindOf(CC_RUNTIME_CLASS(NodePath))) ) 02209 MouldBecomeA::pNodePath=(NodePath*)pNewNode; 02210 else 02211 { 02212 // remember on a pass back we own this object so we 02213 // really need to delete it if we're not going to use it! 02214 pNewNode->CascadeDelete(); 02215 delete pNewNode; 02216 pNewNode = NULL; 02217 } 02218 02219 return TRUE; 02220 } 02221 02222 /******************************************************************************************** 02223 02224 > void MouldBecomeA::Destroy() 02225 02226 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02227 Created: 18/01/95 02228 Purpose: Destroy the contents of the mould become a object 02229 SeeAlso: - 02230 02231 ********************************************************************************************/ 02232 02233 void MouldBecomeA::Destroy() 02234 { 02235 // remember on a pass back we own this object so we 02236 // really need to delete it if we're not going to use it! 02237 if (pNodePath) 02238 { 02239 pNodePath->CascadeDelete(); 02240 delete pNodePath; 02241 pNodePath = NULL; 02242 } 02243 } 02244 02245 02246 /******************************************************************************************** 02247 02248 > OpPasteEnvelope::OpPasteEnvelope() 02249 02250 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02251 Created: 18/01/95 02252 Purpose: Constructor for paste envelope operation 02253 SeeAlso: - 02254 02255 ********************************************************************************************/ 02256 02257 OpPasteEnvelope::OpPasteEnvelope() 02258 { 02259 // Dummy constructor 02260 } 02261 02262 02263 /******************************************************************************************** 02264 02265 > BOOL OpPasteEnvelope::Init() 02266 02267 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02268 Created: 18/01/95 02269 Inputs: - 02270 Outputs: - 02271 Returns: TRUE if the operation could be successfully initialised 02272 FALSE if no more memory could be allocated 02273 Purpose: Initialise the paste mould operation so that it can be accessed from the 02274 interface. 02275 02276 Errors: ERROR will be called if there was insufficient memory to allocate the 02277 operation. 02278 SeeAlso: - 02279 02280 ********************************************************************************************/ 02281 02282 BOOL OpPasteEnvelope::Init() 02283 { 02284 return (RegisterOpDescriptor(0, // tool ID 02285 _R(IDS_PASTEENVELOPE), // string resource ID 02286 CC_RUNTIME_CLASS(OpPasteEnvelope), // runtime class for Op 02287 OPTOKEN_PASTEENVELOPE, // Ptr to token string 02288 OpPasteEnvelope::GetState, // GetState function 02289 0, // help ID 02290 _R(IDBBL_PASTEENVELOPE), // bubble help ID 02291 _R(IDD_MOULDTOOLBAR), // resource ID 02292 _R(IDC_BTN_PASTEENVELOPE), // control ID 02293 SYSTEMBAR_EDIT, // Group bar ID 02294 TRUE, // Receive messages 02295 FALSE, // Smart 02296 FALSE, // Clean 02297 0, // One open Instance ID 02298 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION) 02299 )); 02300 } 02301 02302 02303 /******************************************************************************************** 02304 02305 > OpState OpPasteEnvelope::GetState(String_256*, OpDescriptor*) 02306 02307 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02308 Created: 18/01/95 02309 Inputs: - 02310 Outputs: - 02311 Returns: The state of the OpPasteMouldShape 02312 Purpose: For finding the OpPasteMouldShape state. 02313 02314 ********************************************************************************************/ 02315 02316 OpState OpPasteEnvelope::GetState(String_256* UIDescription, OpDescriptor*) 02317 { 02318 OpState OpSt; 02319 // String_256 DisableReason; 02320 // OpSt.Greyed=(!FindPasteObject(NULL)); 02321 02322 OpSt.Greyed = TRUE; 02323 02324 if (FindPasteObject(NULL)) 02325 { 02326 // Get the selection and the number of selected objects 02327 SelRange* Selected = GetApplication()->FindSelection(); 02328 INT32 Count = Selected->Count(); 02329 02330 // Are there any selected objects? 02331 if (Count > 0) 02332 { 02333 ObjChangeFlags cFlags; 02334 cFlags.DeleteNode = TRUE; 02335 OpPasteEnvelope* op = new OpPasteEnvelope (); // need an op to do correct processing 02336 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,op); 02337 02338 Node* pNode = Selected->FindFirst(); 02339 OpSt.Greyed = FALSE; 02340 while (pNode != NULL && !OpSt.Greyed) 02341 { 02342 OpSt.Greyed = !pNode->AllowOp(&ObjChange,FALSE); 02343 pNode = Selected->FindNext(pNode); 02344 } 02345 delete (op); 02346 } 02347 } 02348 02349 return(OpSt); 02350 } 02351 02352 02353 02354 02355 /******************************************************************************************** 02356 02357 > void OpPasteEnvelope::GetOpName(String_256* OpName) 02358 02359 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02360 Created: 18/01/95 02361 Inputs: - 02362 Outputs: The undo string for the operation 02363 Returns: 02364 Purpose: The GetOpName fn is overridden so that we return back a description 02365 appropriate to the type of attribute that the operation applies. 02366 02367 ********************************************************************************************/ 02368 02369 void OpPasteEnvelope::GetOpName(String_256* OpName) 02370 { 02371 *OpName = String_256(_R(IDS_UNDO_PASTEENVELOPE)); 02372 } 02373 02374 02375 02376 02377 /******************************************************************************************** 02378 02379 > void OpPasteEnvelope::Do(OpDescriptor* opDesc) 02380 02381 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02382 Created: 18/01/95 02383 Inputs: pointer to an OpDescriptor (unused) 02384 pointer to a pastemould parameter block 02385 Outputs: - 02386 Returns: - 02387 Purpose: 02388 Errors: failandexecute will be called if the operation fails in some way, most 02389 likely when no memory is available. 02390 02391 ********************************************************************************************/ 02392 02393 void OpPasteEnvelope::Do(OpDescriptor* pOpDescr) 02394 { 02395 // just call the parent class 02396 OpPasteMouldShape::Do(MOULDSPACE_ENVELOPE); 02397 } 02398 02399 02400 02401 02402 /******************************************************************************************** 02403 02404 > OpPastePerspective::OpPastePerspective() 02405 02406 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02407 Created: 18/01/95 02408 Purpose: Constructor for paste envelope operation 02409 SeeAlso: - 02410 02411 ********************************************************************************************/ 02412 02413 OpPastePerspective::OpPastePerspective() 02414 { 02415 // Dummy constructor 02416 } 02417 02418 02419 /******************************************************************************************** 02420 02421 > BOOL OpPastePerspective::Init() 02422 02423 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02424 Created: 18/01/95 02425 Inputs: - 02426 Outputs: - 02427 Returns: TRUE if the operation could be successfully initialised 02428 FALSE if no more memory could be allocated 02429 Purpose: Initialise the paste mould operation so that it can be accessed from the 02430 interface. 02431 02432 Errors: ERROR will be called if there was insufficient memory to allocate the 02433 operation. 02434 SeeAlso: - 02435 02436 ********************************************************************************************/ 02437 02438 BOOL OpPastePerspective::Init() 02439 { 02440 return (RegisterOpDescriptor(0, // tool ID 02441 _R(IDS_PASTEPERSPECTIVE), // string resource ID 02442 CC_RUNTIME_CLASS(OpPastePerspective), // runtime class for Op 02443 OPTOKEN_PASTEPERSPECTIVE, // Ptr to token string 02444 OpPastePerspective::GetState, // GetState function 02445 0, // help ID 02446 _R(IDBBL_PASTEPERSPECTIVE), // bubble help ID 02447 _R(IDD_MOULDTOOLBAR), // resource ID 02448 _R(IDC_BTN_PASTEPERSPECTIVE), // control ID 02449 SYSTEMBAR_EDIT, // Group bar ID 02450 TRUE, // Receive messages 02451 FALSE, // Smart 02452 FALSE, // Clean 02453 0, // One open Instance ID 02454 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION) 02455 )); 02456 } 02457 02458 02459 /******************************************************************************************** 02460 02461 > OpState OpPastePerspective::GetState(String_256*, OpDescriptor*) 02462 02463 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02464 Created: 18/01/95 02465 Inputs: - 02466 Outputs: - 02467 Returns: The state of the OpPasteMouldShape 02468 Purpose: For finding the OpPasteMouldShape state. 02469 02470 ********************************************************************************************/ 02471 02472 OpState OpPastePerspective::GetState(String_256* UIDescription, OpDescriptor*) 02473 { 02474 OpState OpSt; 02475 // String_256 DisableReason; 02476 // OpSt.Greyed=(!FindPasteObject(NULL)); 02477 02478 OpSt.Greyed = TRUE; 02479 02480 if (FindPasteObject(NULL)) 02481 { 02482 // Get the selection and the number of selected objects 02483 SelRange* Selected = GetApplication()->FindSelection(); 02484 INT32 Count = Selected->Count(); 02485 02486 // Are there any selected objects? 02487 if (Count > 0) 02488 { 02489 ObjChangeFlags cFlags; 02490 cFlags.DeleteNode = TRUE; 02491 OpPasteEnvelope* op = new OpPasteEnvelope (); // need an op to do correct processing 02492 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,op); 02493 02494 Node* pNode = Selected->FindFirst(); 02495 OpSt.Greyed = FALSE; 02496 while (pNode != NULL && !OpSt.Greyed) 02497 { 02498 OpSt.Greyed = !pNode->AllowOp(&ObjChange,FALSE); 02499 pNode = Selected->FindNext(pNode); 02500 } 02501 delete (op); 02502 } 02503 } 02504 02505 return(OpSt); 02506 } 02507 02508 02509 02510 02511 /******************************************************************************************** 02512 02513 > void OpPastePerspective::GetOpName(String_256* OpName) 02514 02515 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02516 Created: 18/01/95 02517 Inputs: - 02518 Outputs: The undo string for the operation 02519 Returns: 02520 Purpose: The GetOpName fn is overridden so that we return back a description 02521 appropriate to the type of attribute that the operation applies. 02522 02523 ********************************************************************************************/ 02524 02525 void OpPastePerspective::GetOpName(String_256* OpName) 02526 { 02527 *OpName = String_256(_R(IDS_UNDO_PASTEPERSPECTIVE)); 02528 } 02529 02530 02531 02532 02533 /******************************************************************************************** 02534 02535 > void OpPastePerspective::Do(OpDescriptor* opDesc) 02536 02537 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02538 Created: 18/01/95 02539 Inputs: pointer to an OpDescriptor (unused) 02540 pointer to a pastemould parameter block 02541 Outputs: - 02542 Returns: - 02543 Purpose: 02544 Errors: failandexecute will be called if the operation fails in some way, most 02545 likely when no memory is available. 02546 02547 ********************************************************************************************/ 02548 02549 void OpPastePerspective::Do(OpDescriptor* pOpDescr) 02550 { 02551 // just call the parent class 02552 OpPasteMouldShape::Do(MOULDSPACE_PERSPECTIVE); 02553 } 02554 02555 02556 02557 02558 02559 /******************************************************************************************** 02560 02561 > OpToggleMouldGrid::OpToggleMouldGrid() 02562 02563 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02564 Created: 18/01/95 02565 Purpose: Constructor for toggle mould grid operation 02566 SeeAlso: - 02567 02568 ********************************************************************************************/ 02569 02570 OpToggleMouldGrid::OpToggleMouldGrid() 02571 { 02572 // Dummy constructor 02573 } 02574 02575 02576 02577 /******************************************************************************************** 02578 02579 > BOOL OpToggleMouldGrid::Init() 02580 02581 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02582 Created: 18/01/95 02583 Inputs: - 02584 Outputs: - 02585 Returns: TRUE if the operation could be successfully initialised 02586 FALSE if no more memory could be allocated 02587 Purpose: Initialise the toggle mould grid operation so that it can be accessed from the 02588 interface. 02589 02590 Errors: ERROR will be called if there was insufficient memory to allocate the 02591 operation. 02592 SeeAlso: - 02593 02594 ********************************************************************************************/ 02595 02596 BOOL OpToggleMouldGrid::Init() 02597 { 02598 return (RegisterOpDescriptor(0, // tool ID 02599 _R(IDS_TOGGLEMOULDGRID), // string resource ID 02600 CC_RUNTIME_CLASS(OpToggleMouldGrid), // runtime class for Op 02601 OPTOKEN_TOGGLEMOULDGRID, // Ptr to token string 02602 OpToggleMouldGrid::GetState, // GetState function 02603 0, // help ID 02604 _R(IDBBL_TOGGLEMOULDGRID), // bubble help ID 02605 _R(IDD_MOULDTOOLBAR), // resource ID 02606 _R(IDC_BTN_TOGGLEMOULDGRID), // control ID 02607 SYSTEMBAR_EDIT, // Group bar ID 02608 TRUE, // Receive messages 02609 FALSE, // Smart 02610 FALSE, // Clean 02611 0, // One open Instance ID 02612 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION) 02613 )); 02614 } 02615 02616 02617 /******************************************************************************************** 02618 02619 > OpState OpToggleMouldGrid::GetState(String_256*, OpDescriptor*) 02620 02621 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02622 Created: 18/01/95 02623 Inputs: - 02624 Outputs: - 02625 Returns: The state of the OpToggleMouldGrid 02626 Purpose: For finding the OpToggleMouldGrid state. 02627 02628 ********************************************************************************************/ 02629 02630 OpState OpToggleMouldGrid::GetState(String_256* UIDescription, OpDescriptor*) 02631 { 02632 OpState OpSt; 02633 String_256 DisableReason; 02634 OpSt.Greyed = FALSE; 02635 02636 /* 02637 if (Document::GetCurrent() != NULL) 02638 { 02639 SelRange* Selected = GetApplication()->FindSelection(); 02640 if (Selected) 02641 if (!Selected->FindObject(CC_RUNTIME_CLASS(NodeMould), NULL)) 02642 OpSt.Greyed = TRUE; 02643 } 02644 */ 02645 02646 BOOL Sel = FALSE; 02647 if (Document::GetCurrent() != NULL) 02648 { 02649 SelRange* Selected = GetApplication()->FindSelection(); 02650 if (Selected) 02651 { 02652 Node* pNode = Selected->FindFirst(); 02653 while ((pNode!=NULL) && (!Sel)) 02654 { 02655 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 02656 Sel=TRUE; 02657 02658 pNode = Selected->FindNext(pNode); 02659 } 02660 } 02661 } 02662 02663 if (!Sel) 02664 OpSt.Greyed = TRUE; 02665 02666 return (OpSt); 02667 } 02668 02669 02670 /******************************************************************************************** 02671 02672 > void OpToggleMouldGrid::Do(OpDescriptor* opDesc) 02673 02674 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02675 Created: 18/01/95 02676 Inputs: pointer to an OpDescriptor (unused) 02677 Outputs: - 02678 Returns: - 02679 Purpose: 02680 Errors: failandexecute will be called if the operation fails in some way, most 02681 likely when no memory is available. 02682 02683 ********************************************************************************************/ 02684 02685 void OpToggleMouldGrid::Do(OpDescriptor*) 02686 { 02687 // Get a snapshot of the selection 02688 SelRange* Selected = GetApplication()->FindSelection(); 02689 Node* pNode = Selected->FindFirst(); 02690 while (pNode) 02691 { 02692 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 02693 { 02694 NodeMould* pMould = (NodeMould*)pNode; 02695 MouldGeometry* pGeometry = pMould->GetGeometry(); 02696 if (pGeometry!=NULL) 02697 { 02698 Spread* pSpread = pNode->FindParentSpread(); 02699 if (pSpread) 02700 pGeometry->ToggleControlBlobs(pSpread); 02701 } 02702 } 02703 pNode = Selected->FindNext(pNode); 02704 } 02705 End(); 02706 } 02707 02708 02709 02710 02711 02712 02713 /******************************************************************************************** 02714 02715 > OpDetachMould::OpDetachMould() 02716 02717 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02718 Created: 20/03/95 02719 Purpose: Constructor for Detach mould operation 02720 SeeAlso: - 02721 02722 ********************************************************************************************/ 02723 02724 OpDetachMould::OpDetachMould() 02725 { 02726 // Dummy constructor 02727 } 02728 02729 02730 02731 /******************************************************************************************** 02732 02733 > BOOL OpDetachMould::Init() 02734 02735 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02736 Created: 20/03/95 02737 Inputs: - 02738 Outputs: - 02739 Returns: TRUE if the operation could be successfully initialised 02740 FALSE if no more memory could be allocated 02741 Purpose: Initialise the detach mould operation so that it can be accessed from the 02742 interface. 02743 02744 Errors: ERROR will be called if there was insufficient memory to allocate the 02745 operation. 02746 SeeAlso: - 02747 02748 ********************************************************************************************/ 02749 02750 BOOL OpDetachMould::Init() 02751 { 02752 return (RegisterOpDescriptor(0, // tool ID 02753 _R(IDS_DETACHMOULD), // string resource ID 02754 CC_RUNTIME_CLASS(OpDetachMould), // runtime class for Op 02755 OPTOKEN_DETACHMOULD, // Ptr to token string 02756 OpDetachMould::GetState, // GetState function 02757 0, // help ID 02758 _R(IDBBL_DETACHMOULD), // bubble help ID 02759 0 02760 )); 02761 } 02762 02763 02764 /******************************************************************************************** 02765 02766 > OpState OpDetachMould::GetState(String_256*, OpDescriptor*) 02767 02768 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02769 Created: 20/03/95 02770 Inputs: - 02771 Outputs: - 02772 Returns: The state of the OpDetachMould 02773 Purpose: For finding the OpDetachMould state. 02774 02775 ********************************************************************************************/ 02776 02777 OpState OpDetachMould::GetState(String_256* UIDescription, OpDescriptor*) 02778 { 02779 OpState OpSt; 02780 String_256 DisableReason; 02781 02782 NodeMould* pLastMould; 02783 INT32 nmoulds = MouldInfoBarOp::SelInfo(&pLastMould); 02784 02785 // Set the detach operation tick and grey fields correctly 02786 OpSt.Greyed = (nmoulds==0); 02787 OpSt.Ticked = ((nmoulds==1) && pLastMould->IsDetached()); 02788 02789 return (OpSt); 02790 } 02791 02792 /******************************************************************************************** 02793 02794 > void OpDetachMould::GetOpName(String_256* OpName) 02795 02796 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02797 Created: 18/01/95 02798 Inputs: - 02799 Outputs: The undo string for the operation 02800 Returns: 02801 Purpose: The GetOpName fn is overridden so that we return back a description 02802 appropriate to the type of attribute that the operation applies. 02803 02804 ********************************************************************************************/ 02805 02806 void OpDetachMould::GetOpName(String_256* OpName) 02807 { 02808 *OpName = String_256(_R(IDS_UNDO_DETACHMOULD)); 02809 } 02810 02811 02812 02813 /******************************************************************************************** 02814 02815 > void OpDetachMould::Do(OpDescriptor*) 02816 02817 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02818 Created: 20/03/95 02819 Inputs: pointer to an OpDescriptor (unused) 02820 Outputs: - 02821 Returns: - 02822 Purpose: 02823 Errors: failandexecute will be called if the operation fails in some way, most 02824 likely when no memory is available. 02825 02826 ********************************************************************************************/ 02827 02828 void OpDetachMould::Do(OpDescriptor*) 02829 { 02830 BeginSlowJob(); 02831 02832 // Note, I only spent the whole afternoon trying to work out why DoStartSelOp(XX,YY) 02833 // Was completely screwing up the selection here. Anyway, the solution was to 02834 // derive this op from UndoableOperation, not SelOperation which solved the problem 02835 // immediately. The morel is, if the selection is not changing, dont use SelOperation! 02836 // + It stops lots of flashing of blobs too. 02837 02838 // Scan the selection 02839 SelRange* Selected = GetApplication()->FindSelection(); 02840 Node* pNode = Selected->FindFirst(); 02841 while (pNode) 02842 { 02843 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 02844 { 02845 NodeMould* pMould = (NodeMould*)pNode; 02846 02847 SaveDetachAction* pSaveDetAct; 02848 ALLOC_WITH_FAIL(pSaveDetAct, (new SaveDetachAction), this); 02849 if (pSaveDetAct==NULL) 02850 { 02851 FailAndExecute(); End(); return; 02852 } 02853 02854 if ((pSaveDetAct->Save(this, pMould))==AC_FAIL) 02855 { 02856 FailAndExecute(); End(); return; 02857 } 02858 02859 // toggle the detach type 02860 pMould->ToggleDetachFlag(); 02861 02862 if (!pMould->IsDetached()) 02863 { 02864 if (!DoInvalidateNodeRegion(pMould,TRUE)) 02865 { 02866 FailAndExecute(); End(); return; 02867 } 02868 02869 if (pMould->StartSaveContext(this,REC_REBUILD)!=CC_OK) 02870 { 02871 FailAndExecute(); End(); return; 02872 } 02873 02874 if (pMould->RemouldAll(this)!=CC_OK) 02875 { 02876 FailAndExecute(); End(); return; 02877 } 02878 02879 if (pMould->EndSaveContext(this,REC_REBUILD)!=CC_OK) 02880 { 02881 FailAndExecute(); End(); return; 02882 } 02883 } 02884 } 02885 pNode = Selected->FindNext(pNode); 02886 } 02887 02888 End(); 02889 } 02890 02891 02892 02893 02894 /******************************************************************************************** 02895 02896 > OpRotateMould::OpRotateMould() 02897 02898 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02899 Created: 20/02/95 02900 Purpose: Constructor for Detach mould operation 02901 SeeAlso: - 02902 02903 ********************************************************************************************/ 02904 02905 OpRotateMould::OpRotateMould() 02906 { 02907 // Dummy constructor 02908 } 02909 02910 02911 02912 /******************************************************************************************** 02913 02914 > BOOL OpRotateMould::Init() 02915 02916 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02917 Created: 20/03/95 02918 Inputs: - 02919 Outputs: - 02920 Returns: TRUE if the operation could be successfully initialised 02921 FALSE if no more memory could be allocated 02922 Purpose: Initialise the rotate mould operation so that it can be accessed from the 02923 interface. 02924 Errors: ERROR will be called if there was insufficient memory to allocate the 02925 operation. 02926 02927 ********************************************************************************************/ 02928 02929 BOOL OpRotateMould::Init() 02930 { 02931 return (RegisterOpDescriptor(0, // tool ID 02932 _R(IDS_ROTATEMOULD), // string resource ID 02933 CC_RUNTIME_CLASS(OpRotateMould), // runtime class for Op 02934 OPTOKEN_ROTATEMOULD, // Ptr to token string 02935 OpRotateMould::GetState, // GetState function 02936 0, // help ID 02937 _R(IDBBL_ROTATEMOULD), // bubble help ID 02938 _R(IDD_MOULDTOOLBAR), // resource ID 02939 _R(IDC_BTN_ROTATEMOULD), // control ID 02940 SYSTEMBAR_EDIT, // Group bar ID 02941 TRUE, // Receive messages 02942 FALSE, // Smart 02943 FALSE, // Clean 02944 0, // One open Instance ID 02945 (GREY_WHEN_NO_CURRENT_DOC | GREY_WHEN_NO_SELECTION) 02946 )); 02947 02948 } 02949 02950 02951 /******************************************************************************************** 02952 02953 > OpState OpRotateMould::GetState(String_256*, OpDescriptor*) 02954 02955 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 02956 Created: 20/03/95 02957 Inputs: - 02958 Outputs: - 02959 Returns: The state of the OpRotateMould 02960 Purpose: For finding the OpRotateMould state. 02961 02962 ********************************************************************************************/ 02963 02964 OpState OpRotateMould::GetState(String_256* UIDescription, OpDescriptor*) 02965 { 02966 OpState OpSt; 02967 String_256 DisableReason; 02968 OpSt.Greyed = FALSE; 02969 02970 BOOL Sel = FALSE; 02971 if (Document::GetCurrent() != NULL) 02972 { 02973 SelRange* Selected = GetApplication()->FindSelection(); 02974 if (Selected) 02975 { 02976 Node* pNode = Selected->FindFirst(); 02977 while ((pNode!=NULL) && (!Sel)) 02978 { 02979 // only rotate mould objects if they're not detached. 02980 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 02981 { 02982 if ( !((NodeMould*)pNode)->IsDetached() ) 02983 Sel=TRUE; 02984 } 02985 pNode = Selected->FindNext(pNode); 02986 } 02987 } 02988 } 02989 02990 if (!Sel) 02991 OpSt.Greyed = TRUE; 02992 02993 return (OpSt); 02994 } 02995 02996 /******************************************************************************************** 02997 02998 > void OpRotateMould::GetOpName(String_256* OpName) 02999 03000 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03001 Created: 18/01/95 03002 Inputs: - 03003 Outputs: The undo string for the operation 03004 Returns: 03005 Purpose: The GetOpName fn is overridden so that we return back a description 03006 appropriate to the type of attribute that the operation applies. 03007 03008 ********************************************************************************************/ 03009 03010 void OpRotateMould::GetOpName(String_256* OpName) 03011 { 03012 *OpName = String_256(_R(IDS_UNDO_ROTATEMOULD)); 03013 } 03014 03015 /******************************************************************************************** 03016 03017 > void OpRotateMould::Do(OpDescriptor* opDesc) 03018 03019 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03020 Created: 18/01/95 03021 Inputs: pointer to an OpDescriptor (unused) 03022 Outputs: - 03023 Returns: - 03024 Purpose: Scan through the selection finding mould objects. Each mould will have 03025 its contents remoulded, having has its mould path rotated around 03026 logically by one element. The result will be to spin the orientation 03027 of the moulded objects around. 03028 Errors: failandexecute will be called if the operation fails in some way, most 03029 likely when no memory is available. 03030 03031 ********************************************************************************************/ 03032 03033 void OpRotateMould::Do(OpDescriptor*) 03034 { 03035 BeginSlowJob(); 03036 SelRange* Selected = GetApplication()->FindSelection(); 03037 Node* pNode = Selected->FindFirst(); 03038 while (pNode) 03039 { 03040 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeMould)) 03041 { 03042 NodeMould* pMould = (NodeMould*)pNode; 03043 03044 if (!DoInvalidateNodeRegion(pMould,TRUE)) 03045 { 03046 FailAndExecute(); End(); return; 03047 } 03048 03049 if (!DoRotateMould(pMould)) 03050 { 03051 FailAndExecute(); End(); return; 03052 } 03053 } 03054 pNode = Selected->FindNext(pNode); 03055 } 03056 End(); 03057 } 03058 03059 03060 03061 03062 03063 /******************************************************************************************** 03064 03065 > OpRectangularEnvelope::OpRectangularEnvelope() 03066 03067 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03068 Created: 20/02/95 03069 Purpose: Constructor for Detach mould operation 03070 SeeAlso: - 03071 03072 ********************************************************************************************/ 03073 03074 OpRectangularEnvelope::OpRectangularEnvelope() 03075 { 03076 // Dummy constructor 03077 } 03078 03079 03080 03081 /******************************************************************************************** 03082 03083 > BOOL OpRectangularEnvelope::Init() 03084 03085 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03086 Created: 20/03/95 03087 Inputs: - 03088 Outputs: - 03089 Returns: TRUE if the operation could be successfully initialised 03090 FALSE if no more memory could be allocated 03091 Purpose: Initialise the rotate mould operation so that it can be accessed from the 03092 interface. 03093 Errors: ERROR will be called if there was insufficient memory to allocate the 03094 operation. 03095 03096 ********************************************************************************************/ 03097 03098 BOOL OpRectangularEnvelope::Init() 03099 { 03100 return (RegisterOpDescriptor(0, // tool ID 03101 _R(IDS_RECTANGULARENVELOPE), // string resource ID 03102 CC_RUNTIME_CLASS(OpRectangularEnvelope),// runtime class for Op 03103 OPTOKEN_RECTANGULARENVELOPE, // Ptr to token string 03104 OpRectangularEnvelope::GetState, // GetState function 03105 0, // help ID 03106 _R(IDBBL_RECTANGULARENVELOPE) 03107 )); 03108 } 03109 03110 03111 /******************************************************************************************** 03112 03113 > OpState OpRectangularEnvelope::GetState(String_256*, OpDescriptor*) 03114 03115 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03116 Created: 20/03/95 03117 Inputs: - 03118 Outputs: - 03119 Returns: The state of the OpRotateMould 03120 Purpose: For finding the OpRotateMould state. 03121 03122 ********************************************************************************************/ 03123 03124 OpState OpRectangularEnvelope::GetState(String_256* UIDescription, OpDescriptor*) 03125 { 03126 OpState OpSt; 03127 String_256 DisableReason; 03128 OpSt.Greyed = TRUE; 03129 03130 ObjChangeFlags cFlags; 03131 cFlags.MultiReplaceNode = TRUE; 03132 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); 03133 03134 SelRange* pSelRange = GetApplication()->FindSelection(); 03135 Node* pNode = pSelRange->FindFirst(); 03136 03137 while (pNode != NULL && OpSt.Greyed) 03138 { 03139 OpSt.Greyed = !(pNode->AllowOp(&ObjChange,FALSE)); 03140 pNode = pSelRange->FindNext(pNode); 03141 } 03142 03143 return (OpSt); 03144 } 03145 03146 /******************************************************************************************** 03147 03148 > void OpRectangularEnvelope::GetOpName(String_256* OpName) 03149 03150 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03151 Created: 18/01/95 03152 Inputs: - 03153 Outputs: The undo string for the operation 03154 Returns: 03155 Purpose: The GetOpName fn is overridden so that we return back a description 03156 appropriate to the type of attribute that the operation applies. 03157 03158 ********************************************************************************************/ 03159 03160 void OpRectangularEnvelope::GetOpName(String_256* OpName) 03161 { 03162 *OpName = String_256(_R(IDS_UNDO_RECTANGULARENVELOPE)); 03163 } 03164 03165 /******************************************************************************************** 03166 03167 > void OpRectangularEnvelope::Do(OpDescriptor* opDesc) 03168 03169 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03170 Created: 18/01/95 03171 Inputs: pointer to an OpDescriptor (unused) 03172 Outputs: - 03173 Returns: - 03174 Purpose: Scan through the selection finding mould objects. Each mould will have 03175 its contents remoulded, having has its mould path rotated around 03176 logically by one element. The result will be to spin the orientation 03177 of the moulded objects around. 03178 Errors: failandexecute will be called if the operation fails in some way, most 03179 likely when no memory is available. 03180 03181 ********************************************************************************************/ 03182 03183 void OpRectangularEnvelope::Do(OpDescriptor*) 03184 { 03185 BeginSlowJob(); 03186 03187 // Assume faied until proven otherwise. 03188 BOOL Failed=TRUE; 03189 03190 // Create a manifold to use 03191 Path* pDefShape = new Path; 03192 if (pDefShape!=NULL) 03193 { 03194 if (pDefShape->Initialise(12,12)) 03195 { 03196 if (EnvelopeShapes::Rectangular(pDefShape)) 03197 { 03198 Failed=!CreateNewMould(pDefShape, MOULDSPACE_ENVELOPE, TRUE, FALSE); 03199 } 03200 } 03201 // remove the shape once used 03202 delete pDefShape; 03203 } 03204 03205 if (Failed) 03206 FailAndExecute(); 03207 03208 End(); 03209 } 03210 03211 03212 03213 03214 03215 /******************************************************************************************** 03216 03217 > OpRectangularPerspective::OpRectangularPerspective() 03218 03219 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03220 Created: 20/02/95 03221 Purpose: Constructor for Detach mould operation 03222 SeeAlso: - 03223 03224 ********************************************************************************************/ 03225 03226 OpRectangularPerspective::OpRectangularPerspective() 03227 { 03228 // Dummy constructor 03229 } 03230 03231 03232 03233 /******************************************************************************************** 03234 03235 > BOOL OpRectangularPerspective::Init() 03236 03237 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03238 Created: 20/03/95 03239 Inputs: - 03240 Outputs: - 03241 Returns: TRUE if the operation could be successfully initialised 03242 FALSE if no more memory could be allocated 03243 Purpose: Initialise the rotate mould operation so that it can be accessed from the 03244 interface. 03245 Errors: ERROR will be called if there was insufficient memory to allocate the 03246 operation. 03247 03248 ********************************************************************************************/ 03249 03250 BOOL OpRectangularPerspective::Init() 03251 { 03252 return (RegisterOpDescriptor(0, // tool ID 03253 _R(IDS_RECTANGULARPERSPECTIVE), // string resource ID 03254 CC_RUNTIME_CLASS(OpRectangularPerspective), // runtime class for Op 03255 OPTOKEN_RECTANGULARPERSPECTIVE, // Ptr to token string 03256 OpRectangularPerspective::GetState, // GetState function 03257 0, // help ID 03258 _R(IDBBL_RECTANGULARPERSPECTIVE) 03259 )); 03260 } 03261 03262 03263 /******************************************************************************************** 03264 03265 > OpState OpRectangularPerspective::GetState(String_256*, OpDescriptor*) 03266 03267 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03268 Created: 20/03/95 03269 Inputs: - 03270 Outputs: - 03271 Returns: The state of the OpRotateMould 03272 Purpose: For finding the OpRotateMould state. 03273 03274 ********************************************************************************************/ 03275 03276 OpState OpRectangularPerspective::GetState(String_256* UIDescription, OpDescriptor*) 03277 { 03278 OpState OpSt; 03279 String_256 DisableReason; 03280 OpSt.Greyed = TRUE; 03281 03282 ObjChangeFlags cFlags; 03283 cFlags.MultiReplaceNode = TRUE; 03284 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL); 03285 03286 SelRange* pSelRange = GetApplication()->FindSelection(); 03287 Node* pNode = pSelRange->FindFirst(); 03288 03289 while (pNode != NULL && OpSt.Greyed) 03290 { 03291 OpSt.Greyed = !(pNode->AllowOp(&ObjChange,FALSE)); 03292 pNode = pSelRange->FindNext(pNode); 03293 } 03294 03295 return (OpSt); 03296 } 03297 03298 /******************************************************************************************** 03299 03300 > void OpRectangularPerspective::GetOpName(String_256* OpName) 03301 03302 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03303 Created: 18/01/95 03304 Inputs: - 03305 Outputs: The undo string for the operation 03306 Returns: 03307 Purpose: The GetOpName fn is overridden so that we return back a description 03308 appropriate to the type of attribute that the operation applies. 03309 03310 ********************************************************************************************/ 03311 03312 void OpRectangularPerspective::GetOpName(String_256* OpName) 03313 { 03314 *OpName = String_256(_R(IDS_UNDO_RECTANGULARPERSPECTIVE)); 03315 } 03316 03317 /******************************************************************************************** 03318 03319 > void OpRectangularPerspective::Do(OpDescriptor* opDesc) 03320 03321 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 03322 Created: 18/01/95 03323 Inputs: pointer to an OpDescriptor (unused) 03324 Outputs: - 03325 Returns: - 03326 Purpose: Scan through the selection finding mould objects. Each mould will have 03327 its contents remoulded, having has its mould path rotated around 03328 logically by one element. The result will be to spin the orientation 03329 of the moulded objects around. 03330 Errors: failandexecute will be called if the operation fails in some way, most 03331 likely when no memory is available. 03332 03333 ********************************************************************************************/ 03334 03335 void OpRectangularPerspective::Do(OpDescriptor*) 03336 { 03337 BeginSlowJob(); 03338 03339 // Assume faied until proven otherwise. 03340 BOOL Failed=TRUE; 03341 03342 // Create a manifold to use 03343 Path* pDefShape = new Path; 03344 if (pDefShape!=NULL) 03345 { 03346 if (pDefShape->Initialise(12,12)) 03347 { 03348 if (PerspectiveShapes::Rectangular(pDefShape)) 03349 { 03350 Failed=!CreateNewMould(pDefShape, MOULDSPACE_PERSPECTIVE, TRUE, FALSE); 03351 } 03352 } 03353 // remove the shape once used 03354 delete pDefShape; 03355 } 03356 03357 if (Failed) 03358 FailAndExecute(); 03359 03360 End(); 03361 } 03362 03363