00001 // $Id: sgframe.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 00099 // SGFrame.cpp - Frame SuperGallery classes - FrameSGallery and SGDisplayFrame 00100 00101 00102 #include "camtypes.h" 00103 00104 //#include "app.h" // For GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED] 00105 //#include "gallery.h" // For _R(IDC_GALLERY_LISTBOX) 00106 //#include "galres.h" 00107 //#include "galstr.h" 00108 #include "layergal.h" 00109 #include "sgdrag.h" 00110 #include "sginit.h" 00111 #include "sgframe.h" 00112 #include "sgmenu.h" 00113 00114 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00115 #include "layer.h" 00116 //#include "markn.h" 00117 //#include "resource.h" 00118 //#include "barsdlgs.h" 00119 //#include "simon.h" 00120 #include "sprdmsg.h" 00121 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00122 #include "dragmgr.h" 00123 //#include "docvmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00124 00125 #include "ccdc.h" // For render-into-dialogue support 00126 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00127 #include "grnddib.h" 00128 #include "guides.h" 00129 //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00130 #include "layerprp.h" 00131 #include "layermsg.h" 00132 00133 //#include "richard2.h" 00134 //#include "andy.h" 00135 //#include "prevwres.h" // _R(IDS_FRAMEGAL_FRAMES) _R(IDB_FGAL_OVERLAY) 00136 #include "frameops.h" // OPTOKEN_FRAME_DELETEFRAME ... 00137 #include "prevwdlg.h" 00138 #include "keypress.h" 00139 #include "aprps.h" 00140 //#include "zordops.h" // OPTOKEN_COMBINELAYERSTOFRAMELAYER 00141 #include "progress.h" 00142 #include "helpuser.h" //For help button 00143 //#include "xshelpid.h" //For help button 00144 //#include "helppath.h" 00145 00146 void Beep(); 00147 00148 #ifndef EXCLUDE_GALS 00149 // Implement the dynamic class bits... 00150 CC_IMPLEMENT_DYNCREATE(FrameSGallery, LayerSGallery) 00151 CC_IMPLEMENT_DYNAMIC(SGFrameGroup, SGLayerGroup) 00152 CC_IMPLEMENT_DYNAMIC(SGDisplayFrame, SGDisplayLayer) 00153 #else 00154 CC_IMPLEMENT_DYNCREATE(FrameSGallery, Operation) 00155 #endif 00156 00157 // This line mustn't go before any CC_IMPLEMENT_... macros 00158 #define new CAM_DEBUG_NEW 00159 00160 #ifndef EXCLUDE_GALS 00161 00162 /*********************************************************************************************** 00163 00164 > SGFrameGroup::SGFrameGroup(SuperGallery *ParentGal, 00165 Document *ParentDoc = NULL, Library *ParentLib = NULL, BOOL IsForeground = TRUE); 00166 00167 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00168 Created: 16/4/97 (Based on Jason's Layer gallery code) 00169 00170 Inputs: ParentGal - points to the SuperGallery object which 'owns' this node 00171 ParentDoc - NULL, or a pointer to the document this group references 00172 ParentLib - NULL, or a pointer to the library this group references 00173 00174 Purpose: SGFrameGroup constructor. Initialises the Group's parent pointers to 00175 point at its parent(s). Note that generally speaking, one of ParentDoc, 00176 ParentLib will be NULL, and the other will be non-NULL. 00177 00178 Notes: This constructor does nothing - jusat passes the call on to the baseclass 00179 constructor of identical proportions. 00180 00181 SeeAlso: SGDisplayGroup::SGDisplayGroup 00182 00183 ***********************************************************************************************/ 00184 00185 SGFrameGroup::SGFrameGroup(SuperGallery *ParentGal, 00186 Document *ParentDoc, Library *ParentLib,BOOL IsForeground) 00187 : SGLayerGroup(ParentGal, ParentDoc, ParentLib, IsForeground) 00188 { 00189 Foreground = IsForeground; 00190 } 00191 00192 00193 00194 /*********************************************************************************************** 00195 00196 > virtual BOOL SGFrameGroup::HandleEvent(SGEventType EventType, void *EventInfo, 00197 SGMiscInfo *MiscInfo) 00198 00199 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00200 Created: 16/4/97 (Based on Jason's Layer gallery code) 00201 00202 Inputs: See SGDisplayNode::HandleEvent 00203 00204 Returns: TRUE if the event was handled successfully 00205 FALSE if it was not 00206 00207 Purpose: Handles a SuperGallery DisplayTree event 00208 00209 Notes: This overrides the SGDisplayNGroup::HandleEvent method, to give a group-type 00210 thing which does wierd stuff for layer galleries (i.e. does not fold, 00211 and gives column titles in the 'group' display) 00212 00213 SeeAlso: SGDisplayGroup::HandleEvent 00214 00215 ***********************************************************************************************/ 00216 00217 BOOL SGFrameGroup::HandleEvent(SGEventType EventType, void *EventInfo, 00218 SGMiscInfo *MiscInfo) 00219 { 00220 // And handle the specific event 00221 switch (EventType) 00222 { 00223 case SGEVENT_REDRAW: 00224 { 00225 DocRect MyRect(FormatRect); // Rely on cached format info being correct 00226 00227 SGRedrawInfo *RedrawInfo = GetRedrawInfo(EventType, EventInfo); 00228 00229 if (IMustRedraw(RedrawInfo)) 00230 { 00231 StartRendering(RedrawInfo, MiscInfo); 00232 00233 DocColour Col(192L, 192L, 192L); //128, 128, 128); 00234 00235 RedrawInfo->Renderer->SetLineWidth(0); 00236 RedrawInfo->Renderer->SetLineColour(RedrawInfo->Transparent); 00237 RedrawInfo->Renderer->SetFillColour(Col); 00238 RedrawInfo->Renderer->DrawRect(&MyRect); 00239 00240 ReadGroupTitle(); // (Re)Cache the title text 00241 00242 // Line up above indented items below 00243 MyRect.lo.x += IndentWidth + MiscInfo->PixelSize; 00244 00245 // Render column titles above the 'locked' and 'invisible' columns 00246 DocRect VisibleBtn; 00247 DocRect LockedBtn; 00248 DocRect SnapBtn; 00249 SGDisplayFrame::CalculateButtonRects(MiscInfo, &MyRect, 00250 &VisibleBtn, &LockedBtn, &SnapBtn); 00251 00252 DrawBitmap(RedrawInfo->Renderer, &VisibleBtn, _R(IDB_FGAL_SOLID)); 00253 DrawBitmap(RedrawInfo->Renderer, &LockedBtn, _R(IDB_FGAL_OVERLAY)); 00254 00255 // And finally, render the title text 00256 MyRect.lo.x += SG_GapBeforeText; // Leave a small gap before text 00257 if (MyRect.lo.x < MyRect.hi.x) // If still room left, draw title 00258 { 00259 RedrawInfo->Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &Col); 00260 00261 String_256 NewTitleText; 00262 00263 UINT32 IDS = _R(IDS_FRAMEGAL_FRAMES); 00264 00265 NewTitleText.MakeMsg(IDS, (TCHAR *)TitleText); 00266 RedrawInfo->Renderer->DrawFixedSystemText(&NewTitleText, MyRect); 00267 } 00268 00269 StopRendering(RedrawInfo, MiscInfo); 00270 } 00271 00272 // Check if the cliprect overlaps any of our children - if not, then we 00273 // can return now, passing the event on quickly without bothering to give 00274 // it to our children. 00275 if (GetChild() == NULL || 00276 !ChildArea.IsIntersectedWith(RedrawInfo->Bounds)) 00277 { 00278 return(FALSE); 00279 } 00280 } 00281 break; 00282 00283 00284 case SGEVENT_MOUSECLICK: 00285 // Mouse clicks on this group type are ignored - but we claim them so that the 00286 // event is not passed on around the tree unnecessarily. 00287 { 00288 SGMouseInfo *MouseInfo = GetMouseInfo(EventType, EventInfo); 00289 if (FormatRect.ContainsCoord(MouseInfo->Position)) 00290 return(TRUE); 00291 } 00292 break; 00293 00294 00295 default: 00296 // For all other purposes (formatting etc), let the base class handle the event 00297 return(SGDisplayGroup::HandleEvent(EventType, EventInfo, MiscInfo)); 00298 break; 00299 } 00300 00301 // Pass the event on to my children, as appropriate, and return the result 00302 return(GiveEventToMyChildren(EventType, EventInfo, MiscInfo)); 00303 } 00304 00305 00306 00307 00308 00309 00310 00311 00312 00313 // -- Static variables 00314 SGDisplayFrame *SGDisplayFrame::LastClickedLayer = NULL; 00315 00316 00317 /*********************************************************************************************** 00318 00319 > SGDisplayFrame::SGDisplayFrame() 00320 00321 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00322 Created: 16/4/97 (Based on Jason's Layer gallery code) 00323 00324 Purpose: SGDisplayFrame constructor 00325 DON'T call this constructor. It ERROR3's. Call the other constructor 00326 00327 ***********************************************************************************************/ 00328 00329 SGDisplayFrame::SGDisplayFrame() : SGDisplayLayer() 00330 { 00331 // Let the baseclass handle it 00332 } 00333 00334 00335 00336 /*********************************************************************************************** 00337 00338 > SGDisplayFrame::SGDisplayFrame(Layer *LayerToDisplay) 00339 00340 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00341 Created: 16/4/97 (Based on Jason's Layer gallery code) 00342 00343 Inputs: LayerToDisplay - The Layer this item will display 00344 00345 Purpose: SGDisplayFrame constructor 00346 00347 ***********************************************************************************************/ 00348 00349 SGDisplayFrame::SGDisplayFrame(Layer *LayerToDisplay) : SGDisplayLayer(LayerToDisplay) 00350 { 00351 // Let the baseclass handle it 00352 } 00353 00354 00355 00356 /*********************************************************************************************** 00357 00358 > SGDisplayFrame::~SGDisplayFrame() 00359 00360 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00361 Created: 16/4/97 (Based on Jason's Layer gallery code) 00362 00363 Purpose: SGDisplayFrame destructor 00364 00365 Notes: Ensures the LastClickedLayer memory is not left pointing at this layer 00366 00367 ***********************************************************************************************/ 00368 00369 SGDisplayFrame::~SGDisplayFrame() 00370 { 00371 // Make sure LastClickedLayer pointer is not left in an invalid state 00372 if (this == LastClickedLayer) 00373 LastClickedLayer = NULL; 00374 } 00375 00376 00377 00378 /*********************************************************************************************** 00379 00380 > virtual void SGDisplayFrame::HandleRedraw(SGRedrawInfo *RedrawInfo, 00381 SGFormatInfo *FormatInfo) 00382 00383 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00384 Created: 16/4/97 (Based on Jason's Layer gallery code) 00385 00386 Inputs: RedrawInfo - The information on the kernel-rendered redraw area 00387 FormatInfo - The formatting information structure 00388 00389 member variable FormatRect should be set up (before calling this method) 00390 to be the rectangle in which to draw this item 00391 00392 Purpose: SGDisplayFrame item redraw method - removed from the main HandleEvent 00393 method merely to make the code tidier. 00394 00395 Scope: private 00396 00397 ***********************************************************************************************/ 00398 00399 void SGDisplayFrame::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo) 00400 { 00401 StartRendering(RedrawInfo, MiscInfo); 00402 00403 DocRect MyRect(FormatRect); // Get my redraw position from the cached FormatRect 00404 00405 RenderRegion *Renderer = RedrawInfo->Renderer; 00406 00407 INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1); 00408 INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2); 00409 00410 Renderer->SetLineWidth(0); 00411 Renderer->SetLineColour(RedrawInfo->Transparent); 00412 Renderer->SetFillColour(DocColour(191L, 191L, 191L)); 00413 00414 // Calculate and redraw the buttons 00415 // NOTE: 00416 // The buttons are usually blank grey rectangles, or a rectangle with an eye/lock 00417 // glyph on them. However, to hint at what the buttons are for, the selected layer 00418 // also shows the buttons in a greyed state 00419 00420 DocRect VisibleBtn; 00421 DocRect LockedBtn; 00422 DocRect SnapBtn; 00423 00424 CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); 00425 00426 // Find out the state of the layer's flags 00427 BOOL ActiveAndVisEd = (GetDisplayedLayer()->IsActive() && Layer::ActiveLayerVisibleAndEditable); 00428 // BOOL Visible = GetDisplayedLayer()->IsVisible(); 00429 // BOOL Locked = GetDisplayedLayer()->IsLocked(); 00430 BOOL Guide = GetDisplayedLayer()->IsGuide(); 00431 BOOL Solid = GetDisplayedLayer()->IsSolid(); 00432 BOOL Overlay = GetDisplayedLayer()->IsOverlay(); 00433 BOOL Edited = GetDisplayedLayer()->IsEdited(); 00434 Document* pDoc = (Document*)GetDisplayedLayer()->FindOwnerDoc(); 00435 00436 ERROR3IF(pDoc == NULL,"Displayed layer doesn't have an owner doc"); 00437 if (pDoc == NULL) return; 00438 00439 // Draw 'Solid' button (The glyph is "on" when the layer is solid) 00440 if (Solid) 00441 { 00442 //if (!Guide && (ActiveAndVisEd || pDoc->IsAllVisible())) 00443 // DrawBitmap(Renderer, &VisibleBtn, _R(IDB_LGAL_TICKFORCED)); 00444 //else 00445 DrawBitmap(Renderer, &VisibleBtn, _R(IDB_LGAL_TICKON)); 00446 } 00447 else 00448 DrawBitmap(Renderer, &VisibleBtn, _R(IDB_LGAL_TICKOFF)); 00449 00450 // Draw 'Overlay' button (Glyph is on if the layer is overlayed) 00451 if (Overlay) 00452 { 00453 // If Solid is on then this is superfluous so render the greyed form 00454 if (Solid) 00455 DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKFORCED)); 00456 else 00457 DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKON)); 00458 } 00459 else 00460 { 00461 // If Solid is on then this is superfluous so render the greyed form 00462 if (Solid) 00463 DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKOFFFORCED)); 00464 else 00465 DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKOFF)); 00466 } 00467 00468 Layer* pLayer = GetDisplayedLayer(); 00469 ERROR3IF(pLayer == NULL, "I'm displaying a NULL layer? Serious screwup has occurred!"); 00470 if (pLayer == NULL) 00471 return; 00472 00473 DocColour Foreground = RedrawInfo->Foreground; 00474 DocColour Background = RedrawInfo->Background; 00475 DocColour SelForeground = RedrawInfo->SelForeground; 00476 DocColour SelBackground = RedrawInfo->SelBackground; 00477 00478 // Set up the colours for rendering our text, and fill the background if selected 00479 if (Flags.Selected) 00480 { 00481 // Fill the entire background with the 'selected' colour, so we don't 00482 // get gaps between bits of text or uneven rectangles in multiple selections 00483 Renderer->SetFillColour(SelBackground); 00484 Renderer->DrawRect(&MyRect); 00485 Renderer->SetFixedSystemTextColours(&SelForeground,&SelBackground); 00486 } 00487 else 00488 Renderer->SetFixedSystemTextColours(&Foreground, &Background); 00489 00490 MyRect.lo.x += SG_GapBeforeText; // Leave a small gap before text begins 00491 00492 // And render the text 00493 String_256 MyText = pLayer->GetLayerID(); 00494 00495 // Find the delay value and add it to the end of the layer/frame name 00496 BOOL IsHidden = pLayer->IsHiddenFrame(); 00497 if (!IsHidden) 00498 { 00499 UINT32 FrameDelay = pLayer->GetFrameDelay(); 00500 String_256 Delay; 00501 Delay.MakeMsg(_R(IDS_FRAMEDELAYFORMAT), FrameDelay); 00502 MyText += Delay; 00503 } 00504 else 00505 { 00506 String_256 HiddenText(_R(IDS_SHOWFRAMEISHIDDEN)); // (Hidden) 00507 MyText += HiddenText; 00508 } 00509 00510 #ifdef _DEBUG 00511 // If the layer is edited then add a star onto it 00512 if (pLayer->IsEdited()) 00513 MyText += " *"; // DEBUG only so ok 00514 #endif 00515 00516 Renderer->DrawFixedSystemText(&MyText, MyRect); 00517 00518 StopRendering(RedrawInfo, MiscInfo); 00519 } 00520 00521 00522 00523 /*********************************************************************************************** 00524 00525 > void SGDisplayFrame::ChangeRangeState(SGDisplayFrame *Start, SGDisplayFrame *End, 00526 BOOL Range, INT32 WhichButton, SGMiscInfo *MiscInfo) 00527 00528 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00529 Created: 16/4/97 (Based on Jason's Layer gallery code) 00530 00531 Inputs: Start - Points to the node, or start of a range of nodes, to set 00532 End - NULL or points to the end of the range 00533 Range - TRUE to do a whole range, FALSE to do only the Start node 00534 This is used to override the range description. 00535 WhichButton - 0 to change VISIBLE state 00536 1 to change LOCKED state 00537 2 to change SNAP state 00538 MiscInfo - The usual (see HandleEvent) 00539 00540 Purpose: To handle extension-clicks on layers, we set the state of a range of 00541 layers rather than just the one clicked. The range usually extends to the 00542 layer which was previously clicked. 00543 00544 Notes: This scans the sibling list containing Start, and sets the states of all 00545 layers it finds between start and end. If End is not found then Start is 00546 treated as a single item. 00547 00548 Scope: private 00549 00550 ***********************************************************************************************/ 00551 00552 void SGDisplayFrame::ChangeRangeState(SGDisplayFrame *Start, SGDisplayFrame *End, 00553 BOOL Range, INT32 WhichButton, SGMiscInfo *MiscInfo) 00554 { 00555 ERROR3IF(Start == NULL || MiscInfo == NULL, "Illegal NULL params"); 00556 00557 SuperGallery *ParentGallery = GetParentGallery(); 00558 ERROR3IF(ParentGallery == NULL, "No parent gallery?! Weird!"); 00559 00560 // Determine the new state based on inverting this item's state 00561 BOOL NewState = TRUE; 00562 switch (WhichButton) 00563 { 00564 case 0: // Solid state 00565 NewState = !(GetDisplayedLayer()->IsSolid()); 00566 break; 00567 00568 case 1: // Overlayed sate 00569 NewState = !(GetDisplayedLayer()->IsOverlay()); 00570 break; 00571 00572 default: 00573 ERROR3("Illegal WhichButton parameter to SGDisplayFrame::ChangeRangeState (must be 0..2)"); 00574 break; 00575 } 00576 00577 // Scan the sibling list to find the start and end nodes, and determine if end comes 00578 // before start (in which case we'll need to swap them over before continuing) 00579 SGDisplayFrame *Ptr = NULL; 00580 00581 if (!Range || End == NULL) 00582 End = Start; 00583 00584 BOOL FoundStart = FALSE; 00585 BOOL FoundEnd = FALSE; 00586 BOOL MustSwap = FALSE; 00587 00588 Ptr = (SGDisplayFrame *) (Start->GetParent()->GetChild()); 00589 while (Ptr != NULL) 00590 { 00591 if (Ptr == Start) 00592 FoundStart = TRUE; 00593 00594 if (Ptr == End) 00595 { 00596 FoundEnd = TRUE; 00597 MustSwap = !FoundStart; // If not found Start first, then the range is backwards 00598 } 00599 00600 Ptr = (SGDisplayFrame *) Ptr->GetNext(); 00601 } 00602 00603 if (!FoundStart) // Couldn't even find the start node! 00604 { 00605 ERROR3("Start node not found"); 00606 return; 00607 } 00608 00609 if (!FoundEnd) // No end node? Make the range one item only 00610 End = Start; 00611 00612 if (MustSwap) // Range is backwards - swap the pointers 00613 { 00614 Ptr = Start; 00615 Start = End; 00616 End = Ptr; 00617 } 00618 00619 00620 // Now scan the list from Start to End, setting all the layers (inclusive) 00621 Ptr = Start; 00622 00623 while (Ptr != NULL) 00624 { 00625 DocRect MyRect(Ptr->FormatRect); 00626 DocRect VisibleBtn; 00627 DocRect LockedBtn; 00628 DocRect SnapBtn; 00629 Ptr->CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); 00630 00631 switch (WhichButton) 00632 { 00633 case 0: // Visible state 00634 // Notify the gif animation property tabs dlg about this state change. 00635 // This allows us to sit on the ACTIVE_LAYER_CHANGED message. 00636 GIFAnimationPropertyTabs::SetChangeLayerState(TRUE); 00637 00638 // Ask the gallery to change the state of the flag 00639 Ptr->DoChangeState(LAYER_SOLID, NewState); 00640 // Do a redraw so we notice the change 00641 ParentGallery->ForceRedrawOfArea(&VisibleBtn); 00642 00643 // Set this flag back to false. 00644 GIFAnimationPropertyTabs::SetChangeLayerState(FALSE); 00645 break; 00646 00647 case 1: // Locked state 00648 // Notify the gif animation property tabs dlg about this state change. 00649 // This allows us to sit on the ACTIVE_LAYER_CHANGED message. 00650 GIFAnimationPropertyTabs::SetChangeLayerState(TRUE); 00651 00652 // Ask the gallery to change the state of the flag 00653 Ptr->DoChangeState(LAYER_OVERLAY, NewState); 00654 // Do a redraw so we notice the change 00655 ParentGallery->ForceRedrawOfArea(&LockedBtn); 00656 00657 // Set this flag back to false. 00658 GIFAnimationPropertyTabs::SetChangeLayerState(FALSE); 00659 break; 00660 } 00661 00662 if (Ptr == End) // Slight strangeness to handle (Start==End) case 00663 Ptr = NULL; // Have hit and processed End, so stop 00664 else 00665 Ptr = (SGDisplayFrame *) Ptr->GetNext(); // Have not, so go on to next layer 00666 } 00667 } 00668 00669 00670 00671 /*********************************************************************************************** 00672 00673 > virtual BOOL SGDisplayFrame::HandleEvent(SGEventType EventType, void *EventInfo, 00674 SGMiscInfo *MiscInfo) 00675 00676 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 00677 Created: 16/4/97 (Based on Jason's Layer gallery code) 00678 00679 Inputs: EventType - An enumerated value describing what type of event is to be processed 00680 00681 EventInfo - A structure describing the event (may be NULL). The exact thing 00682 pointed at by this pointer depends upon the event type: 00683 00684 MonoOn 00685 Event Thing EventInfo points at 00686 SGEVENT_FORMAT (SGFormatInfo *) 00687 SGEVENT_REDRAW (SGRedrawInfo *) 00688 SGEVENT_MOUSECLICK (SGMouseInfo *) 00689 MonoOff 00690 Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this 00691 information - they provide useful error/type checking, and hide the cast 00692 00693 MiscInfo - always provided. Contains a few useful bits of info that may be 00694 needed for all event types. 00695 00696 Outputs: FormatInfo is updated as appropriate 00697 00698 Returns: TRUE if the event was handled successfully 00699 FALSE if it was not 00700 00701 Purpose: Handles a SuperGallery DisplayTree event 00702 00703 Notes: This overrides the pure virtual SGDisplayNode::HandleEvent method 00704 00705 A node need not handle a specific event - if it does not handle it, it 00706 should return FALSE. 00707 00708 Redraw and Formatting handlers should never return TRUE, as this will 00709 prevent the event from continuing through the tree. 00710 00711 Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order 00712 to pass the event dow the tree. THIS node is a leaf-node, so it doesn't. 00713 00714 SeeAlso: SGDisplayNode::HandleEvent 00715 00716 ***********************************************************************************************/ 00717 00718 BOOL SGDisplayFrame::HandleEvent(SGEventType EventType, void *EventInfo, 00719 SGMiscInfo *MiscInfo) 00720 { 00721 switch (EventType) 00722 { 00723 case SGEVENT_FORMAT: 00724 { 00725 SGFormatInfo *FormatInfo = GetFormatInfo(EventType, EventInfo); 00726 CalculateMyRect(FormatInfo, MiscInfo); // Cache our FormatRect for later use 00727 } 00728 break; 00729 00730 00731 case SGEVENT_REDRAW: 00732 { 00733 DocRect MyRect(FormatRect); // Rely on FormatRect being cached from above 00734 SGRedrawInfo *RedrawInfo = GetRedrawInfo(EventType, EventInfo); 00735 00736 if (IMustRedraw(RedrawInfo)) // only redraw if we intersect the clip rect 00737 HandleRedraw(RedrawInfo, MiscInfo); 00738 } 00739 break; // exit and return FALSE to pass the redraw event on 00740 00741 00742 case SGEVENT_MOUSECLICK: 00743 { 00744 SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo); 00745 00746 SuperGallery *ParentGallery = GetParentGallery(); 00747 ERROR3IF(ParentGallery == NULL, "No parent gallery?! Weird!"); 00748 00749 if (FormatRect.ContainsCoord(Mouse->Position)) 00750 { 00751 DocRect MyRect(FormatRect); 00752 DocRect VisibleBtn; 00753 DocRect LockedBtn; 00754 DocRect SnapBtn; 00755 Document* pDoc = (Document*)GetDisplayedLayer()->FindOwnerDoc(); 00756 ERROR2IF(pDoc == NULL,TRUE,"Can't find owner doc for layer"); 00757 ERROR2IF(!IS_A(pDoc,Document),TRUE,"Owner doc is not a Document"); 00758 00759 Layer* pLayer = GetDisplayedLayer(); 00760 ERROR2IF(pLayer == NULL,TRUE,"GetDisplayedLayer() returned NULL"); 00761 00762 // Find out the state of the layer's flags 00763 BOOL ActiveAndVisEd = (pLayer->IsActive() && Layer::ActiveLayerVisibleAndEditable); 00764 //BOOL Visible = pLayer->GetVisibleFlagState(); 00765 //BOOL Locked = pLayer->GetLockedFlagState(); 00766 BOOL Guide = pLayer->IsGuide(); 00767 BOOL Solid = pLayer->IsSolid(); 00768 //BOOL Guide = pLayer->IsOverlay(); 00769 00770 CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); 00771 00772 // Ignore menu clicks on the Visible button 00773 if (!Mouse->MenuClick && VisibleBtn.ContainsCoord(Mouse->Position)) 00774 { 00775 // At present always change the actual setting of the Solid flag 00776 if (TRUE) //Guide || (!pDoc->IsAllVisible() && !ActiveAndVisEd)) 00777 { 00778 ChangeRangeState(this, LastClickedLayer, Mouse->Extend, 0, MiscInfo); 00779 // Remember this as the "anchor" layer for extend-click setting of ranges 00780 LastClickedLayer = this; 00781 00782 // We need to force a redraw of the overlay button as it is dependent 00783 // on the locked state 00784 ParentGallery->ForceRedrawOfArea(&LockedBtn); 00785 } 00786 else 00787 { 00788 UINT32 IDS = _R(IDS_LAYER_NOCHANGE_VISIBLE); 00789 00790 if (ActiveAndVisEd) 00791 IDS = _R(IDS_LAYER_NOCHANGE_VISIBLE_ACTIVE); 00792 00793 String_256 msg(IDS); 00794 GetApplication()->UpdateStatusBarText(&msg); 00795 Beep(); 00796 } 00797 00798 break; 00799 } 00800 00801 // Ignore menu clicks on the Locked button 00802 if (!Mouse->MenuClick && LockedBtn.ContainsCoord(Mouse->Position)) 00803 { 00804 // Only change the actual setting if the Multilayer flag is clear 00805 // and it's not the active layer with the 'active layer is visible and edtable' pref on 00806 if (!Solid) 00807 { 00808 ChangeRangeState(this, LastClickedLayer, Mouse->Extend, 1, MiscInfo); 00809 // Remember this as the "anchor" layer for extend-click setting of ranges 00810 LastClickedLayer = this; 00811 } 00812 else 00813 { 00814 UINT32 IDS = _R(IDS_LAYER_NOCHANGE_OVERLAY); 00815 00816 String_256 msg(IDS); 00817 GetApplication()->UpdateStatusBarText(&msg); 00818 Beep(); 00819 } 00820 00821 break; 00822 } 00823 00824 // Only treat clicks as selection clicks if they are to the right of the tick buttons 00825 // This is easy, as MyRect excludes the buttons 00826 if (MyRect.ContainsCoord(Mouse->Position)) 00827 { 00828 // In the layer gallery the selection can never be more than one item, 00829 // so all clicks are treated like Select clicks. 00830 if (!Flags.Selected) 00831 { 00832 // Make the layer we're displaying the active one 00833 Layer* pLayer = GetDisplayedLayer(); 00834 FrameSGallery::MakeActiveLayer(pLayer); 00835 00836 // Now update the selection states... 00837 ParentGallery->SelectItems(FALSE); // Deselect everything else 00838 00839 // Repaint the list box now. This is because if there is a large 00840 // distance between the old selection and the new one, we get a huge 00841 // redraw cliprect, so get a (slow) complete redraw, instead of two 00842 // small redraws. It is thus better to break the redraw into 2 steps 00843 // so that we are more likely to get 2 fast redraws than one slow one. 00844 //ParentGallery->PaintGadgetNow(_R(IDC_GALLERY_LISTBOX)); 00845 ParentGallery->PaintListNow(); 00846 00847 // And select myself, and the new active layer 00848 SetSelected(TRUE); 00849 00850 // My selection state has changed, so I'd better redraw myself 00851 ForceRedrawOfMyself(); 00852 00853 // And inform the parent gallery that the selection has changed, so 00854 // it can shade/unshade buttons as appropriate, etc 00855 ParentGallery->SelectionHasChanged(); 00856 } 00857 00858 // Remember this as the "anchor" layer for extend-click setting of ranges 00859 LastClickedLayer = this; 00860 00861 // Start a drag on the layer item 00862 SGListDragInfo* pDragInfo = new SGListDragInfo(ParentGallery,this,Mouse,Mouse->MenuClick); 00863 00864 if (pDragInfo != NULL) 00865 DragManagerOp::StartDrag(pDragInfo, GetListWindow()); 00866 } 00867 00868 return(TRUE); // Claim this event - nobody else can own this click 00869 } 00870 } 00871 break; 00872 00873 00874 default: 00875 // Let the base class handle all unknown/unwanted events 00876 return(SGDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo)); 00877 } 00878 00879 // Default return value: We do not claim this event, so it will be passed on to others 00880 return(FALSE); 00881 } 00882 00883 00884 00885 /*********************************************************************************************** 00886 00887 > void SGDisplayFrame::DoChangeState(OpLayerGalReason Reason,BOOL NewState) 00888 00889 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 00890 Created: 16/4/97 (Based on Jason's Layer gallery code) 00891 Inputs: Reason = reason code definiting what 'NewState' represents 00892 NewState= boolean that determines the new state of the flag defined by 'Reason' 00893 00894 Returns: - 00895 Purpose: Called when a flag changes for a layer gallery item 00896 00897 Notes: Does not redraw the layer in the display list 00898 00899 ***********************************************************************************************/ 00900 00901 void SGDisplayFrame::DoChangeState(OpLayerGalReason Reason,BOOL NewState) 00902 { 00903 FrameSGallery* pGal = (FrameSGallery*)GetParentGallery(); 00904 ERROR3IF(!IS_A(pGal,FrameSGallery),"Parent not a frame gallery"); 00905 if (!IS_A(pGal,FrameSGallery)) return; 00906 00907 Layer* pLayer = GetDisplayedLayer(); 00908 pGal->DoChangeLayerState(pLayer,Reason,NewState); 00909 } 00910 00911 /*********************************************************************************************** 00912 00913 > virtual void SGDisplayFrame::MoveLayer(SGDisplayNode *NodeToMove,BOOL Before,BOOL ToggleBackground) 00914 00915 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 00916 Created: 16/4/97 (Based on Jason's Layer gallery code) 00917 00918 Inputs: NodeToMove = the node to move (which specifies the layer to move) 00919 Before = if TRUE the layer is moved previous (before) this layer, otherwise 00920 the layer is moved next (after) this layer 00921 ToggleBacground = TRUE if the background flag should be toggled when moved 00922 00923 Purpose: This moves the given layer either before or after this layer, in an undoable way 00924 00925 Errors: ERROR3 and quiet exit if NodeToMove == NULL 00926 00927 SeeAlso: SuperGallery; SGDisplayNode::MoveAfter; SGDisplayNode::InsertAfter; SGDisplayNode::AddItem 00928 00929 Note: Same as LayerSGallery version but uses FRAME_MOVE 00930 00931 ***********************************************************************************************/ 00932 00933 void SGDisplayFrame::MoveLayer(SGDisplayNode *NodeToMove,BOOL Before,BOOL ToggleBackground) 00934 { 00935 ERROR3IF(!IS_A(NodeToMove,SGDisplayFrame),"The node to move is not a SGDisplayFrame"); 00936 if(!IS_A(NodeToMove,SGDisplayFrame)) 00937 return; 00938 00939 Layer* pLayerToMove = ((SGDisplayFrame*)NodeToMove)->GetDisplayedLayer(); 00940 Layer* pThisLayer = GetDisplayedLayer(); 00941 00942 Spread* pSpread = pLayerToMove->FindParentSpread(); 00943 ERROR3IF(pSpread == NULL,"Parent spread is NULL"); 00944 if (pSpread == NULL) 00945 return; 00946 00947 OpLayerGalReason Reason; 00948 00949 if (pLayerToMove == pThisLayer) 00950 { 00951 // if the context node and the layer to move are the same, and we don't have to toggle 00952 // the background flag, just return (give errors in debug mode) 00953 ERROR3IF(!ToggleBackground,"Not moving the layer OR toggling the background flag, so why did you call?"); 00954 if (!ToggleBackground) 00955 return; 00956 00957 Reason = LAYER_TOGGLEBACKGROUND; 00958 } 00959 else 00960 Reason = FRAME_MOVE; 00961 00962 00963 OpLayerGalParam Param(Reason,pSpread); 00964 00965 Param.pLayer = pLayerToMove; 00966 Param.pContextNode = pThisLayer; 00967 Param.MoveRedraw = TRUE; 00968 Param.ToggleBackground = ToggleBackground; 00969 Param.pLayerSGal = (FrameSGallery*)GetParentGallery(); 00970 00971 if (Before) 00972 Param.AttDir = NEXT; // next means insert-before-this 00973 else 00974 Param.AttDir = PREV; // prev means insert-after-this 00975 00976 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_LAYERGALCHANGE); 00977 if (pOpDesc != NULL) 00978 pOpDesc->Invoke((OpParam*)&Param); 00979 else 00980 { 00981 ERROR3("Couldn't find OPTOKEN_LAYERGALCHANGE op descriptor"); 00982 } 00983 } 00984 00985 #endif // EXCLUDE_GALS 00986 00987 00988 00989 /******************************************************************************************** 00991 ********************************************************************************************/ 00992 00993 00994 00995 00996 /******************************************************************************************** 00997 00998 > FrameSGallery::FrameSGallery() 00999 01000 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 01001 Created: 16/4/97 (Based on Jason's Layer gallery code) 01002 Purpose: FrameSGallery default constructor 01003 01004 ********************************************************************************************/ 01005 01006 FrameSGallery::FrameSGallery() 01007 { 01008 #ifndef EXCLUDE_GALS 01009 pSpread = NULL; 01010 pDoc = NULL; 01011 DisplayForeground = NULL; // Group of foreground layers 01012 DisplayBackground = NULL; // Group of background layers 01013 01014 OldGuideLayerState = -1; 01015 NewGuideLayerState = -1; 01016 m_NewDocBorn = FALSE; 01017 #endif 01018 } 01019 01020 01021 01022 /******************************************************************************************** 01023 01024 > FrameSGallery::~FrameSGallery() 01025 01026 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 01027 Created: 16/4/97 (Based on Jason's Layer gallery code) 01028 Purpose: FrameSGallery destructor. 01029 01030 ********************************************************************************************/ 01031 01032 FrameSGallery::~FrameSGallery() 01033 { 01034 } 01035 01036 #ifndef EXCLUDE_GALS 01037 01038 /******************************************************************************************** 01039 01040 > void FrameSGallery::CreateNewSubtree(Document *ParentDoc, SGDisplayGroup *ExistingGroup) 01041 01042 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 01043 Created: 16/4/97 (Based on Jason's Layer gallery code) 01044 01045 Inputs: ParentDoc - The document to create a display subtree for 01046 ExistingGroup - NULL (creates a new group for this document), or 01047 a pointer to the existing group-node for this document (in which case 01048 it clears all displayitems from the group and rebuilds it in place - this 01049 stops the display group moving around the tree at random!) 01050 01051 Purpose: Internal call. This takes the Layer list of the given document and 01052 creates a DisplayTree subtree from it. This subtree is then added to 01053 the DisplayTree. Note that this does not force a redraw of the list - 01054 after making this call, you should also call ForceRedrawOfList 01055 01056 Notes: Passing in a NULL parent document pointer results in an ERROR3 - 01057 the function returns without doing anything in retail builds 01058 01059 SeeAlso: SuperGallery::ForceRedrawOfList 01060 01061 ********************************************************************************************/ 01062 01063 void FrameSGallery::CreateNewSubtree(Document *ParentDoc, SGDisplayGroup *ExistingGroup) 01064 { 01065 if (DisplayTree == NULL) 01066 return; 01067 01068 TRACEUSER( "Neville", _T("FrameSGallery::CreateNewSubtree Just about to DestroySubtree\n")); 01069 // The layer gallery only ever shows one document, so destroy the entire tree 01070 // and start again from scratch (note that this doesn't destroy the root node) 01071 DisplayTree->DestroySubtree(); 01072 01073 // All groups will be destroyed by DestroySubtree(), so we'd better forget them 01074 DisplayForeground = NULL; 01075 01076 TRACEUSER( "Neville", _T("FrameSGallery::CreateNewSubtree completed DestroySubtree\n")); 01077 01078 if (ParentDoc == NULL) 01079 return; 01080 01081 SGDisplayFrame *DisplayLayer = NULL; 01082 01083 EnsureActiveLayerIntegrity(); 01084 01085 // Create the foreground layer group 01086 DisplayForeground = new SGFrameGroup(this, ParentDoc,NULL,TRUE); // Create new Group 01087 if (DisplayForeground == NULL) // Total failure - abort 01088 return; 01089 DisplayTree->AddItem(DisplayForeground); // Add new group to tree 01090 01091 Spread* pSelSpread = GetSelectedSpread(); 01092 ERROR3IF(pSelSpread == NULL,"No selected spread in FrameSGallery"); 01093 if (pSelSpread == NULL) return; 01094 01095 Layer* pLayer = pSelSpread->FindLastLayer(); 01096 Layer* pActiveLayer = NULL; 01097 Layer* pGuideLayer = NULL; 01098 BOOL SetActiveLayer = FALSE; 01099 // Only Webster needs to show a dummy frame layer 01100 #ifdef WEBSTER 01101 Layer* pSingleNonFrameLayer = NULL; 01102 BOOL ShownSingleNonFrameLayer = FALSE; 01103 #endif // WEBSTER 01104 01105 while (pLayer != NULL) 01106 { 01107 // If we find a guide layer then note that for future use 01108 if (pLayer->IsGuide()) 01109 { 01110 pGuideLayer = pLayer; 01111 } 01112 else if ( 01113 (pLayer->IsPseudoFrame() && pLayer->IsFrame()) // its a proper frame layer 01114 #ifdef WEBSTER 01115 || (pLayer->IsPseudoFrame() && !ShownSingleNonFrameLayer) // its a potential frame layer 01116 #endif // WEBSTER 01117 ) 01118 { 01119 #ifdef WEBSTER 01120 // If its not a frame layer then note that we have added our single 01121 // non-frame layer in. 01122 if (!pLayer->IsFrame()) 01123 { 01124 ShownSingleNonFrameLayer = TRUE; 01125 pSingleNonFrameLayer = pLayer; 01126 } 01127 #endif // WEBSTER 01128 01129 // Only add foreground layers and non-guide layers 01130 DisplayLayer = new SGDisplayFrame(pLayer); 01131 01132 if (DisplayLayer != NULL) 01133 { 01134 // Always add to the foreground layers 01135 DisplayForeground->AddItem(DisplayLayer); 01136 01137 if (pLayer->IsActive()) 01138 { 01139 ERROR3IF(pActiveLayer != NULL,"Found more than one active layer in the selected spread"); 01140 pActiveLayer = pLayer; 01141 01142 DisplayLayer->SetSelected(TRUE); // Make the active layer selected 01143 SetActiveLayer = TRUE; // Note this fact 01144 } 01145 } 01146 } 01147 01148 pLayer = pLayer->FindPrevLayer(); 01149 } 01150 01151 // If we have not set a selected layer then this is very bad 01152 if (!SetActiveLayer) 01153 { 01154 TRACEUSER( "Neville", _T("Active layer is not a frame layer so force it!\n")); 01155 Layer * pNewActiveLayer = pSpread->FindLastFrameLayer(); 01156 #ifdef WEBSTER 01157 if (pNewActiveLayer == NULL && pSingleNonFrameLayer != NULL) 01158 pNewActiveLayer = pSingleNonFrameLayer; 01159 #else 01160 // ERROR3IF(pNewActiveLayer == NULL,"No current active frame layer"); 01161 #endif // WEBSTER 01162 01163 // If we have an active layer, ensure that it really is the one and only active layer 01164 if (pNewActiveLayer != NULL) 01165 { 01166 // Search for the new display item to match this new active layer 01167 SGDisplayLayer *pWantedDispLayer = NULL; 01168 SGDisplayLayer *pDispLayer = ((SGDisplayLayer *) DisplayForeground->GetChild()); 01169 while (pDispLayer != NULL) 01170 { 01171 if (pDispLayer->GetDisplayedLayer() == pNewActiveLayer) 01172 pWantedDispLayer = pDispLayer; 01173 pDispLayer = ((SGDisplayLayer *)pDispLayer->GetNext()); 01174 } 01175 01176 // If we found the required display item then go and select it 01177 if (pWantedDispLayer) 01178 { 01179 // Now update the selection states... 01180 SelectItems(FALSE); // Deselect everything else 01181 // Something has changed so we must go and select this new item 01182 pWantedDispLayer->SetSelected(TRUE); 01183 } 01184 01185 // As this can only happen when we have a frame layer which is not active 01186 // e.g. import a non-frame xar/web document into a non-frame document 01187 // we must use the layer form of MakeActiveLayer so that the visibility of 01188 // layers is not affected. 01189 LayerSGallery::MakeActiveLayer(pNewActiveLayer); 01190 //FrameSGallery::MakeActiveLayer(pNewActiveLayer); 01191 } 01192 } 01193 01194 // The new state of the Guide Layer is now the old state 01195 OldGuideLayerState = NewGuideLayerState; 01196 01197 if (pGuideLayer == NULL) 01198 NewGuideLayerState = -1; // If there's no guide layer, set new state to be -1 01199 else 01200 NewGuideLayerState = pGuideLayer->IsVisible(); // New state is based on the guide layer's visibility 01201 01202 if (IsVisible()) 01203 { 01204 SetBoolGadgetSelected(_R(IDC_BTN_MULTILAYER),!(ParentDoc->IsMultilayer() == 0)); 01205 SetBoolGadgetSelected(_R(IDC_BTN_ALLVISIBLE),!(ParentDoc->IsAllVisible() == 0)); 01206 } 01207 01208 TRACEUSER( "Neville", _T("FrameSGallery::CreateNewSubtree exit\n")); 01209 } 01210 01211 01212 /******************************************************************************************** 01213 01214 > BOOL FrameSGallery::PostCreate(void) 01215 01216 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 01217 Created: 16/4/97 (Based on Jason's Layer gallery code) 01218 01219 Returns: TRUE if the Gallery initialised successfully 01220 FALSE if it should not be opened due to a failure to initialise 01221 01222 Purpose: The FrameSGallery PostCreate handler. This overrides the base class 01223 PostCreate function. It is called at the very end of the 01224 SuperGallery::Create method, after the window has been created and opened. 01225 01226 ********************************************************************************************/ 01227 01228 BOOL FrameSGallery::PostCreate(void) 01229 { 01230 Document *ParentDoc = Document::GetSelected(); 01231 if (ParentDoc != NULL) 01232 { 01233 SetBoolGadgetSelected(_R(IDC_BTN_MULTILAYER),!(ParentDoc->IsMultilayer() == 0)); 01234 SetBoolGadgetSelected(_R(IDC_BTN_ALLVISIBLE),!(ParentDoc->IsAllVisible() == 0)); 01235 } 01236 01237 EnableGadget(_R(IDC_GALLERY_COPY),ParentDoc != NULL && !IsSelectedItemGuideLayer()); 01238 01239 UpdateFrameRelatedButtons(); 01240 01241 return(TRUE); 01242 } 01243 01244 01245 01246 /******************************************************************************************** 01247 01248 > virtual BOOL FrameSGallery::ApplyAction(SGActionType Action) 01249 01250 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 01251 Created: 16/4/97 (Based on Jason's Layer gallery code) 01252 01253 Inputs: Action - Indicates what action to apply 01254 01255 Returns: TRUE to indicate successful handling of the action, or 01256 FALSE to indicate failure 01257 01258 Purpose: Applies certain conventional gallery actions (usually associated with 01259 gallery buttons, for new, edit, delete, etc) 01260 01261 SeeAlso: SGActionType 01262 01263 ********************************************************************************************/ 01264 01265 BOOL FrameSGallery::ApplyAction(SGActionType Action) 01266 { 01267 // No display tree? Better forget about it then! 01268 if (DisplayTree == NULL) 01269 return(FALSE); 01270 01271 // Determine useful info - this is usually needed for most actions, so always get it 01272 Document *SelectedDoc = Document::GetSelected(); 01273 SGDisplayGroup *DocumentGroup = DisplayTree->FindSubtree(this, SelectedDoc, NULL); 01274 SGDisplayFrame *FirstSelected = NULL; 01275 01276 if (DocumentGroup != NULL) 01277 FirstSelected = (SGDisplayFrame *) DocumentGroup->FindNextSelectedItem(NULL); 01278 01279 // Now, process the action TO DO! - see Colour gallery for examples 01280 switch(Action) 01281 { 01282 case SGACTION_CREATE: 01283 DoCreateNewItem(); 01284 break; 01285 01286 case SGACTION_EDIT: 01287 DoChangeName(); 01288 break; 01289 01290 case SGACTION_DELETE: 01291 //if (PrepareToDelete()) // No warning on Frame gallery 01292 DoDeleteSelection(); 01293 break; 01294 01295 // case SGACTION_APPLY: 01296 // case SGACTION_REDEFINE: 01297 // case SGACTION_DISPLAYMODECHANGED: 01298 // These operations are not provided by the layer gallery 01299 // break; 01300 01301 default: 01302 return(SuperGallery::ApplyAction(Action)); 01303 } 01304 01305 return(TRUE); 01306 } 01307 01308 01309 01310 /******************************************************************************************** 01311 01312 > virtual MsgResult FrameSGallery::Message(Msg* Message) 01313 01314 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 01315 Created: 16/4/97 (Based on Jason's Layer gallery code) 01316 Inputs: Message - The message to handle 01317 01318 Purpose: A standard message handler, really. 01319 01320 Notes: Any messages that this does not handle must be passed down to the 01321 SuperGallery base class message handler. 01322 01323 NOTE WELL that the SuperGallery base class handler does some funky things 01324 for us - see SuperGallery::Message - such as deleting our display subtree 01325 for any document which dies (which, uncannily, would explain why they go 01326 away like that when you close documents ;-), and shading the gallery when 01327 there are no documents present. [To override this behaviour in these cases, 01328 you should respond to the message, and return OK rather than calling the 01329 base class message handler] 01330 01331 SeeAlso: SuperGallery::Message 01332 01333 ********************************************************************************************/ 01334 01335 MsgResult FrameSGallery::Message(Msg* Message) 01336 { 01337 if (IS_OUR_DIALOG_MSG(Message)) 01338 { 01339 DialogMsg* Msg = (DialogMsg*)Message; 01340 01341 switch (Msg->DlgMsg) 01342 { 01343 case DIM_CREATE: 01344 SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFRAMEGALLERY, TRUE); 01345 break; 01346 01347 case DIM_CANCEL: 01348 SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFRAMEGALLERY, FALSE); 01349 break; 01350 } 01351 } 01352 01353 // If we have no displaytree, then we have not been shown, or something terrible has 01354 // happened, so we don't bother handling any of these messages. 01355 if (DisplayTree == NULL) 01356 return(SuperGallery::Message(Message)); 01357 01358 01359 if (IS_OUR_DIALOG_MSG(Message)) 01360 { 01361 DialogMsg* Msg = (DialogMsg*)Message; 01362 INT32 state; 01363 01364 switch (Msg->DlgMsg) 01365 { 01366 case DIM_LFT_BN_CLICKED: 01367 //TRACE( _T("Gadget %d clicked\n"),Msg->GadgetID); 01368 switch(Msg->GadgetID) 01369 { 01370 case _R(IDC_BTN_MULTILAYER): 01371 state = GetLongGadgetValue(_R(IDC_BTN_MULTILAYER),0,1); 01372 DoChangeLayerState(NULL,FRAME_MULTILAYER,state); 01373 break; 01374 01375 case _R(IDC_BTN_ALLVISIBLE): 01376 state = GetLongGadgetValue(_R(IDC_BTN_ALLVISIBLE),0,1); 01377 DoChangeLayerState(NULL,FRAME_ALLVISIBLE,state); 01378 break; 01379 01380 case _R(IDC_GALLERY_UPONE): 01381 DoMoveLayer(MOVELAYER_UPONE); 01382 break; 01383 01384 case _R(IDC_GALLERY_DOWNONE): 01385 DoMoveLayer(MOVELAYER_DOWNONE); 01386 break; 01387 01388 case _R(IDC_GALLERY_NEW_NODLG): 01389 DoCreateNewItem(); 01390 break; 01391 01392 case _R(IDC_GALLERY_COPY_NODLG): 01393 DoCopyLayer(); 01394 break; 01395 01396 case _R(IDC_GALLERY_HELP): // Show help page 01397 HelpUserTopic(_R(IDS_HELPPATH_Gallery_Frame)); 01398 break; 01399 01400 01401 /* case _R(IDC_GALLERY_PROPERTIES): 01402 // Handled by optoken 01403 DoFrameProperties(); 01404 break; */ 01405 01406 /* case _R(IDC_BMPGAL_SAVE): 01407 // Handled by optoken 01408 DoSaveAnimation(); 01409 break; */ 01410 01411 /* case _R(IDC_BMPGAL_PREVIEW): 01412 // Handled by optoken 01413 DoPreviewAnimation(); 01414 break; */ 01415 01416 /* case _R(IDC_FRAME_ANIMATION): 01417 // Handled by optoken 01418 // Implement **** 01419 break; */ 01420 } 01421 break; 01422 } 01423 } 01424 else if (MESSAGE_IS_A(Message, OpMsg)) 01425 { 01426 switch (((OpMsg*)Message)->MsgType) 01427 { 01428 case OpMsg::AFTER_UNDO: 01429 case OpMsg::AFTER_REDO: 01430 EnsureSelSpreadSelectionIntegrity(); 01431 break; 01432 } 01433 } 01434 else if (MESSAGE_IS_A(Message, SpreadMsg)) 01435 { 01436 SpreadMsg* pSpreadMsg = (SpreadMsg*) Message; 01437 01438 switch (pSpreadMsg->Reason) 01439 { 01440 case SpreadMsg::SELCHANGED: 01441 NewSelectedSpread(pSpreadMsg->pNewSpread); // gets selected doc too 01442 if (pDoc != NULL && IsVisible()) 01443 { 01444 TRACEUSER( "Neville", _T("frame SpreadMsg::SELCHANGED CreateNewSubtree\n")); 01445 CreateNewSubtree(pDoc); 01446 ForceRedrawOfList(); 01447 } 01448 break; 01449 01450 01451 case SpreadMsg::LAYERCHANGES: 01452 if (IsVisible()) 01453 { 01454 if (pSpreadMsg->pNewSpread == pSpread) 01455 { 01456 if (pSpread->FindFirstLayer() != NULL) 01457 { 01458 EnsureActiveLayerIntegrity(); 01459 if (pDoc != NULL && IsVisible()) 01460 { 01461 TRACEUSER( "Neville", _T("frame SpreadMsg::LAYERCHANGES CreateNewSubtree\n")); 01462 CreateNewSubtree(pDoc); 01463 ForceRedrawOfList(); 01464 } 01465 } 01466 } 01467 } 01468 else 01469 { 01470 if (pSpreadMsg->pNewSpread->FindFirstLayer() != NULL) 01471 { 01472 pSpread = pSpreadMsg->pNewSpread; 01473 EnsureActiveLayerIntegrity(); 01474 } 01475 } 01476 break; 01477 } 01478 } 01479 else if (MESSAGE_IS_A(Message, DocChangingMsg)) 01480 { 01481 DocChangingMsg *Msg = (DocChangingMsg *) Message; 01482 switch (Msg->State) 01483 { 01484 case DocChangingMsg::DocState::TITLECHANGED: 01485 { 01486 // Showstopper removed, Jason, 28/3/96 01487 // When the doc title changes, we simply need to redraw to update the group titles. 01488 // Calling CreateNewSubtree will destroy the existing tree - this is really really bad 01489 // when the document title changed as a result of us (e.g.) locking a layer, because the 01490 // message broadcats hits us while we're still in the middle of traversing the tree, 01491 // we then delete the tree out from under ourselves, and are then in a highly dodgy state! 01492 // CreateNewSubtree(Msg->pChangingDoc); 01493 ForceRedrawOfList(); 01494 break; 01495 } 01496 01497 // This message is sent when a new or just opened document is stable. 01498 case DocChangingMsg::DocState::SELCHANGED: 01499 { 01500 if (Msg->pNewDoc == NULL) 01501 { 01502 // No documents around any more, so we must wipe the display tree 01503 // The base class will shade the gallery for us. 01504 TRACEUSER( "Neville", _T("frame DocChangingMsg CreateNewSubtree\n")); 01505 CreateNewSubtree(NULL); 01506 ForceRedrawOfList(); 01507 } 01508 else 01509 { 01510 #ifdef WEBSTER 01511 // There is an active document, so ensure the gallery is unshaded 01512 ShadeGallery(FALSE); 01513 #else 01514 //Do not process the message if it has been sent due to the creation of a new document. 01515 if (!GetNewDocBorn()) 01516 { 01517 // The document has changed, do we detect any non-frame layers? 01518 BOOL FrameMode = FALSE; 01519 01520 // Get a ptr to the document. 01521 Document* pDoc = Msg->pNewDoc; 01522 01523 // Ensure a valid ptr. 01524 if(pDoc) 01525 { 01526 // Determine the document mode. 01527 FrameMode = IsFrameMode(pDoc); 01528 01529 // If we are no longer in Frame mode and the frame gallery is open, 01530 // then close the frame gallery and open the layer gallery. 01531 if( !FrameMode && IsVisible() ) 01532 { 01533 // Close the frame gallery. 01534 if(CloseFrameGallery()) 01535 { 01536 // Open the the layer gallery. 01537 OpenLayerGallery(); 01538 } 01539 } 01540 } 01541 } 01542 01543 // If the gallery is visible, then ensure the gallery is unshaded. 01544 if(IsVisible()) 01545 { 01546 // There is an active document, so ensure the gallery is unshaded 01547 ShadeGallery(FALSE); 01548 } 01549 01550 #endif 01551 } 01552 break; 01553 } 01554 #ifndef WEBSTER 01555 case DocChangingMsg::DocState::BORN: 01556 { 01557 // When a new document is created, a SELCHANGED 01558 // message is broadcasted, for Camelot2 frame/layer integration 01559 // we do not wish to process the message. 01560 // We therefore set this flag to notify us when a new document 01561 // is born. 01562 01563 // Ensure the frame gallery is open. 01564 if( IsVisible() ) 01565 { 01566 // Set the flag to true. 01567 // This is set to false in BORNANDSTABLE. 01568 SetNewDocBorn(TRUE); 01569 } 01570 break; 01571 } 01572 01573 case DocChangingMsg::DocState::BORNANDSTABLE: 01574 { 01575 // The document has changed, do we detect any non-frame layers? 01576 BOOL FrameMode = FALSE; 01577 BOOL GalleryClosed = FALSE; 01578 01579 // Get a ptr to the document. 01580 Document* pChangingDoc = Msg->pChangingDoc; 01581 01582 // Ensure a valid ptr. 01583 if(pChangingDoc) 01584 { 01585 // Determine the document mode. 01586 FrameMode = IsFrameMode(pChangingDoc); 01587 01588 // If we are no longer in Frame mode then 01589 // close the frame gallery and open the layer gallery. 01590 if( !FrameMode && IsVisible() ) 01591 { 01592 // Close the frame gallery. 01593 if(CloseFrameGallery()) 01594 { 01595 // Open the Layer gallery. 01596 OpenLayerGallery(); 01597 01598 // Now we have processed this message, it is safe to process SELCHANGED messages. 01599 SetNewDocBorn(FALSE); 01600 } 01601 } 01602 } 01603 break; 01604 } 01605 01606 case DocChangingMsg::DocState::KILLED: 01607 case DocChangingMsg::DocState::ABOUTTODIE: 01608 { 01609 // The doc. is about to die, therefore, set this falg to false. 01610 SetNewDocBorn(FALSE); 01611 break; 01612 } 01613 #endif 01614 } 01615 } 01616 else if (MESSAGE_IS_A(Message, DocViewMsg)) 01617 { 01618 DocViewMsg *Msg = (DocViewMsg *) Message; 01619 switch (Msg->State) 01620 { 01621 case DocViewMsg::DocViewState::SELABOUTTOCHANGE: 01622 OldGuideLayerState = GetGuideLayerState(Msg->pNewDocView); 01623 break; 01624 01625 case DocViewMsg::DocViewState::SELCHANGED: 01626 { 01627 if (IsVisible()) 01628 { 01629 NewGuideLayerState = GetGuideLayerState(Msg->pNewDocView); 01630 if (OldGuideLayerState != NewGuideLayerState) 01631 { 01632 TRACEUSER( "Neville", _T("frame DocViewMsg::DocViewState::SELCHANGED CreateNewSubtree\n")); 01633 CreateNewSubtree(Msg->pNewDocView->GetDoc()); 01634 ForceRedrawOfList(); 01635 } 01636 } 01637 } 01638 break; 01639 } 01640 } 01641 else if (MESSAGE_IS_A(Message, LayerMsg)) 01642 { 01643 LayerMsg *pMsg = (LayerMsg *) Message; 01644 01645 switch ( pMsg->Reason ) 01646 { 01647 // The active layer has changed. 01648 case LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED: 01649 { 01650 EnableGadget(_R(IDC_GALLERY_COPY),pMsg->pNewLayer != NULL && !pMsg->pNewLayer->IsGuide()); 01651 01652 UpdateFrameRelatedButtons(); 01653 } 01654 break; 01655 01656 // The active layer has been changed externally to the gallery. 01657 case LayerMsg::LayerReason::UPDATE_ACTIVE_LAYER: 01658 { 01659 // We must now check whether the selected layer has been changed externally 01660 // to us. May happen if an animated GIF is being loaded onto layers 01661 SGDisplayLayer *pDisplayItem = NULL; 01662 if (DisplayForeground != NULL && IsVisible()) 01663 pDisplayItem = GetSelectedLayerGalItem(); 01664 if (pDisplayItem != NULL) 01665 { 01666 if (pMsg->pNewLayer != NULL && pDisplayItem->GetDisplayedLayer() != pMsg->pNewLayer) 01667 { 01668 Layer* pNewActiveLayer = pMsg->pNewLayer; 01669 // Search for the new display item to match this new active layer 01670 SGDisplayLayer *pWantedDispLayer = NULL; 01671 SGDisplayLayer *pDispLayer = ((SGDisplayLayer *) DisplayForeground->GetChild()); 01672 while (pDispLayer != NULL) 01673 { 01674 if (pDispLayer->GetDisplayedLayer() == pNewActiveLayer) 01675 pWantedDispLayer = pDispLayer; 01676 pDispLayer = ((SGDisplayLayer *)pDispLayer->GetNext()); 01677 } 01678 01679 // If we found the required display item then go and select it 01680 if (pWantedDispLayer) 01681 { 01682 // Now update the selection states... 01683 SelectItems(FALSE); // Deselect everything else 01684 // Something has changed so we must go and select this new item 01685 pWantedDispLayer->SetSelected(TRUE); 01686 } 01687 } 01688 } 01689 } 01690 break; 01691 01692 // The specified layer has been changed externally to the gallery. 01693 // So redraw the name. 01694 case LayerMsg::LayerReason::REDRAW_LAYER: 01695 { 01696 TRACEUSER( "Neville", _T("frame LayerMsg::LayerReason::REDRAW_LAYER\n")); 01697 Layer * pWantedLayer = pMsg->pNewLayer; 01698 if (pWantedLayer != NULL && DisplayForeground != NULL && IsVisible()) 01699 { 01700 // Search for the new display item to match this new active layer 01701 SGDisplayLayer *pWantedDispLayer = NULL; 01702 SGDisplayLayer *pDispLayer = ((SGDisplayLayer *) DisplayForeground->GetChild()); 01703 while (pDispLayer != NULL) 01704 { 01705 if (pDispLayer->GetDisplayedLayer() == pWantedLayer) 01706 pWantedDispLayer = pDispLayer; 01707 pDispLayer = ((SGDisplayLayer *)pDispLayer->GetNext()); 01708 } 01709 01710 // If we found it then force a redraw 01711 if (pWantedDispLayer) 01712 pWantedDispLayer->ForceRedrawOfMyself(); 01713 } 01714 } 01715 break; 01716 } 01717 } 01718 01719 return(SuperGallery::Message(Message)); 01720 } 01721 01722 /*********************************************************************************************** 01723 01724 > void FrameSGallery::EnsureSelSpreadSelectionIntegrity() 01725 01726 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 01727 Created: 16/4/97 (Based on Jason's Layer gallery code) 01728 Purpose: This makes sure that all the invisible and/or locked layers in the spread 01729 have no selection. It calls NodeRenderableInk::DeselectAllOnLayer() on each 01730 layer that should NOT have a selection, just in case. 01731 Currently only called after an undo or redo op, because it could be quite slow 01732 01733 ***********************************************************************************************/ 01734 01735 void FrameSGallery::EnsureSelSpreadSelectionIntegrity() 01736 { 01737 if (pSpread == NULL) return; 01738 01739 // Get the first layer in the spread 01740 Layer* pLayer = pSpread->FindFirstLayer(); 01741 01742 while (pLayer != NULL) 01743 { 01744 // If the layer is not visible OR the layer is locked, make sure there is no selection 01745 if (!pLayer->IsVisible() || pLayer->IsLocked()) 01746 NodeRenderableInk::DeselectAllOnLayer(pLayer); 01747 01748 pLayer = pLayer->FindNextLayer(); 01749 } 01750 } 01751 01752 #endif // EXCLUDE_GALS 01753 01754 01755 /*********************************************************************************************** 01756 01757 > static void FrameSGallery::SetActive(Document* pDoc,Layer* pLayer,BOOL state) 01758 01759 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 01760 Created: 16/4/97 (Based on Jason's Layer gallery code) 01761 Inputs: pDoc = ptr to doc containing layer 01762 pLayer = ptr that contains this layer 01763 state = TRUE means make active, FALSE means make inactive 01764 Outputs: - 01765 Returns: - 01766 Purpose: Calls pLayer->SetActive(state), redrawing and changing the layer's selection 01767 if necessary. 01768 DON'T CALL THIS FUNC!! USE MakeActiveLayer() INSTEAD!!!! 01769 01770 ***********************************************************************************************/ 01771 01772 void FrameSGallery::SetActive(Document* pDoc,Layer* pLayer,BOOL state) 01773 { 01774 // This flag is TRUE if the selection on the layer should be cleared 01775 BOOL ClearSelection = FALSE; 01776 01777 // get state before active change 01778 BOOL PrevVisibleState = pLayer->IsVisible(); 01779 BOOL PrevLockedState = pLayer->IsLocked(); 01780 01781 // Change active state 01782 pLayer->SetActive(state); 01783 01784 // get state after active change 01785 BOOL PostVisibleState = pLayer->IsVisible(); 01786 BOOL PostLockedState = pLayer->IsLocked(); 01787 01788 if (PrevVisibleState != PostVisibleState) 01789 { 01790 // If the visible state has changed, redraw the layer 01791 FrameSGallery::ForceRedrawLayer(pDoc,pLayer); 01792 01793 // If it has just become invisible, clear the selection 01794 ClearSelection = (ClearSelection || !PostVisibleState); 01795 } 01796 01797 // if it has just become locked, clear the selection 01798 if (PrevLockedState != PostLockedState) 01799 ClearSelection = (ClearSelection || PostLockedState); 01800 01801 // Clear the selection if needed 01802 if (ClearSelection) 01803 NodeRenderableInk::DeselectAllOnLayer(pLayer); 01804 } 01805 01806 01807 01808 /*********************************************************************************************** 01809 01810 > static void FrameSGallery::MakeActiveLayer(Layer* pNewActiveLayer, UndoableOperation * pUndoOp = NULL) 01811 01812 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 01813 Created: 16/4/97 (Based on Jason's Layer gallery code) 01814 Inputs: pNewActiveLayer = ptr to the layer you want to be active 01815 pUndoOp = if non null, the default, will do the change undoably 01816 Outputs: - 01817 Returns: - 01818 Purpose: Makes the layer active. 01819 Firstly it will inactivate any other active layers, forcing it to redraw if necessary 01820 Then it will set this layer to be active, again forcing a redraw if necessary 01821 01822 If the given new layer is already active, nothing happens 01823 01824 Note: pNewActiveLayer must be in the currect doc 01825 01826 ***********************************************************************************************/ 01827 01828 void FrameSGallery::MakeActiveLayer(Layer* pNewActiveLayer, UndoableOperation * pUndoOp) 01829 { 01830 Spread* pSpread = pNewActiveLayer->FindParentSpread(); 01831 ERROR3IF(pSpread == NULL,"Eh up, the layer has no parent spread"); 01832 if (pSpread == NULL) return; 01833 01834 Document *pDoc = pSpread->FindParentDocument(); 01835 if (pDoc == NULL) return; 01836 01837 { 01838 // Remove any other active layers, redrawing if necessary. 01839 Layer* pLayer = pSpread->FindFirstLayer(); 01840 while (pLayer != NULL) 01841 { 01842 if (pLayer->IsActive() && pLayer != pNewActiveLayer) 01843 { 01844 if (pUndoOp == NULL) 01845 FrameSGallery::SetActive(pDoc,pLayer,FALSE); 01846 else 01847 { 01848 // Make layer active undoably 01849 OpLayerGalParam Param(LAYER_ACTIVE, pSpread); 01850 Param.NewState = FALSE; 01851 Param.pLayer = pLayer; 01852 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 01853 } 01854 } 01855 01856 pLayer = pLayer->FindNextLayer(); 01857 } 01858 } 01859 01860 // Go though the layers from the new active layer downwards and set 01861 // all previous layers non-visible and non-selected 01862 FixOtherLayersFromActive(pNewActiveLayer, pUndoOp); 01863 01864 // Make sure the new layer is active, redrawing if necessary 01865 /* if (!pNewActiveLayer->IsActive()) 01866 { 01867 if (pUndoOp == NULL) 01868 FrameSGallery::SetActive(pDoc,pNewActiveLayer,TRUE); 01869 else 01870 { 01871 // Make layer active undoably 01872 OpLayerGalParam Param(LAYER_ACTIVE, pSpread); 01873 Param.NewState = TRUE; 01874 Param.pLayer = pNewActiveLayer; 01875 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 01876 } 01877 } */ 01878 if (pUndoOp == NULL) 01879 { 01880 if (!pNewActiveLayer->IsActive()) 01881 FrameSGallery::SetActive(pDoc,pNewActiveLayer,TRUE); 01882 } 01883 else 01884 { 01885 // Make layer active undoably 01886 OpLayerGalParam Param(LAYER_ACTIVE, pSpread); 01887 Param.NewState = TRUE; 01888 Param.pLayer = pNewActiveLayer; 01889 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 01890 } 01891 01892 #if defined(EXCLUDE_FROM_RALPH) 01893 //ERROR3("FrameSGallery::MakeActiveLayer supressed broadcast - bad !"); 01894 #else 01895 BROADCAST_TO_ALL(LayerMsg(pNewActiveLayer,LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); 01896 #endif 01897 } 01898 01899 01900 /*********************************************************************************************** 01901 01902 > static void FrameSGallery::FixOtherLayers() 01903 01904 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01905 Created: 17/4/97 01906 Inputs: pSpread = ptr to spread 01907 Outputs: - 01908 Returns: - 01909 Purpose: A layer flag such as overlay or solid has been changed and so we need to go 01910 and find the active layer and ensure that the other layers above and below this 01911 have the correct visibility and locked settings. 01912 01913 ***********************************************************************************************/ 01914 01915 void FrameSGallery::FixOtherLayers(Spread* pSpread) 01916 { 01917 // Check that the class variable storing the current/selected spread is ok 01918 if (pSpread == NULL) return; 01919 01920 // Get the first layer in the spread 01921 Layer* pFirstLayer = pSpread->FindFirstLayer(); 01922 01923 // Not found an active layer yet 01924 Layer* pActiveLayer = NULL; 01925 01926 // Start the search from the first layer 01927 Layer* pLayer = pFirstLayer; 01928 while (pLayer != NULL && pActiveLayer == NULL) 01929 { 01930 if (pLayer->IsActive()) 01931 pActiveLayer = pLayer; // Found the active layer, so make a note of it 01932 01933 pLayer = pLayer->FindNextLayer(); 01934 } 01935 01936 if (pActiveLayer) 01937 FixOtherLayersFromActive(pActiveLayer); 01938 } 01939 01940 /*********************************************************************************************** 01941 01942 > static void FrameSGallery::FixOtherLayersFromActive(Layer * pActiveLayer, 01943 UndoableOperation * pUndoOp = NULL) 01944 01945 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01946 Created: 17/4/97 01947 Inputs: pActiveLayer = the current active layer 01948 pUndoOp = if non null, the default, will do the change undoably 01949 Purpose: A layer flag such as overlay or solid has been changed and so we need take the 01950 passed in current active layer and then ensure that the other layers above and 01951 below this have the correct visibility and locked settings. 01952 01953 ***********************************************************************************************/ 01954 01955 void FrameSGallery::FixOtherLayersFromActive(Layer * pActiveLayer, 01956 UndoableOperation * pUndoOp) 01957 { 01958 // This might be the new active layer that we are setting and so 01959 // it might not have been made active yet! 01960 if (pActiveLayer == NULL) // || !pActiveLayer->IsActive()) 01961 { 01962 ERROR3("FixOtherLayersFromActive has been given a bad active layer!"); 01963 return; 01964 } 01965 01966 // Only need a spread pointer in the undoable case 01967 Spread * pSpread = NULL; 01968 if (pUndoOp != NULL) 01969 pSpread = pActiveLayer->FindParentSpread(); 01970 01971 // Ensure that the new active layer is going to be visible and unlocked 01972 // Assume code is called from make active code which will force the redraw 01973 // and selection changes as required. So do it the simple way 01974 if (pUndoOp == NULL || pSpread == NULL) 01975 { 01976 LayerSGallery::DoChangeVisible(pActiveLayer,TRUE); 01977 LayerSGallery::DoChangeLocked(pActiveLayer,FALSE); 01978 } 01979 else 01980 { 01981 // Make visible and locked 01982 // Only change if required as otherwise we will get an unwanted undo step 01983 // if (!pActiveLayer->IsVisible()) 01984 { 01985 OpLayerGalParam Param(LAYER_VISIBLE, pSpread); 01986 Param.NewState = TRUE; 01987 Param.pLayer = pActiveLayer; 01988 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 01989 } 01990 01991 // Only change if required as otherwise we will get an unwanted undo step 01992 // if (pActiveLayer->IsLocked()) 01993 { 01994 OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); 01995 LockedParam.NewState = FALSE; 01996 LockedParam.pLayer = pActiveLayer; 01997 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); 01998 } 01999 } 02000 02001 // Go though the layers from the new active layer downwards and set 02002 // all previous layers non-visible and non-selected 02003 Layer* pLayer = pActiveLayer->FindPrevLayer(); 02004 BOOL FoundSolid = pActiveLayer->IsSolid(); 02005 BOOL OverlayPrevious = FALSE; 02006 // Solid flag overrides the overlay flag 02007 if (!FoundSolid) 02008 OverlayPrevious = pActiveLayer->IsOverlay(); 02009 while (pLayer != NULL) 02010 { 02011 if (pLayer->IsPseudoFrame()) 02012 { 02013 if (pLayer->IsSolid() && !FoundSolid) 02014 { 02015 // Stop any later solid frames having any effect 02016 FoundSolid = TRUE; 02017 // Stop any overlay having an effect 02018 OverlayPrevious = FALSE; 02019 if (pUndoOp == NULL || pSpread == NULL) 02020 { 02021 LayerSGallery::DoChangeVisible(pLayer,TRUE); 02022 LayerSGallery::DoChangeLocked(pLayer,TRUE); 02023 } 02024 else 02025 { 02026 // Only change if required as otherwise we will get an unwanted undo step 02027 // if (!pLayer->IsVisible()) 02028 { 02029 OpLayerGalParam Param(LAYER_VISIBLE, pSpread); 02030 Param.NewState = TRUE; 02031 Param.pLayer = pLayer; 02032 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 02033 } 02034 // Only change if required as otherwise we will get an unwanted undo step 02035 // if (!pLayer->IsLocked()) 02036 { 02037 OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); 02038 LockedParam.NewState = TRUE; 02039 LockedParam.pLayer = pLayer; 02040 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); 02041 } 02042 } 02043 } 02044 else 02045 { 02046 BOOL NewVisibleState = TRUE; 02047 if (OverlayPrevious) 02048 NewVisibleState = TRUE; 02049 else 02050 NewVisibleState = FALSE; 02051 02052 if (pUndoOp == NULL || pSpread == NULL) 02053 { 02054 LayerSGallery::DoChangeVisible(pLayer,NewVisibleState); 02055 LayerSGallery::DoChangeLocked(pLayer,TRUE); 02056 } 02057 else 02058 { 02059 // Only change if required as otherwise we will get an unwanted undo step 02060 // if (pLayer->IsVisible() != NewVisibleState) 02061 { 02062 OpLayerGalParam Param(LAYER_VISIBLE, pSpread); 02063 Param.NewState = NewVisibleState; 02064 Param.pLayer = pLayer; 02065 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 02066 } 02067 // Only change if required as otherwise we will get an unwanted undo step 02068 // if (!pLayer->IsLocked()) 02069 { 02070 OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); 02071 LockedParam.NewState = TRUE; 02072 LockedParam.pLayer = pLayer; 02073 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); 02074 } 02075 } 02076 02077 // If we are currently overlaying and this frame 02078 // is overlay as well then keep overlay on, otherwise 02079 // turn it off. 02080 if (OverlayPrevious && pLayer->IsOverlay()) 02081 OverlayPrevious = TRUE; 02082 else 02083 OverlayPrevious = FALSE; 02084 } 02085 02086 // Overlay should only affect the previous frame 02087 //if (!pLayer->IsSolid() && pLayer->IsOverlay()) 02088 // OverlayPrevious = TRUE; 02089 //else 02090 // OverlayPrevious = FALSE; 02091 } 02092 02093 pLayer = pLayer->FindPrevLayer(); 02094 } 02095 02096 // Go though the layers from the new active layer upwards and set 02097 // all layers above to be non-visible and non-selected 02098 pLayer = pActiveLayer->FindNextLayer(); 02099 while (pLayer != NULL) 02100 { 02101 if (pLayer->IsPseudoFrame()) 02102 { 02103 if (pUndoOp == NULL || pSpread == NULL) 02104 { 02105 LayerSGallery::DoChangeVisible(pLayer,FALSE); 02106 LayerSGallery::DoChangeLocked(pLayer,TRUE); 02107 } 02108 else 02109 { 02110 // Only change if required as otherwise we will get an unwanted undo step 02111 // if (pLayer->IsVisible()) 02112 { 02113 OpLayerGalParam Param(LAYER_VISIBLE, pSpread); 02114 Param.NewState = FALSE; 02115 Param.pLayer = pLayer; 02116 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); 02117 } 02118 // Only change if required as otherwise we will get an unwanted undo step 02119 // if (!pLayer->IsLocked()) 02120 { 02121 OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); 02122 LockedParam.NewState = TRUE; 02123 LockedParam.pLayer = pLayer; 02124 LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); 02125 } 02126 } 02127 } 02128 02129 pLayer = pLayer->FindNextLayer(); 02130 } 02131 } 02132 02133 02134 /*********************************************************************************************** 02135 02136 > static void FrameSGallery::EnsureActiveLayerIntegrity(Spread* pSpread,Layer** ppActiveLayer = NULL) 02137 02138 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02139 Created: 16/4/97 (Based on Jason's Layer gallery code) 02140 Inputs: pSpread = ptr to spread 02141 Outputs: - 02142 Returns: - 02143 Purpose: This checks that there is one and only one active layer in the given spread. 02144 If there isn't an active layer, the first layer is made active. 02145 If there is more than on active layer, all but the first active layer are 02146 made inactive. 02147 02148 ***********************************************************************************************/ 02149 02150 /* void FrameSGallery::EnsureActiveLayerIntegrity(Spread* pSpread,Layer** ppActiveLayer) 02151 { 02152 if (pSpread == NULL) return; 02153 02154 // Get the first layer in the spread 02155 Layer* pFirstLayer = pSpread->FindFirstLayer(); 02156 02157 // Not found an active layer yet 02158 Layer* pActiveLayer = NULL; 02159 02160 // Start the search from the first layer 02161 Layer* pLayer = pFirstLayer; 02162 02163 while (pLayer != NULL && pActiveLayer == NULL) 02164 { 02165 if (pLayer->IsActive()) 02166 pActiveLayer = pLayer; // Found the active layer, so make a note of it 02167 02168 pLayer = pLayer->FindNextLayer(); 02169 } 02170 02171 // If we haven't found any active layers, make the last (top) one active 02172 if (pActiveLayer == NULL) 02173 pActiveLayer = pSpread->FindLastLayer(); 02174 02175 // If we have an active layer, ensure that it really is the one and only active layer 02176 if (pActiveLayer != NULL) 02177 FrameSGallery::MakeActiveLayer(pActiveLayer); 02178 02179 // If caller wants the ptr to the active layer 02180 if (ppActiveLayer != NULL) 02181 *ppActiveLayer = pActiveLayer; 02182 } */ 02183 02184 02185 /******************************************************************************************** 02186 02187 > static BOOL FrameSGallery::EnsureFrameLayerIntegrity(Spread* pSpread) 02188 02189 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02190 Created: 21/5/97 02191 Returns: True if worked ok, False otherwise. 02192 Purpose: This function should be called before any frame related actions are carried out 02193 It will ensure that all the visible layers are frame layers. 02194 Errors: - 02195 SeeAlso: - 02196 02197 ********************************************************************************************/ 02198 02199 BOOL FrameSGallery::EnsureFrameLayerIntegrity(Spread* pSpread) 02200 { 02201 ERROR2IF(pSpread == NULL,FALSE,"EnsureFrameLayerIntegrity null spread passed in"); 02202 02203 // For the present moment just ensure that the active layer is a frame layer 02204 //Layer * pActiveLayer = pSpread->FindActiveLayer(); 02205 //if (pActiveLayer) 02206 // pActiveLayer->SetFrame(TRUE); 02207 02208 /* #if _DEBUG 02209 // Find out whether the operation thinks it is required or not 02210 String_256 ShadeReason; 02211 OpState State; 02212 State = OpCombineLayersToFrameLayer::GetState(&ShadeReason, NULL); 02213 if (!State.Greyed) 02214 { 02215 // Try and find the operation we want to use 02216 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_COMBINELAYERSTOFRAMELAYER); 02217 if (pOpDesc != NULL) 02218 { 02219 // We found it, so invoke it with the spread we were given 02220 OpParam Param; 02221 Param.Param1 = (INT32)pSpread; 02222 pOpDesc->Invoke(&Param); 02223 } 02224 else 02225 { 02226 ERROR3("Couldn't find OPTOKEN_COMBINELAYERSTOFRAMELAYER op descriptor"); 02227 } 02228 } */ 02229 02230 /* #if 0 //_DEBUG 02231 // WARNING only do this in Webster builds as otherwise may be corrupting layers that are in the 02232 // undo buffer which could lead to immense problems. 02233 // This leads to problems in the undo e.g. draw object, import doc with layers and undo back to start 02234 // can mean no layers in doc. 02235 // In Camelot do nothing 02236 #ifdef WEBSTER 02237 // Ensure that all other non-guide and non-background layers are frame layers 02238 UINT32 NonFrameLayersFound = 0; 02239 Layer* pCurrentLayer = pSpread->FindFirstLayer(); 02240 Layer* pNonFrameLayer = NULL; 02241 while (pCurrentLayer != NULL) 02242 { 02243 if (!pCurrentLayer->IsBackground() && !pCurrentLayer->IsGuide() && 02244 !pCurrentLayer->IsPageBackground() && !pCurrentLayer->IsFrame()) 02245 { 02246 // Note that we have found a non-frame layer. 02247 pNonFrameLayer = pCurrentLayer; 02248 NonFrameLayersFound++; 02249 } 02250 02251 pCurrentLayer = pCurrentLayer->FindNextLayer(); 02252 } 02253 02254 if (NonFrameLayersFound > 0 && pNonFrameLayer != NULL) 02255 { 02256 TRACEUSER( "Neville", _T("++++++++++EnsureFrameLayerIntegrity found %d non-frame layers\n"),NonFrameLayersFound); 02257 02258 // Right, we need to move all the nodes from the all non-frame layers and move them 02259 // to one of the non-frame layers and make this one a frame layer. The user should 02260 // therefore notice no difference in appearance of the document as they would have 02261 // been seeing one frame representing all the non-frame layers in the frame gallery. 02262 02263 // First, mark the non-frame layer found in the above search as a frame layer as this 02264 // is the one that we are going to use as out destination. Then all other non-frame 02265 // searches will not find it. Also, mark it as edited. 02266 pNonFrameLayer->SetFrame(TRUE); 02267 pNonFrameLayer->SetEdited(TRUE); 02268 02269 // Start a progress bar 02270 Progress CombiningProgress(_R(IDS_COMBINING_LAYERS)); 02271 CombiningProgress.Update(); 02272 02273 BOOL UpdateSelection = FALSE; 02274 Layer* pLayer = pSpread->FindFirstLayer(); 02275 while (pLayer != NULL) 02276 { 02277 if (!pLayer->IsBackground() && !pLayer->IsGuide() && 02278 !pLayer->IsPageBackground() && !pLayer->IsFrame()) 02279 { 02280 // Move all the top level nodes to the new layer 02281 // We MUST include hidden nodes as these will be in undo records 02282 Node * pNode = pLayer->FindFirstChild(); 02283 while (pNode) 02284 { 02285 // Note the node to move 02286 Node* pNodeToMove = pNode; 02287 // and the next node in the tree 02288 pNode = pNode->FindNext(); 02289 // Now move hide the node (should hide it but we are not undoable) 02290 UpdateSelection = pNodeToMove->IsSelected(); 02291 //if (!DoHideNode(pNodeToMove, FALSE, NULL, FALSE)) 02292 // Find the insertion point, which will be after the last child but 02293 // BEFORE the insertion node, if present. 02294 Node * pInsertPoint = pNonFrameLayer->FindLastChild(TRUE); 02295 if (pInsertPoint) 02296 pNodeToMove->MoveNode(pInsertPoint, NEXT); 02297 else 02298 pNodeToMove->MoveNode(pNonFrameLayer, LASTCHILD); 02299 02300 // Update the progress display to show we have done something 02301 CombiningProgress.Update(); 02302 } 02303 02304 // Finally, go and hide that layer 02305 Layer * pLayerToHide = pLayer; 02306 // First, invalidate the bounding rect 02307 pLayerToHide->InvalidateBoundingRect(); 02308 // note the next layer 02309 pLayer = pLayer->FindNextLayer(); 02310 // and hide the layer itself. 02311 // Have to do this ourselves as we are not undoable 02312 pLayerToHide->CascadeDelete(); 02313 delete pLayerToHide; 02314 pLayerToHide = NULL; 02315 } 02316 else 02317 pLayer = pLayer->FindNextLayer(); 02318 02319 // Update the progress display to show we have done something 02320 CombiningProgress.Update(); 02321 } 02322 02323 // Make sure that our new frame layer is up to date 02324 pNonFrameLayer->InvalidateBoundingRect(); 02325 02326 // If we have changed a selected node then update the selection 02327 if (UpdateSelection) 02328 { 02329 // Update the selection range 02330 Camelot.UpdateSelection(); 02331 } 02332 02333 // We need to update the display as one or more layer items have changed status 02334 // So tell ourselves about the change. (We are static and so cannot do it directly!) 02335 BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::SpreadReason::LAYERCHANGES)); 02336 02337 // Update the progress display to show we have done something 02338 CombiningProgress.Update(); 02339 } 02340 #endif // WEBSTER 02341 #endif // DEBUG 02342 */ 02343 02344 // In Webster ensure that all layers are actually frames 02345 // In Camelot do nothing 02346 #ifdef WEBSTER 02347 // Ensure that all other non-guide and non-background layers are frame layers 02348 UINT32 NonFrameLayersFound = 0; 02349 Layer* pCurrentLayer = pSpread->FindFirstLayer(); 02350 while (pCurrentLayer != NULL) 02351 { 02352 if (pCurrentLayer->IsPseudoFrame() && !pCurrentLayer->IsFrame()) 02353 { 02354 pCurrentLayer->SetFrame(TRUE); 02355 NonFrameLayersFound++; 02356 } 02357 02358 pCurrentLayer = pCurrentLayer->FindNextLayer(); 02359 } 02360 02361 if (NonFrameLayersFound > 0) 02362 { 02363 TRACEUSER( "Neville", _T("++++++++++EnsureFrameLayerIntegrity found %d non-frame layers\n"),NonFrameLayersFound); 02364 02365 // We need to update the display as one or more layer items have changed status 02366 // So tell ourselves about the change. (We are static and so cannot do it directly!) 02367 BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::SpreadReason::LAYERCHANGES)); 02368 } 02369 #endif // WEBSTER 02370 02371 return TRUE; 02372 } 02373 02374 /******************************************************************************************** 02375 02376 > static BOOL FrameSGallery::DoHideNode(Node* pNodeToHide) 02377 02378 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 02379 Created: 21/5/97 02380 Returns: True if worked ok, False otherwise. 02381 Purpose: This function tries to hide the specified node. Copy of the undoable operation 02382 version as we are not undoable and don't have an op. 02383 Hide it as it may be mentioned in the undo history. 02384 Note: 02385 This would be safer than deleting the layer nodes but if we use this, which should be the same 02386 as the DoHideNode in undoable operation does, then it leaks the hidden nodes and layers that 02387 are being hidden. So there must be something sneaky going on. 02388 02389 ********************************************************************************************/ 02390 02391 /* BOOL FrameSGallery::DoHideNode(Node* pNodeToHide) 02392 { 02393 ERROR2IF(pNodeToHide == NULL,FALSE,"FrameSGallery::DoHideNode Bad node speicifed"); 02394 02395 // Try to hide the Node 02396 NodeHidden* pHidden = new NodeHidden(pNodeToHide); 02397 if (pHidden == NULL) 02398 { 02399 return FALSE; 02400 } 02401 02402 return TRUE; 02403 } */ 02404 02405 02406 /******************************************************************************************** 02407 02408 > static String_256 FrameSGallery::CreateUniqueLayerID(Spread* pSpread, const String_256 * pBaseName) 02409 02410 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02411 Created: 16/4/97 (Based on Jason's Layer gallery code) 02412 Inputs: pSpread - the spread to use when checking 02413 pBaseName - the name to use as the basis of the layer name, defaults to just 'Frame' 02414 Returns: A LayerID which is unique for the layer galleries spread. 02415 Purpose: Used to generate a LayerID which is unique for the spread. The name 02416 generated is normally of the form "Layer n", where n is the number of layers 02417 in the spread + 1. If "Layer n" already exists on the spread then 02418 "Layer m" is generated where m is the smallest integer greater than n such 02419 that the id is unique. 02420 Errors: - 02421 SeeAlso: - 02422 02423 ********************************************************************************************/ 02424 02425 String_256 FrameSGallery::CreateUniqueLayerID(Spread* pSpread, const String_256 * pBaseName) 02426 { 02427 if (pSpread == NULL) return String_256(""); 02428 02429 String_256 UniqueLayerID; 02430 INT32 NumLayers = 0; 02431 02432 Layer* pLayer = pSpread->FindFirstLayer(); 02433 02434 // Calculate how many layers are on the current spread 02435 while (pLayer != NULL) 02436 { 02437 NumLayers++; 02438 pLayer = pLayer->FindNextLayer(); 02439 } 02440 02441 INT32 NewLayerNum = NumLayers; 02442 if (NewLayerNum == 0) 02443 NewLayerNum = 1; // Always start at one 02444 02445 BOOL Unique; // Flag used to indicate if the id generated is unique or not 02446 String_256 LayerName(_R(IDS_DEFAULTFRAMENAME)); 02447 // If the caller suggested a base name then use this instead. 02448 if (pBaseName != NULL) 02449 LayerName = *pBaseName; 02450 02451 do 02452 { 02453 // Construct a first attempt at a unique layer id 'Layer n' 02454 // where n = the number of layers on the current spread + 1 02455 UniqueLayerID.MakeMsg(_R(IDS_FRAMENAMEUNIQUEFORM), (TCHAR *)LayerName, NewLayerNum); 02456 //UniqueLayerID.MakeMsg(_R(IDS_SGLAYER_LAYER_NUM), /*TEXT("Layer #1%ld"),*/NewLayerNum); 02457 02458 // Check that UniqueLayerID is indeed unique 02459 Unique = TRUE; // Until we know better 02460 pLayer = pSpread->FindFirstLayer(); 02461 while (pLayer != NULL) 02462 { 02463 if (UniqueLayerID == pLayer->GetLayerID()) 02464 { 02465 Unique = FALSE; 02466 02467 // UniqueLayerID is not unique so increment NewLayerNum and try again 02468 NewLayerNum++; 02469 break; 02470 } 02471 pLayer = pLayer->FindNextLayer(); 02472 } 02473 02474 } while (!Unique); 02475 02476 return(UniqueLayerID); 02477 } 02478 02479 #ifndef EXCLUDE_GALS 02480 02481 /*********************************************************************************************** 02482 02483 > SGDisplayFrame *FrameSGallery::GetSelectedLayerGalItem() 02484 02485 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02486 Created: 16/4/97 (Based on Jason's Layer gallery code) 02487 Returns: A ptr to the selected layer gallery item. 02488 NULL if there is no selectet item 02489 Purpose: Gets the selected layer gallery item 02490 In debug builds, an ENSURE will go off if there is no selected gal item 02491 02492 ***********************************************************************************************/ 02493 02494 SGDisplayLayer *FrameSGallery::GetSelectedLayerGalItem() 02495 { 02496 SGDisplayFrame* pDispLayer = NULL; 02497 02498 if (CheckVarsAreValid()) 02499 { 02500 ERROR3IF(DisplayForeground == NULL,"Foreground group is NULL"); 02501 if (DisplayForeground == NULL) 02502 return NULL; 02503 02504 // Look in the foreground group first 02505 pDispLayer = ((SGDisplayFrame *) DisplayForeground->FindNextSelectedItem(NULL)); 02506 02507 ERROR3IF(pDispLayer == NULL,"Can't find the selected layer item in the layer gallery"); 02508 } 02509 02510 return(pDispLayer); 02511 } 02512 02513 /*********************************************************************************************** 02514 02515 > BOOL FrameSGallery::DoDeleteSelection(void) 02516 02517 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02518 Created: 16/4/97 (Based on Jason's Layer gallery code) 02519 Returns: FALSE if it couldn't delete the selection. (This should, if at all possible 02520 leave the entire selection undeleted in this case) 02521 02522 Purpose: FORCIBLY deletes the active layer/frame. 02523 02524 SeeAlso: FrameSGallery::PrepareToDelete; ColourManager::HideColours 02525 02526 ***********************************************************************************************/ 02527 02528 BOOL FrameSGallery::DoDeleteSelection(void) 02529 { 02530 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_DELETEFRAME); 02531 if (pOpDesc != NULL) 02532 pOpDesc->Invoke(); 02533 else 02534 { 02535 ERROR3("Couldn't find OPTOKEN_FRAME_DELETEFRAME op descriptor"); 02536 } 02537 02538 return TRUE; 02539 } 02540 02541 02542 /*********************************************************************************************** 02543 02544 > void FrameSGallery::DoCreateNewItem(void) 02545 02546 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02547 Created: 16/4/97 (Based on Jason's Layer gallery code) 02548 02549 Purpose: This function is meant to be overridden in derived classes 02550 It creates a new item and adds it to the Gallery DisplayList 02551 The item may be created by cloning/deriving/basing-on the 02552 selected item, depending on the type of Gallery concerned. 02553 02554 ***********************************************************************************************/ 02555 void FrameSGallery::DoCreateNewItem(void) 02556 { 02557 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_NEWFRAME); 02558 if (pOpDesc != NULL) 02559 pOpDesc->Invoke(); 02560 else 02561 { 02562 ERROR3("Couldn't find OPTOKEN_FRAME_NEWFRAME op descriptor"); 02563 } 02564 } 02565 02566 /*********************************************************************************************** 02567 02568 > void FrameSGallery::DoCopyLayer() 02569 02570 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02571 Created: 16/4/97 (Based on Jason's Layer gallery code) 02572 Inputs: - 02573 Returns: - 02574 Purpose: Copies the active layer creating a new one with a default frame name. 02575 02576 ***********************************************************************************************/ 02577 02578 void FrameSGallery::DoCopyLayer() 02579 { 02580 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_COPYFRAME); 02581 if (pOpDesc != NULL) 02582 pOpDesc->Invoke(); 02583 else 02584 { 02585 ERROR3("Couldn't find OPTOKEN_FRAME_COPYFRAME op descriptor"); 02586 } 02587 } 02588 02589 /*********************************************************************************************** 02590 02591 > static void FrameSGallery::DoChangeSoild(Layer* pLayer,BOOL Solid) 02592 02593 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02594 Created: 16/4/97 (Based on Jason's Layer gallery code) 02595 Inputs: pLayer = the layer to change 02596 Solid - TRUE means make the displayed layer Solid 02597 FALSE means make Solid 02598 02599 Returns: - 02600 Purpose: Called when the Solid button is clicked in a layer gallery item. 02601 Changes the Solidness of the displayed layer. 02602 02603 Notes: Does not redraw the layer in the display list 02604 02605 ***********************************************************************************************/ 02606 02607 void FrameSGallery::DoChangeSolid(Layer* pLayer,BOOL Solid) 02608 { 02609 ERROR3IF(pLayer == NULL,"pLayer == NULL"); 02610 if (pLayer == NULL) return; 02611 02612 BOOL PrevSolid = pLayer->IsSolid(); 02613 pLayer->SetSolid(Solid); 02614 BOOL PostSolid = pLayer->IsSolid(); 02615 02616 /* if (PrevSolid != PostSolid) 02617 { 02618 // Force a redraw if the layer's visibility has changed 02619 FrameSGallery::ForceRedrawLayer(pLayer->FindDocument(), pLayer); 02620 02621 // If layer has just become invisible, remove the selections on the layer 02622 if (!PostSolid) 02623 NodeRenderableInk::DeselectAllOnLayer(pLayer); 02624 } */ 02625 02626 if (PrevSolid != PostSolid) 02627 { 02628 // Mark all frames above this as edited until we reach the last frame 02629 // OR we hit a solid/background layer. 02630 // Previewing all the frames copes with dependent frames 02631 // Previwing single frames does not if you preview the solid frame. 02632 Layer * pFrame = pLayer->FindNextFrameLayer(); 02633 while (pFrame != NULL && !pFrame->IsSolid()) 02634 { 02635 // Mark that frame as edited 02636 pFrame->SetEdited(TRUE); 02637 pFrame = pFrame->FindNextFrameLayer(); 02638 } 02639 02640 Spread* pSpread = pLayer->FindParentSpread(); 02641 // Go and fix the status of other layers according to this new setting 02642 FixOtherLayers(pSpread); 02643 02644 // Ensure that the buttons are in the correct state 02645 BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); 02646 } 02647 } 02648 02649 /*********************************************************************************************** 02650 02651 > static void FrameSGallery::DoChangeOverlay(Layer* pLayer,BOOL Overlay) 02652 02653 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02654 Created: 16/4/97 (Based on Jason's Layer gallery code) 02655 Inputs: pLayer = the layer to change 02656 Overlay - TRUE means make the displayed layer Overlayed 02657 FALSE means make the displayed layer non-Overlayed 02658 02659 Returns: - 02660 Purpose: Called when the Overlay button is clicked in a layer gallery item. 02661 Changes the Overlayness of the displayed layer. 02662 02663 Notes: Does not redraw the layer in the display list 02664 02665 ***********************************************************************************************/ 02666 02667 void FrameSGallery::DoChangeOverlay(Layer* pLayer,BOOL Overlay) 02668 { 02669 ERROR3IF(pLayer == NULL,"pLayer == NULL"); 02670 if (pLayer == NULL) return; 02671 02672 BOOL PrevOverlay = pLayer->IsOverlay(); 02673 pLayer->SetOverlay(Overlay); 02674 BOOL PostOverlay = pLayer->IsOverlay(); 02675 02676 //if (PrevOverlay != PostOverlay) 02677 // NodeRenderableInk::DeselectAllOnLayer(pLayer); 02678 02679 if (PrevOverlay != PostOverlay) 02680 { 02681 Spread* pSpread = pLayer->FindParentSpread(); 02682 // Go and fix the status of other layers according to this new setting 02683 FixOtherLayers(pSpread); 02684 02685 // Ensure that the buttons are in the correct state 02686 BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); 02687 } 02688 } 02689 02690 02691 /*********************************************************************************************** 02692 02693 > void FrameSGallery::DoMoveLayer(MoveLayerType Reason) 02694 02695 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Mark N's function in the Layer gallery code) 02696 Created: 16/4/97 (Based on Jason's Layer gallery code) 02697 Inputs: Reason = how the layer should be moved 02698 Returns: - 02699 Purpose: Called when the Locked button is clicked in the layers gallery. 02700 Changes the lockedness of the selected layer, if there is one. 02701 02702 Note: Same as LayerSGallery version but uses FRAME_MOVE 02703 02704 ***********************************************************************************************/ 02705 02706 void FrameSGallery::DoMoveLayer(MoveLayerType Reason) 02707 { 02708 SGDisplayLayer* pLayerGalItem = GetSelectedLayerGalItem(); 02709 02710 if (pLayerGalItem != NULL) 02711 { 02712 OpLayerGalParam Param(FRAME_MOVE, pSpread); 02713 02714 Param.pLayer = pLayerGalItem->GetDisplayedLayer(); 02715 02716 switch (Reason) 02717 { 02718 case (MOVELAYER_UPONE) : 02719 Param.pContextNode = Param.pLayer->FindNextLayer(); 02720 Param.AttDir = NEXT; 02721 break; 02722 02723 case (MOVELAYER_DOWNONE) : 02724 Param.pContextNode = Param.pLayer->FindPrevLayer(); 02725 Param.AttDir = PREV; 02726 break; 02727 02728 default: 02729 ERROR3("Unrecognised MoveLayer reason"); 02730 break; 02731 } 02732 02733 if (Param.pContextNode != NULL) 02734 { 02735 // Redraw after the op if both this layer and the one it's moving in front/behind 02736 // is also visible 02737 Param.MoveRedraw = ((Layer*)Param.pContextNode)->IsVisible() && 02738 Param.pLayer->IsVisible(); 02739 02740 // The above won't work in an undo or redo, so always redraw 02741 Param.MoveRedraw = TRUE; 02742 02743 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_LAYERGALCHANGE); 02744 if (pOpDesc != NULL) 02745 pOpDesc->Invoke((OpParam*)&Param); 02746 else 02747 { 02748 ERROR3("Couldn't find OPTOKEN_LAYERGALCHANGE op descriptor"); 02749 } 02750 } 02751 } 02752 } 02753 02754 /*********************************************************************************************** 02755 02756 > void FrameSGallery::DoShadeGallery(BOOL ShadeIt) 02757 02758 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 02759 Created: 16/4/97 (Based on Jason's Layer gallery code) 02760 Inputs: ShadeIt - TRUE if the gallery is being shaded 02761 FALSE if the gallery is being unshaded 02762 Purpose: Called by the base class whenever the shaded status of the gallery 02763 is changed, to allow derived galleries to shade/unshade any extra 02764 controls that they provide in the window. ONLY called if the gallery 02765 is actually open/visible. 02766 02767 Notes: Need not be overridden - the default action is to do nothing extra 02768 to the normal shade/unshade operation. 02769 SeeAlso: Gallery::ShadeGallery; Gallery::UnshadeGallery 02770 02771 ***********************************************************************************************/ 02772 02773 void FrameSGallery::DoShadeGallery(BOOL ShadeIt) 02774 { 02775 EnableGadget(_R(IDC_GALLERY_UPONE), !ShadeIt); 02776 EnableGadget(_R(IDC_GALLERY_DOWNONE), !ShadeIt); 02777 EnableGadget(_R(IDC_GALLERY_PROPERTIES),!ShadeIt); 02778 EnableGadget(_R(IDC_GALLERY_COPY), !ShadeIt && !IsSelectedItemGuideLayer()); 02779 EnableGadget(_R(IDC_FRAME_DELETE), !ShadeIt); 02780 02781 EnableGadget(_R(IDC_BTN_MULTILAYER), !ShadeIt); 02782 EnableGadget(_R(IDC_BTN_ALLVISIBLE), !ShadeIt); 02783 02784 //EnableGadget(_R(IDC_GALLERY_NAME), !ShadeIt); 02785 02786 EnableGadget(_R(IDC_GALLERY_COPY), !ShadeIt && !IsSelectedItemGuideLayer()); 02787 02788 UpdateFrameRelatedButtons(); 02789 } 02790 02791 02792 /******************************************************************************************** 02793 02794 > virtual BOOL FrameSGallery::InitMenuCommands(void) 02795 02796 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 02797 Created: 16/4/97 (Based on Jason's Layer gallery code) 02798 02799 Returns: TRUE for success 02800 02801 Purpose: Initialises any menu commands that this gallery needs. 02802 02803 Notes: Will only create the menu commands once - further calls in the future 02804 will return TRUE immediately wihtout doing anything. 02805 02806 ********************************************************************************************/ 02807 02808 BOOL FrameSGallery::InitMenuCommands(void) 02809 { 02810 static BOOL MenusInitialised = FALSE; 02811 02812 BOOL ok = TRUE; 02813 02814 if (!MenusInitialised) 02815 { 02816 // Initialise menu command Ops 02817 // "Special" entries for over-list menu 02818 ok = ok && InitMenuCommand((StringBase *) &SGCmd_Copy, _R(IDS_COPYFRAME)); 02819 ok = ok && InitMenuCommand((StringBase *) &SGCmd_Delete, _R(IDS_DELETEFRAME)); 02820 ok = ok && InitMenuCommand((StringBase *) &SGCmd_New, _R(IDS_NEWFRAME)); // _R(IDS_SGMENU_NEW) 02821 // ok = ok && InitMenuCommand((StringBase *) &SGCmd_Animation, _R(IDS_SGMENU_ANIMATION)); 02822 // ok = ok && InitMenuCommand((StringBase *) &SGCmd_Save, _R(IDS_SGMENU_SAVE)); 02823 ok = ok && InitMenuCommand((StringBase *) &SGCmd_Preview, _R(IDS_GRABFRAME)); // _R(IDS_SGMENU_PREVIEW)); 02824 // ok = ok && InitMenuCommand((StringBase *) &SGCmd_Browser, _R(IDS_SGMENU_BROWSER)); 02825 ok = ok && InitMenuCommand((StringBase *) &SGCmd_Properties,_R(IDS_FRAMEPROPERTIES)); //_R(IDS_SGMENU_FRAMEPROPS)); 02826 // ok = ok && InitMenuCommand((StringBase *) &SGCmd_FrameProps,_R(IDS_SGMENU_FRAMEPROPS)); 02827 ok = ok && InitMenuCommand((StringBase *) &SGCmd_Show, _R(IDS_SGMENU_SHOWFRAME)); 02828 MenusInitialised = TRUE; 02829 } 02830 02831 return(ok); 02832 } 02833 02834 02835 02836 /******************************************************************************************** 02837 02838 > virtual BOOL FrameSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID) 02839 02840 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 02841 Created: 16/4/97 (Based on Jason's Layer gallery code) 02842 02843 Inputs: TheMenu - The menu to add commands to 02844 MenuID - The type of menu (over-list or from-options-button) to create 02845 02846 Returns: TRUE if it succeeded 02847 02848 Purpose: To build a menu of commands to be popped up over the gallery. 02849 02850 Notes: The Layer gallery provides only a simple item-pop-up menu 02851 02852 ********************************************************************************************/ 02853 02854 BOOL FrameSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID) 02855 { 02856 BOOL ok = TRUE; 02857 02858 if (MenuID == SGMENU_OVERITEM) 02859 { 02860 // Over-list menu 02861 SGDisplayLayer* pLayerGalItem = GetSelectedLayerGalItem(); 02862 02863 #ifndef STANDALONE 02864 // no layer properties tab present on standalone version 02865 if (pLayerGalItem != NULL) 02866 { 02867 GIFAnimationPropertyTabs * pTabHandler = GIFAnimationPropertyTabsDlg::GetGIFAnimationPropertiesTabs(); 02868 //LayerPropertyTabs * pTabHandler = LayerPropertyTabsDlg::GetLayerPropertiesTabs(); 02869 if (pTabHandler) 02870 { 02871 pTabHandler->SetCurrentLayer(pLayerGalItem->GetDisplayedLayer()); 02872 } 02873 } 02874 #endif 02875 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_New); 02876 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Copy); 02877 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Delete,TRUE); 02878 #ifndef STANDALONE 02879 // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Animation); 02880 // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Save); 02881 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Preview); 02882 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Properties); 02883 // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_FrameProps); 02884 // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Browser); 02885 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Show); 02886 #endif 02887 } 02888 02889 return(ok); 02890 } 02891 02892 02893 02894 /******************************************************************************************** 02895 02896 > virtual OpState FrameSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason) 02897 02898 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 02899 Created: 16/4/97 (Based on Jason's Layer gallery code) 02900 02901 Inputs: CommandID - TheString ID of the command 02902 Outputs: ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled 02903 ion with the reason that the item is shaded/greyed. 02904 02905 Returns: An OpState indicating the current menu item state. 02906 02907 Purpose: To determine the state of a given menu item. This method is an exact 02908 parallel to an Op's GetState method (in fact, it is called by an Op's GetState) 02909 02910 Notes: Override this method to provide state info for your special commands 02911 Call the base class for unknown commands to allow it to handle them for you 02912 02913 The base class handles all of these (maybe more - see the base class help) 02914 Properties, Sort, Find; 02915 New, Edit, Delete, Redefine; 02916 NextGroup, PrevGroup, FoldGroup, UnfoldGroup; 02917 02918 ********************************************************************************************/ 02919 02920 OpState FrameSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason) 02921 { 02922 OpState State; 02923 02924 if (AmShaded) // No commands available while the gallery is shaded 02925 { 02926 State.Greyed = TRUE; 02927 return(State); 02928 } 02929 02930 if (*CommandID == SGCmd_Copy || // --- Copy/Delete/Properties 02931 // *CommandID == SGCmd_Delete || 02932 *CommandID == SGCmd_Show 02933 // *CommandID == SGCmd_Properties || 02934 // *CommandID == SGCmd_Animation || 02935 // *CommandID == SGCmd_Browser || 02936 // *CommandID == SGCmd_FrameProps 02937 ) 02938 { 02939 SGDisplayLayer* pItem = GetSelectedLayerGalItem(); 02940 02941 if (pItem == NULL) 02942 { 02943 State.Greyed = TRUE; 02944 ShadeReason->MakeMsg(_R(IDS_SGSHADE_SINGLECOL)); 02945 } 02946 else if (*CommandID == SGCmd_Copy) // Can't copy Guide layers 02947 State.Greyed = IsSelectedItemGuideLayer(); 02948 else if (*CommandID == SGCmd_Show) // Can't hide Guide layers 02949 { 02950 State.Greyed = IsSelectedItemGuideLayer(); 02951 Layer * pLayer = pItem->GetDisplayedLayer(); 02952 if (pLayer) 02953 State.Ticked = !pLayer->IsHiddenFrame(); 02954 else 02955 State.Greyed = TRUE; 02956 } 02957 /* #ifndef STANDALONE 02958 else if (*CommandID == SGCmd_Properties) // Shade when dlg is open 02959 { 02960 //State.Greyed = (LayerPropertyTabs::GetTabbedDlg() != NULL); 02961 LayerPropertyTabs * pTabHandler = LayerPropertyTabsDlg::GetLayerPropertiesTabs(); 02962 if (pTabHandler) 02963 State.Greyed = (pTabHandler->GetTabbedDlg() != NULL); 02964 else 02965 State.Greyed = TRUE; 02966 } 02967 #endif */ 02968 } 02969 /* #if _DEBUG 02970 else if (*CommandID == SGCmd_Save) 02971 { 02972 // Just call the GetState function for the op directly 02973 return OpSaveAnimatedGIF::GetState(ShadeReason, NULL); 02974 } 02975 #endif */ 02976 else if (*CommandID == SGCmd_Preview) 02977 { 02978 // Just call the GetState function for the op directly 02979 return OpGrabAllFrames::GetState(ShadeReason, NULL); 02980 } 02981 else if (*CommandID == SGCmd_FrameProps || *CommandID == SGCmd_Properties) 02982 { 02983 // Call the GetState function for the frame properties op. 02984 return OpFrameProperties::GetState(ShadeReason, NULL); 02985 } 02986 else if (*CommandID == SGCmd_Delete) 02987 { 02988 // Call the GetState function for the frame delete op. 02989 return OpDeleteFrame::GetState(ShadeReason, NULL); 02990 } 02991 02992 // Don't call the base class 'cos we don't want any other commands 02993 02994 return(State); 02995 } 02996 02997 02998 02999 /******************************************************************************************** 03000 03001 > virtual void FrameSGallery::DoCommand(StringBase *CommandID) 03002 03003 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason's Layer gallery code) 03004 Created: 16/4/97 (Based on Jason's Layer gallery code) 03005 03006 Inputs: CommandID - The String ID of the command 03007 03008 Purpose: To apply a given command when it is chosen from the menu. 03009 03010 Notes: Override this method to provide handling for your special commands. 03011 Call the base class if you don't recognise the command, so that it can 03012 handle standard commands. 03013 03014 The base class handles all of these (maybe more - see the base class help) 03015 Properties, Sort, Find; 03016 New, Edit, Delete, Redefine; (it calls ApplyAction as appropriate) 03017 NextGroup, PrevGroup, FoldGroup, UnfoldGroup; 03018 03019 ********************************************************************************************/ 03020 03021 void FrameSGallery::DoCommand(StringBase *CommandID) 03022 { 03023 if (*CommandID == SGCmd_Copy) 03024 DoCopyLayer(); 03025 else if (*CommandID == SGCmd_New) 03026 DoCreateNewItem(); 03027 else if (*CommandID == SGCmd_Delete) 03028 { 03029 //if (PrepareToDelete()) // No warning on Frame gallery 03030 DoDeleteSelection(); 03031 } 03032 // else if (*CommandID == SGCmd_Properties) 03033 // DoFrameProperties(); 03034 else if (*CommandID == SGCmd_Preview) 03035 { 03036 DoPreviewAnimation(); 03037 } 03038 else if (*CommandID == SGCmd_FrameProps || *CommandID == SGCmd_Properties) 03039 { 03040 // Open the Animation properties dlg with the "Frame properties" page selected. 03041 DoFrameProperties(); 03042 } 03043 else if (*CommandID == SGCmd_Show) 03044 { 03045 // Toggle the state of the show frame in animation flag 03046 SGDisplayLayer* pItem = GetSelectedLayerGalItem(); 03047 Layer * pLayer = NULL; 03048 if (pItem) 03049 pLayer = pItem->GetDisplayedLayer(); 03050 if (pLayer) 03051 { 03052 BOOL CurrentState = pLayer->IsHiddenFrame(); 03053 pLayer->SetHiddenFrame(!CurrentState); 03054 if (pItem) 03055 pItem->ForceRedrawOfMyself(); 03056 03057 // Ensure that the buttons are in the correct state 03058 BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); 03059 } 03060 } 03061 // else if (*CommandID == SGCmd_Save) 03062 // DoSaveAnimation(); 03063 // Implement **** 03064 // *CommandID == SGCmd_Animation 03065 // *CommandID == SGCmd_Browser 03066 03067 // Don't call the base class 'cos we don't want any other commands 03068 } 03069 03070 /*********************************************************************************************** 03071 03072 > virtual BOOL FrameSGallery::DoSaveAnimation() 03073 03074 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03075 Created: 30/4/97 03076 Inputs: - 03077 Returns: True if worked ok, False otherwise 03078 Purpose: Saves out the current animation to file. 03079 03080 ***********************************************************************************************/ 03081 03082 BOOL FrameSGallery::DoSaveAnimation() 03083 { 03084 // Not required at present 03085 /* OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_SAVEANIMATEDGIF); 03086 if (pOpDesc != NULL) 03087 pOpDesc->Invoke(); 03088 else 03089 { 03090 ERROR3("Couldn't find OPTOKEN_FRAME_COPYFRAME op descriptor"); 03091 } 03092 */ 03093 return TRUE; 03094 } 03095 03096 /*********************************************************************************************** 03097 03098 > virtual BOOL FrameSGallery::DoPreviewAnimation() 03099 03100 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03101 Created: 30/4/97 03102 Inputs: - 03103 Returns: True if worked ok, False otherwise 03104 Purpose: Previews the current animation. 03105 03106 ***********************************************************************************************/ 03107 03108 BOOL FrameSGallery::DoPreviewAnimation() 03109 { 03110 // Check to see if the operation is available 03111 // No longer required as the button is hooked into the real op 03112 //String_256 ShadeReason; 03113 //OpState State; 03114 03115 //State = OpGrabAllFrames::GetState(&ShadeReason, NULL); 03116 //if (State.Greyed) 03117 // return FALSE; 03118 03119 // Normally we want to invoke the grab frame, but we will sneak in that 03120 // if the shift key is pressed then we will grab all frames. 03121 OpDescriptor* pOpDesc = NULL; 03122 // Is the shift key pressed? 03123 if (KeyPress::IsAdjustPressed()) 03124 pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABALLFRAMES); 03125 else 03126 pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABFRAME); 03127 03128 if (pOpDesc != NULL) 03129 pOpDesc->Invoke(); 03130 else 03131 { 03132 ERROR3("Couldn't find OPTOKEN_FRAME_GRABFRAME/_GRABALLFRAMES op descriptor"); 03133 } 03134 03135 return TRUE; 03136 } 03137 03138 /*********************************************************************************************** 03139 03140 > BOOL FrameSGallery::DoRegenerateSingleFrame() 03141 03142 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03143 Created: 14/05/97 03144 Inputs: - 03145 Returns: True if worked ok, False otherwise 03146 Purpose: While previewing an animation, if the frame layer properties are changed 03147 we neeed to regenerate the active frame. This function invokes the correct Op. 03148 03149 *************************************************************************************************/ 03150 03151 BOOL FrameSGallery::DoRegenerateSingleFrame() 03152 { 03153 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABFRAME); 03154 GIFAnimationExportParam Param; 03155 if (pOpDesc != NULL) 03156 pOpDesc->Invoke(&Param); 03157 else 03158 { 03159 ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor"); 03160 } 03161 03162 return TRUE; 03163 } 03164 03165 /*********************************************************************************************** 03166 03167 > BOOL FrameSGallery::DoRegenerateFrames() 03168 03169 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03170 Created: 14/05/97 03171 Inputs: - 03172 Returns: True if worked ok, False otherwise 03173 Purpose: While previewing an animation, if the spread properties are changed 03174 we neeed to regenerate the frame layers. 03175 This function invokes the correct Op. 03176 03177 *************************************************************************************************/ 03178 03179 BOOL FrameSGallery::DoRegenerateFrames() 03180 { 03181 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABALLFRAMES); 03182 if (pOpDesc != NULL) 03183 pOpDesc->Invoke(); 03184 else 03185 { 03186 ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor"); 03187 } 03188 03189 return TRUE; 03190 } 03191 03192 03193 /*********************************************************************************************** 03194 03195 > BOOL FrameSGallery::DoFrameProperties() 03196 03197 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03198 Created: 22/5/97 03199 Inputs: - 03200 Returns: True if worked ok, False otherwise 03201 Purpose: Opens the frame properties dlg 03202 03203 ***********************************************************************************************/ 03204 03205 BOOL FrameSGallery::DoFrameProperties() 03206 { 03207 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFANIMPROPERTYTABS); 03208 03209 if (pOpDesc != NULL) 03210 { 03211 // Select the "Frame properties tab". 03212 GIFAnimationPropertyTabsDlg::SetPageToOpen(GIFAnimationPropertyTabs::FramePropertiesTabNumber); 03213 03214 String_256 Str; 03215 OpState State = pOpDesc->GetOpsState(&Str); 03216 if (!State.Greyed) 03217 pOpDesc->Invoke(); 03218 else 03219 { 03220 GIFAnimationPropertyTabs * pTabHandler = GIFAnimationPropertyTabsDlg::GetGIFAnimationPropertiesTabs(); 03221 if (pTabHandler) 03222 { 03223 DialogTabOp* pDlg = pTabHandler->GetTabbedDlg(); 03224 if (pDlg != NULL) 03225 pDlg->Open(); 03226 } 03227 } 03228 } 03229 return TRUE; 03230 } 03231 03232 /*********************************************************************************************** 03233 03234 > BOOL FrameSGallery::UpdateFrameRelatedButtons() 03235 03236 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 03237 Created: 29/5/97 03238 Inputs: - 03239 Returns: True if worked ok, False otherwise 03240 Purpose: Ensures that they buttons on the gallery up to date in their greying/ungreying 03241 status. 03242 03243 ***********************************************************************************************/ 03244 03245 BOOL FrameSGallery::UpdateFrameRelatedButtons() 03246 { 03247 // This is no longer required for the present as we have hooked the buttons 03248 // into the real ops that we have. 03249 03250 // String_256 ShadeReason; 03251 // OpState State; 03252 03253 // State = OpGrabAllFrames::GetState(&ShadeReason, NULL); 03254 // EnableGadget(_R(IDC_BMPGAL_PREVIEW), !State.Greyed); 03255 03256 // State = OpFrameProperties::GetState(&ShadeReason, NULL); 03257 // EnableGadget(_R(IDC_GALLERY_PROPERTIES), !State.Greyed); 03258 03259 return TRUE; 03260 } 03261 03262 /******************************************************************************************** 03263 03264 > BOOL FrameSGallery::CloseFrameGallery() 03265 03266 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03267 Created: 21/10/97 03268 Inputs: - 03269 Returns: TRUE if sucessful, else FALSE. 03270 03271 ********************************************************************************************/ 03272 03273 BOOL FrameSGallery::CloseFrameGallery() 03274 { 03275 String_32 Name(_R(IDS_FRAMEGAL_GALLNAME)); 03276 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(Name); 03277 03278 // Ensure a valid ptr. 03279 if (pDialogBarOp == NULL) 03280 return FALSE; 03281 03282 if (pDialogBarOp->GetRuntimeClass() == CC_RUNTIME_CLASS(FrameSGallery)) 03283 { 03284 GIFAnimationPropertyTabs::SetFrameGalleryOpen(FALSE); 03285 03286 // Toggle the visible state of the gallery window 03287 pDialogBarOp->SetVisibility( FALSE ); 03288 } 03289 else 03290 { 03291 ERROR3("Got the frame gallery but it's not of the LayerSGallery class"); 03292 } 03293 03294 SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFRAMEGALLERY, FALSE); 03295 03296 GIFAnimationPropertyTabs::SetFrameGalleryOpen(FALSE); 03297 03298 // Everything ok. 03299 return TRUE; 03300 } 03301 03302 /******************************************************************************************** 03303 03304 > BOOL FrameSGallery::OpenLayerGallery() 03305 03306 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03307 Created: 21/10/97 03308 Inputs: - 03309 Returns: TRUE if the document is Frame based, else FALSE. 03310 03311 ********************************************************************************************/ 03312 03313 BOOL FrameSGallery::OpenLayerGallery() 03314 { 03315 // Find the OP. for the Layer gallery. 03316 OpDescriptor* OpDesc; 03317 OpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_DISPLAYLAYERGALLERY); 03318 03319 // Ensure we get a ptr to the OP. 03320 if(!OpDesc) 03321 return FALSE; 03322 03323 // ok, now open the layergallery. 03324 OpDesc->Invoke(); 03325 03326 // Lets go back. 03327 return TRUE; 03328 } 03329 03330 03331 /******************************************************************************************** 03332 03333 > BOOL FrameSGallery::IsFrameMode() 03334 03335 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 03336 Created: 21/10/97 03337 Inputs: Pointer to the document. 03338 Returns: TRUE if the document is Frame based, else FALSE. 03339 03340 ********************************************************************************************/ 03341 03342 BOOL FrameSGallery::IsFrameMode(Document* pDoc) 03343 { 03344 ERROR3IF(pDoc == NULL,"pDoc == NULL"); 03345 03346 // flag to determine the document mode. 03347 BOOL FrameMode = FALSE; 03348 03349 // Get a ptr to the selected spread 03350 Spread* pSpread = pDoc->GetSelectedSpread(); 03351 03352 // Ensure a valid spread ptr. 03353 if(pSpread) 03354 { 03355 // Are there any frame layers? 03356 Layer* pFrameLayer = pSpread->FindFirstFrameLayer(); 03357 03358 //If a frame layer exists, then this is an animation doc. 03359 if (pFrameLayer) 03360 FrameMode = TRUE; 03361 } 03362 03363 // return the document mode. 03364 return FrameMode; 03365 } 03366 03367 #endif // EXCLUDE_GALS 03368 03369