// $Id: sgframe.cpp 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // SGFrame.cpp - Frame SuperGallery classes - FrameSGallery and SGDisplayFrame #include "camtypes.h" //#include "app.h" // For GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED] //#include "gallery.h" // For _R(IDC_GALLERY_LISTBOX) //#include "galres.h" //#include "galstr.h" #include "layergal.h" #include "sgdrag.h" #include "sginit.h" #include "sgframe.h" #include "sgmenu.h" //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "layer.h" //#include "markn.h" //#include "resource.h" //#include "barsdlgs.h" //#include "simon.h" #include "sprdmsg.h" //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "dragmgr.h" //#include "docvmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "ccdc.h" // For render-into-dialogue support //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "grnddib.h" #include "guides.h" //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "layerprp.h" #include "layermsg.h" //#include "richard2.h" //#include "andy.h" //#include "prevwres.h" // _R(IDS_FRAMEGAL_FRAMES) _R(IDB_FGAL_OVERLAY) #include "frameops.h" // OPTOKEN_FRAME_DELETEFRAME ... #include "prevwdlg.h" #include "keypress.h" #include "aprps.h" //#include "zordops.h" // OPTOKEN_COMBINELAYERSTOFRAMELAYER #include "progress.h" #include "helpuser.h" //For help button //#include "xshelpid.h" //For help button //#include "helppath.h" void Beep(); #ifndef EXCLUDE_GALS // Implement the dynamic class bits... CC_IMPLEMENT_DYNCREATE(FrameSGallery, LayerSGallery) CC_IMPLEMENT_DYNAMIC(SGFrameGroup, SGLayerGroup) CC_IMPLEMENT_DYNAMIC(SGDisplayFrame, SGDisplayLayer) #else CC_IMPLEMENT_DYNCREATE(FrameSGallery, Operation) #endif // This line mustn't go before any CC_IMPLEMENT_... macros #define new CAM_DEBUG_NEW #ifndef EXCLUDE_GALS /*********************************************************************************************** > SGFrameGroup::SGFrameGroup(SuperGallery *ParentGal, Document *ParentDoc = NULL, Library *ParentLib = NULL, BOOL IsForeground = TRUE); Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: ParentGal - points to the SuperGallery object which 'owns' this node ParentDoc - NULL, or a pointer to the document this group references ParentLib - NULL, or a pointer to the library this group references Purpose: SGFrameGroup constructor. Initialises the Group's parent pointers to point at its parent(s). Note that generally speaking, one of ParentDoc, ParentLib will be NULL, and the other will be non-NULL. Notes: This constructor does nothing - jusat passes the call on to the baseclass constructor of identical proportions. SeeAlso: SGDisplayGroup::SGDisplayGroup ***********************************************************************************************/ SGFrameGroup::SGFrameGroup(SuperGallery *ParentGal, Document *ParentDoc, Library *ParentLib,BOOL IsForeground) : SGLayerGroup(ParentGal, ParentDoc, ParentLib, IsForeground) { Foreground = IsForeground; } /*********************************************************************************************** > virtual BOOL SGFrameGroup::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: See SGDisplayNode::HandleEvent Returns: TRUE if the event was handled successfully FALSE if it was not Purpose: Handles a SuperGallery DisplayTree event Notes: This overrides the SGDisplayNGroup::HandleEvent method, to give a group-type thing which does wierd stuff for layer galleries (i.e. does not fold, and gives column titles in the 'group' display) SeeAlso: SGDisplayGroup::HandleEvent ***********************************************************************************************/ BOOL SGFrameGroup::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo) { // And handle the specific event switch (EventType) { case SGEVENT_REDRAW: { DocRect MyRect(FormatRect); // Rely on cached format info being correct SGRedrawInfo *RedrawInfo = GetRedrawInfo(EventType, EventInfo); if (IMustRedraw(RedrawInfo)) { StartRendering(RedrawInfo, MiscInfo); DocColour Col(192L, 192L, 192L); //128, 128, 128); RedrawInfo->Renderer->SetLineWidth(0); RedrawInfo->Renderer->SetLineColour(RedrawInfo->Transparent); RedrawInfo->Renderer->SetFillColour(Col); RedrawInfo->Renderer->DrawRect(&MyRect); ReadGroupTitle(); // (Re)Cache the title text // Line up above indented items below MyRect.lo.x += IndentWidth + MiscInfo->PixelSize; // Render column titles above the 'locked' and 'invisible' columns DocRect VisibleBtn; DocRect LockedBtn; DocRect SnapBtn; SGDisplayFrame::CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); DrawBitmap(RedrawInfo->Renderer, &VisibleBtn, _R(IDB_FGAL_SOLID)); DrawBitmap(RedrawInfo->Renderer, &LockedBtn, _R(IDB_FGAL_OVERLAY)); // And finally, render the title text MyRect.lo.x += SG_GapBeforeText; // Leave a small gap before text if (MyRect.lo.x < MyRect.hi.x) // If still room left, draw title { RedrawInfo->Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &Col); String_256 NewTitleText; UINT32 IDS = _R(IDS_FRAMEGAL_FRAMES); NewTitleText.MakeMsg(IDS, (TCHAR *)TitleText); RedrawInfo->Renderer->DrawFixedSystemText(&NewTitleText, MyRect); } StopRendering(RedrawInfo, MiscInfo); } // Check if the cliprect overlaps any of our children - if not, then we // can return now, passing the event on quickly without bothering to give // it to our children. if (GetChild() == NULL || !ChildArea.IsIntersectedWith(RedrawInfo->Bounds)) { return(FALSE); } } break; case SGEVENT_MOUSECLICK: // Mouse clicks on this group type are ignored - but we claim them so that the // event is not passed on around the tree unnecessarily. { SGMouseInfo *MouseInfo = GetMouseInfo(EventType, EventInfo); if (FormatRect.ContainsCoord(MouseInfo->Position)) return(TRUE); } break; default: // For all other purposes (formatting etc), let the base class handle the event return(SGDisplayGroup::HandleEvent(EventType, EventInfo, MiscInfo)); break; } // Pass the event on to my children, as appropriate, and return the result return(GiveEventToMyChildren(EventType, EventInfo, MiscInfo)); } // -- Static variables SGDisplayFrame *SGDisplayFrame::LastClickedLayer = NULL; /*********************************************************************************************** > SGDisplayFrame::SGDisplayFrame() Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Purpose: SGDisplayFrame constructor DON'T call this constructor. It ERROR3's. Call the other constructor ***********************************************************************************************/ SGDisplayFrame::SGDisplayFrame() : SGDisplayLayer() { // Let the baseclass handle it } /*********************************************************************************************** > SGDisplayFrame::SGDisplayFrame(Layer *LayerToDisplay) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: LayerToDisplay - The Layer this item will display Purpose: SGDisplayFrame constructor ***********************************************************************************************/ SGDisplayFrame::SGDisplayFrame(Layer *LayerToDisplay) : SGDisplayLayer(LayerToDisplay) { // Let the baseclass handle it } /*********************************************************************************************** > SGDisplayFrame::~SGDisplayFrame() Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Purpose: SGDisplayFrame destructor Notes: Ensures the LastClickedLayer memory is not left pointing at this layer ***********************************************************************************************/ SGDisplayFrame::~SGDisplayFrame() { // Make sure LastClickedLayer pointer is not left in an invalid state if (this == LastClickedLayer) LastClickedLayer = NULL; } /*********************************************************************************************** > virtual void SGDisplayFrame::HandleRedraw(SGRedrawInfo *RedrawInfo, SGFormatInfo *FormatInfo) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: RedrawInfo - The information on the kernel-rendered redraw area FormatInfo - The formatting information structure member variable FormatRect should be set up (before calling this method) to be the rectangle in which to draw this item Purpose: SGDisplayFrame item redraw method - removed from the main HandleEvent method merely to make the code tidier. Scope: private ***********************************************************************************************/ void SGDisplayFrame::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo) { StartRendering(RedrawInfo, MiscInfo); DocRect MyRect(FormatRect); // Get my redraw position from the cached FormatRect RenderRegion *Renderer = RedrawInfo->Renderer; INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1); INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2); Renderer->SetLineWidth(0); Renderer->SetLineColour(RedrawInfo->Transparent); Renderer->SetFillColour(DocColour(191L, 191L, 191L)); // Calculate and redraw the buttons // NOTE: // The buttons are usually blank grey rectangles, or a rectangle with an eye/lock // glyph on them. However, to hint at what the buttons are for, the selected layer // also shows the buttons in a greyed state DocRect VisibleBtn; DocRect LockedBtn; DocRect SnapBtn; CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); // Find out the state of the layer's flags BOOL ActiveAndVisEd = (GetDisplayedLayer()->IsActive() && Layer::ActiveLayerVisibleAndEditable); // BOOL Visible = GetDisplayedLayer()->IsVisible(); // BOOL Locked = GetDisplayedLayer()->IsLocked(); BOOL Guide = GetDisplayedLayer()->IsGuide(); BOOL Solid = GetDisplayedLayer()->IsSolid(); BOOL Overlay = GetDisplayedLayer()->IsOverlay(); BOOL Edited = GetDisplayedLayer()->IsEdited(); Document* pDoc = (Document*)GetDisplayedLayer()->FindOwnerDoc(); ERROR3IF(pDoc == NULL,"Displayed layer doesn't have an owner doc"); if (pDoc == NULL) return; // Draw 'Solid' button (The glyph is "on" when the layer is solid) if (Solid) { //if (!Guide && (ActiveAndVisEd || pDoc->IsAllVisible())) // DrawBitmap(Renderer, &VisibleBtn, _R(IDB_LGAL_TICKFORCED)); //else DrawBitmap(Renderer, &VisibleBtn, _R(IDB_LGAL_TICKON)); } else DrawBitmap(Renderer, &VisibleBtn, _R(IDB_LGAL_TICKOFF)); // Draw 'Overlay' button (Glyph is on if the layer is overlayed) if (Overlay) { // If Solid is on then this is superfluous so render the greyed form if (Solid) DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKFORCED)); else DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKON)); } else { // If Solid is on then this is superfluous so render the greyed form if (Solid) DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKOFFFORCED)); else DrawBitmap(Renderer, &LockedBtn, _R(IDB_LGAL_TICKOFF)); } Layer* pLayer = GetDisplayedLayer(); ERROR3IF(pLayer == NULL, "I'm displaying a NULL layer? Serious screwup has occurred!"); if (pLayer == NULL) return; DocColour Foreground = RedrawInfo->Foreground; DocColour Background = RedrawInfo->Background; DocColour SelForeground = RedrawInfo->SelForeground; DocColour SelBackground = RedrawInfo->SelBackground; // Set up the colours for rendering our text, and fill the background if selected if (Flags.Selected) { // Fill the entire background with the 'selected' colour, so we don't // get gaps between bits of text or uneven rectangles in multiple selections Renderer->SetFillColour(SelBackground); Renderer->DrawRect(&MyRect); Renderer->SetFixedSystemTextColours(&SelForeground,&SelBackground); } else Renderer->SetFixedSystemTextColours(&Foreground, &Background); MyRect.lo.x += SG_GapBeforeText; // Leave a small gap before text begins // And render the text String_256 MyText = pLayer->GetLayerID(); // Find the delay value and add it to the end of the layer/frame name BOOL IsHidden = pLayer->IsHiddenFrame(); if (!IsHidden) { UINT32 FrameDelay = pLayer->GetFrameDelay(); String_256 Delay; Delay.MakeMsg(_R(IDS_FRAMEDELAYFORMAT), FrameDelay); MyText += Delay; } else { String_256 HiddenText(_R(IDS_SHOWFRAMEISHIDDEN)); // (Hidden) MyText += HiddenText; } #ifdef _DEBUG // If the layer is edited then add a star onto it if (pLayer->IsEdited()) MyText += " *"; // DEBUG only so ok #endif Renderer->DrawFixedSystemText(&MyText, MyRect); StopRendering(RedrawInfo, MiscInfo); } /*********************************************************************************************** > void SGDisplayFrame::ChangeRangeState(SGDisplayFrame *Start, SGDisplayFrame *End, BOOL Range, INT32 WhichButton, SGMiscInfo *MiscInfo) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: Start - Points to the node, or start of a range of nodes, to set End - NULL or points to the end of the range Range - TRUE to do a whole range, FALSE to do only the Start node This is used to override the range description. WhichButton - 0 to change VISIBLE state 1 to change LOCKED state 2 to change SNAP state MiscInfo - The usual (see HandleEvent) Purpose: To handle extension-clicks on layers, we set the state of a range of layers rather than just the one clicked. The range usually extends to the layer which was previously clicked. Notes: This scans the sibling list containing Start, and sets the states of all layers it finds between start and end. If End is not found then Start is treated as a single item. Scope: private ***********************************************************************************************/ void SGDisplayFrame::ChangeRangeState(SGDisplayFrame *Start, SGDisplayFrame *End, BOOL Range, INT32 WhichButton, SGMiscInfo *MiscInfo) { ERROR3IF(Start == NULL || MiscInfo == NULL, "Illegal NULL params"); SuperGallery *ParentGallery = GetParentGallery(); ERROR3IF(ParentGallery == NULL, "No parent gallery?! Weird!"); // Determine the new state based on inverting this item's state BOOL NewState = TRUE; switch (WhichButton) { case 0: // Solid state NewState = !(GetDisplayedLayer()->IsSolid()); break; case 1: // Overlayed sate NewState = !(GetDisplayedLayer()->IsOverlay()); break; default: ERROR3("Illegal WhichButton parameter to SGDisplayFrame::ChangeRangeState (must be 0..2)"); break; } // Scan the sibling list to find the start and end nodes, and determine if end comes // before start (in which case we'll need to swap them over before continuing) SGDisplayFrame *Ptr = NULL; if (!Range || End == NULL) End = Start; BOOL FoundStart = FALSE; BOOL FoundEnd = FALSE; BOOL MustSwap = FALSE; Ptr = (SGDisplayFrame *) (Start->GetParent()->GetChild()); while (Ptr != NULL) { if (Ptr == Start) FoundStart = TRUE; if (Ptr == End) { FoundEnd = TRUE; MustSwap = !FoundStart; // If not found Start first, then the range is backwards } Ptr = (SGDisplayFrame *) Ptr->GetNext(); } if (!FoundStart) // Couldn't even find the start node! { ERROR3("Start node not found"); return; } if (!FoundEnd) // No end node? Make the range one item only End = Start; if (MustSwap) // Range is backwards - swap the pointers { Ptr = Start; Start = End; End = Ptr; } // Now scan the list from Start to End, setting all the layers (inclusive) Ptr = Start; while (Ptr != NULL) { DocRect MyRect(Ptr->FormatRect); DocRect VisibleBtn; DocRect LockedBtn; DocRect SnapBtn; Ptr->CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); switch (WhichButton) { case 0: // Visible state // Notify the gif animation property tabs dlg about this state change. // This allows us to sit on the ACTIVE_LAYER_CHANGED message. GIFAnimationPropertyTabs::SetChangeLayerState(TRUE); // Ask the gallery to change the state of the flag Ptr->DoChangeState(LAYER_SOLID, NewState); // Do a redraw so we notice the change ParentGallery->ForceRedrawOfArea(&VisibleBtn); // Set this flag back to false. GIFAnimationPropertyTabs::SetChangeLayerState(FALSE); break; case 1: // Locked state // Notify the gif animation property tabs dlg about this state change. // This allows us to sit on the ACTIVE_LAYER_CHANGED message. GIFAnimationPropertyTabs::SetChangeLayerState(TRUE); // Ask the gallery to change the state of the flag Ptr->DoChangeState(LAYER_OVERLAY, NewState); // Do a redraw so we notice the change ParentGallery->ForceRedrawOfArea(&LockedBtn); // Set this flag back to false. GIFAnimationPropertyTabs::SetChangeLayerState(FALSE); break; } if (Ptr == End) // Slight strangeness to handle (Start==End) case Ptr = NULL; // Have hit and processed End, so stop else Ptr = (SGDisplayFrame *) Ptr->GetNext(); // Have not, so go on to next layer } } /*********************************************************************************************** > virtual BOOL SGDisplayFrame::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: EventType - An enumerated value describing what type of event is to be processed EventInfo - A structure describing the event (may be NULL). The exact thing pointed at by this pointer depends upon the event type: MonoOn Event Thing EventInfo points at SGEVENT_FORMAT (SGFormatInfo *) SGEVENT_REDRAW (SGRedrawInfo *) SGEVENT_MOUSECLICK (SGMouseInfo *) MonoOff Use the provided SGDisplayNode::Get[Format]Info() inlines to retrieve this information - they provide useful error/type checking, and hide the cast MiscInfo - always provided. Contains a few useful bits of info that may be needed for all event types. Outputs: FormatInfo is updated as appropriate Returns: TRUE if the event was handled successfully FALSE if it was not Purpose: Handles a SuperGallery DisplayTree event Notes: This overrides the pure virtual SGDisplayNode::HandleEvent method A node need not handle a specific event - if it does not handle it, it should return FALSE. Redraw and Formatting handlers should never return TRUE, as this will prevent the event from continuing through the tree. Non-leaf-nodes must call SGDisplayNode::GiveEventToMyChildren in order to pass the event dow the tree. THIS node is a leaf-node, so it doesn't. SeeAlso: SGDisplayNode::HandleEvent ***********************************************************************************************/ BOOL SGDisplayFrame::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo) { switch (EventType) { case SGEVENT_FORMAT: { SGFormatInfo *FormatInfo = GetFormatInfo(EventType, EventInfo); CalculateMyRect(FormatInfo, MiscInfo); // Cache our FormatRect for later use } break; case SGEVENT_REDRAW: { DocRect MyRect(FormatRect); // Rely on FormatRect being cached from above SGRedrawInfo *RedrawInfo = GetRedrawInfo(EventType, EventInfo); if (IMustRedraw(RedrawInfo)) // only redraw if we intersect the clip rect HandleRedraw(RedrawInfo, MiscInfo); } break; // exit and return FALSE to pass the redraw event on case SGEVENT_MOUSECLICK: { SGMouseInfo *Mouse = GetMouseInfo(EventType, EventInfo); SuperGallery *ParentGallery = GetParentGallery(); ERROR3IF(ParentGallery == NULL, "No parent gallery?! Weird!"); if (FormatRect.ContainsCoord(Mouse->Position)) { DocRect MyRect(FormatRect); DocRect VisibleBtn; DocRect LockedBtn; DocRect SnapBtn; Document* pDoc = (Document*)GetDisplayedLayer()->FindOwnerDoc(); ERROR2IF(pDoc == NULL,TRUE,"Can't find owner doc for layer"); ERROR2IF(!IS_A(pDoc,Document),TRUE,"Owner doc is not a Document"); Layer* pLayer = GetDisplayedLayer(); ERROR2IF(pLayer == NULL,TRUE,"GetDisplayedLayer() returned NULL"); // Find out the state of the layer's flags BOOL ActiveAndVisEd = (pLayer->IsActive() && Layer::ActiveLayerVisibleAndEditable); //BOOL Visible = pLayer->GetVisibleFlagState(); //BOOL Locked = pLayer->GetLockedFlagState(); BOOL Guide = pLayer->IsGuide(); BOOL Solid = pLayer->IsSolid(); //BOOL Guide = pLayer->IsOverlay(); CalculateButtonRects(MiscInfo, &MyRect, &VisibleBtn, &LockedBtn, &SnapBtn); // Ignore menu clicks on the Visible button if (!Mouse->MenuClick && VisibleBtn.ContainsCoord(Mouse->Position)) { // At present always change the actual setting of the Solid flag if (TRUE) //Guide || (!pDoc->IsAllVisible() && !ActiveAndVisEd)) { ChangeRangeState(this, LastClickedLayer, Mouse->Extend, 0, MiscInfo); // Remember this as the "anchor" layer for extend-click setting of ranges LastClickedLayer = this; // We need to force a redraw of the overlay button as it is dependent // on the locked state ParentGallery->ForceRedrawOfArea(&LockedBtn); } else { UINT32 IDS = _R(IDS_LAYER_NOCHANGE_VISIBLE); if (ActiveAndVisEd) IDS = _R(IDS_LAYER_NOCHANGE_VISIBLE_ACTIVE); String_256 msg(IDS); GetApplication()->UpdateStatusBarText(&msg); Beep(); } break; } // Ignore menu clicks on the Locked button if (!Mouse->MenuClick && LockedBtn.ContainsCoord(Mouse->Position)) { // Only change the actual setting if the Multilayer flag is clear // and it's not the active layer with the 'active layer is visible and edtable' pref on if (!Solid) //!pDoc->IsMultilayer() && !ActiveAndVisEd) { ChangeRangeState(this, LastClickedLayer, Mouse->Extend, 1, MiscInfo); // Remember this as the "anchor" layer for extend-click setting of ranges LastClickedLayer = this; } else { UINT32 IDS = _R(IDS_LAYER_NOCHANGE_OVERLAY); String_256 msg(IDS); GetApplication()->UpdateStatusBarText(&msg); Beep(); } break; } // Only treat clicks as selection clicks if they are to the right of the tick buttons // This is easy, as MyRect excludes the buttons if (MyRect.ContainsCoord(Mouse->Position)) { // In the layer gallery the selection can never be more than one item, // so all clicks are treated like Select clicks. if (!Flags.Selected) { // Make the layer we're displaying the active one Layer* pLayer = GetDisplayedLayer(); FrameSGallery::MakeActiveLayer(pLayer); // Now update the selection states... ParentGallery->SelectItems(FALSE); // Deselect everything else // Repaint the list box now. This is because if there is a large // distance between the old selection and the new one, we get a huge // redraw cliprect, so get a (slow) complete redraw, instead of two // small redraws. It is thus better to break the redraw into 2 steps // so that we are more likely to get 2 fast redraws than one slow one. //ParentGallery->PaintGadgetNow(_R(IDC_GALLERY_LISTBOX)); ParentGallery->PaintListNow(); // And select myself, and the new active layer SetSelected(TRUE); // My selection state has changed, so I'd better redraw myself ForceRedrawOfMyself(); // And inform the parent gallery that the selection has changed, so // it can shade/unshade buttons as appropriate, etc ParentGallery->SelectionHasChanged(); } // Remember this as the "anchor" layer for extend-click setting of ranges LastClickedLayer = this; // Start a drag on the layer item SGListDragInfo* pDragInfo = new SGListDragInfo(ParentGallery,this,Mouse,Mouse->MenuClick); if (pDragInfo != NULL) DragManagerOp::StartDrag(pDragInfo, GetListWindow()); } return(TRUE); // Claim this event - nobody else can own this click } } break; default: // Let the base class handle all unknown/unwanted events return(SGDisplayItem::HandleEvent(EventType, EventInfo, MiscInfo)); } // Default return value: We do not claim this event, so it will be passed on to others return(FALSE); } /*********************************************************************************************** > void SGDisplayFrame::DoChangeState(OpLayerGalReason Reason,BOOL NewState) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: Reason = reason code definiting what 'NewState' represents NewState= boolean that determines the new state of the flag defined by 'Reason' Returns: - Purpose: Called when a flag changes for a layer gallery item Notes: Does not redraw the layer in the display list ***********************************************************************************************/ void SGDisplayFrame::DoChangeState(OpLayerGalReason Reason,BOOL NewState) { FrameSGallery* pGal = (FrameSGallery*)GetParentGallery(); ERROR3IF(!IS_A(pGal,FrameSGallery),"Parent not a frame gallery"); if (!IS_A(pGal,FrameSGallery)) return; Layer* pLayer = GetDisplayedLayer(); pGal->DoChangeLayerState(pLayer,Reason,NewState); } /*********************************************************************************************** > virtual void SGDisplayFrame::MoveLayer(SGDisplayNode *NodeToMove,BOOL Before,BOOL ToggleBackground) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: NodeToMove = the node to move (which specifies the layer to move) Before = if TRUE the layer is moved previous (before) this layer, otherwise the layer is moved next (after) this layer ToggleBacground = TRUE if the background flag should be toggled when moved Purpose: This moves the given layer either before or after this layer, in an undoable way Errors: ERROR3 and quiet exit if NodeToMove == NULL SeeAlso: SuperGallery; SGDisplayNode::MoveAfter; SGDisplayNode::InsertAfter; SGDisplayNode::AddItem Note: Same as LayerSGallery version but uses FRAME_MOVE ***********************************************************************************************/ void SGDisplayFrame::MoveLayer(SGDisplayNode *NodeToMove,BOOL Before,BOOL ToggleBackground) { ERROR3IF(!IS_A(NodeToMove,SGDisplayFrame),"The node to move is not a SGDisplayFrame"); if(!IS_A(NodeToMove,SGDisplayFrame)) return; Layer* pLayerToMove = ((SGDisplayFrame*)NodeToMove)->GetDisplayedLayer(); Layer* pThisLayer = GetDisplayedLayer(); Spread* pSpread = pLayerToMove->FindParentSpread(); ERROR3IF(pSpread == NULL,"Parent spread is NULL"); if (pSpread == NULL) return; OpLayerGalReason Reason; if (pLayerToMove == pThisLayer) { // if the context node and the layer to move are the same, and we don't have to toggle // the background flag, just return (give errors in debug mode) ERROR3IF(!ToggleBackground,"Not moving the layer OR toggling the background flag, so why did you call?"); if (!ToggleBackground) return; Reason = LAYER_TOGGLEBACKGROUND; } else Reason = FRAME_MOVE; OpLayerGalParam Param(Reason,pSpread); Param.pLayer = pLayerToMove; Param.pContextNode = pThisLayer; Param.MoveRedraw = TRUE; Param.ToggleBackground = ToggleBackground; Param.pLayerSGal = (FrameSGallery*)GetParentGallery(); if (Before) Param.AttDir = NEXT; // next means insert-before-this else Param.AttDir = PREV; // prev means insert-after-this OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_LAYERGALCHANGE); if (pOpDesc != NULL) pOpDesc->Invoke((OpParam*)&Param); else { ERROR3("Couldn't find OPTOKEN_LAYERGALCHANGE op descriptor"); } } #endif // EXCLUDE_GALS /******************************************************************************************** /// FrameSGallery ********************************************************************************************/ /******************************************************************************************** > FrameSGallery::FrameSGallery() Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Purpose: FrameSGallery default constructor ********************************************************************************************/ FrameSGallery::FrameSGallery() { #ifndef EXCLUDE_GALS pSpread = NULL; pDoc = NULL; DisplayForeground = NULL; // Group of foreground layers DisplayBackground = NULL; // Group of background layers OldGuideLayerState = -1; NewGuideLayerState = -1; m_NewDocBorn = FALSE; #endif } /******************************************************************************************** > FrameSGallery::~FrameSGallery() Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Purpose: FrameSGallery destructor. ********************************************************************************************/ FrameSGallery::~FrameSGallery() { } #ifndef EXCLUDE_GALS /******************************************************************************************** > void FrameSGallery::CreateNewSubtree(Document *ParentDoc, SGDisplayGroup *ExistingGroup) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: ParentDoc - The document to create a display subtree for ExistingGroup - NULL (creates a new group for this document), or a pointer to the existing group-node for this document (in which case it clears all displayitems from the group and rebuilds it in place - this stops the display group moving around the tree at random!) Purpose: Internal call. This takes the Layer list of the given document and creates a DisplayTree subtree from it. This subtree is then added to the DisplayTree. Note that this does not force a redraw of the list - after making this call, you should also call ForceRedrawOfList Notes: Passing in a NULL parent document pointer results in an ERROR3 - the function returns without doing anything in retail builds SeeAlso: SuperGallery::ForceRedrawOfList ********************************************************************************************/ void FrameSGallery::CreateNewSubtree(Document *ParentDoc, SGDisplayGroup *ExistingGroup) { if (DisplayTree == NULL) return; TRACEUSER( "Neville", _T("FrameSGallery::CreateNewSubtree Just about to DestroySubtree\n")); // The layer gallery only ever shows one document, so destroy the entire tree // and start again from scratch (note that this doesn't destroy the root node) DisplayTree->DestroySubtree(); // All groups will be destroyed by DestroySubtree(), so we'd better forget them DisplayForeground = NULL; TRACEUSER( "Neville", _T("FrameSGallery::CreateNewSubtree completed DestroySubtree\n")); if (ParentDoc == NULL) return; SGDisplayFrame *DisplayLayer = NULL; EnsureActiveLayerIntegrity(); // Create the foreground layer group DisplayForeground = new SGFrameGroup(this, ParentDoc,NULL,TRUE); // Create new Group if (DisplayForeground == NULL) // Total failure - abort return; DisplayTree->AddItem(DisplayForeground); // Add new group to tree Spread* pSelSpread = GetSelectedSpread(); ERROR3IF(pSelSpread == NULL,"No selected spread in FrameSGallery"); if (pSelSpread == NULL) return; Layer* pLayer = pSelSpread->FindLastLayer(); Layer* pActiveLayer = NULL; Layer* pGuideLayer = NULL; BOOL SetActiveLayer = FALSE; // Only Webster needs to show a dummy frame layer #ifdef WEBSTER Layer* pSingleNonFrameLayer = NULL; BOOL ShownSingleNonFrameLayer = FALSE; #endif // WEBSTER while (pLayer != NULL) { // If we find a guide layer then note that for future use if (pLayer->IsGuide()) { pGuideLayer = pLayer; } else if ( (pLayer->IsPseudoFrame() && pLayer->IsFrame()) // its a proper frame layer #ifdef WEBSTER || (pLayer->IsPseudoFrame() && !ShownSingleNonFrameLayer) // its a potential frame layer #endif // WEBSTER ) { #ifdef WEBSTER // If its not a frame layer then note that we have added our single // non-frame layer in. if (!pLayer->IsFrame()) { ShownSingleNonFrameLayer = TRUE; pSingleNonFrameLayer = pLayer; } #endif // WEBSTER // Only add foreground layers and non-guide layers DisplayLayer = new SGDisplayFrame(pLayer); if (DisplayLayer != NULL) { // Always add to the foreground layers DisplayForeground->AddItem(DisplayLayer); if (pLayer->IsActive()) { ERROR3IF(pActiveLayer != NULL,"Found more than one active layer in the selected spread"); pActiveLayer = pLayer; DisplayLayer->SetSelected(TRUE); // Make the active layer selected SetActiveLayer = TRUE; // Note this fact } } } pLayer = pLayer->FindPrevLayer(); } // If we have not set a selected layer then this is very bad if (!SetActiveLayer) { TRACEUSER( "Neville", _T("Active layer is not a frame layer so force it!\n")); Layer * pNewActiveLayer = pSpread->FindLastFrameLayer(); #ifdef WEBSTER if (pNewActiveLayer == NULL && pSingleNonFrameLayer != NULL) pNewActiveLayer = pSingleNonFrameLayer; #else // ERROR3IF(pNewActiveLayer == NULL,"No current active frame layer"); #endif // WEBSTER // If we have an active layer, ensure that it really is the one and only active layer if (pNewActiveLayer != NULL) { // Search for the new display item to match this new active layer SGDisplayLayer *pWantedDispLayer = NULL; SGDisplayLayer *pDispLayer = ((SGDisplayLayer *) DisplayForeground->GetChild()); while (pDispLayer != NULL) { if (pDispLayer->GetDisplayedLayer() == pNewActiveLayer) pWantedDispLayer = pDispLayer; pDispLayer = ((SGDisplayLayer *)pDispLayer->GetNext()); } // If we found the required display item then go and select it if (pWantedDispLayer) { // Now update the selection states... SelectItems(FALSE); // Deselect everything else // Something has changed so we must go and select this new item pWantedDispLayer->SetSelected(TRUE); } // As this can only happen when we have a frame layer which is not active // e.g. import a non-frame xar/web document into a non-frame document // we must use the layer form of MakeActiveLayer so that the visibility of // layers is not affected. LayerSGallery::MakeActiveLayer(pNewActiveLayer); //FrameSGallery::MakeActiveLayer(pNewActiveLayer); } } // The new state of the Guide Layer is now the old state OldGuideLayerState = NewGuideLayerState; if (pGuideLayer == NULL) NewGuideLayerState = -1; // If there's no guide layer, set new state to be -1 else NewGuideLayerState = pGuideLayer->IsVisible(); // New state is based on the guide layer's visibility if (IsVisible()) { SetBoolGadgetSelected(_R(IDC_BTN_MULTILAYER),!(ParentDoc->IsMultilayer() == 0)); SetBoolGadgetSelected(_R(IDC_BTN_ALLVISIBLE),!(ParentDoc->IsAllVisible() == 0)); } TRACEUSER( "Neville", _T("FrameSGallery::CreateNewSubtree exit\n")); } /******************************************************************************************** > BOOL FrameSGallery::PostCreate(void) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Returns: TRUE if the Gallery initialised successfully FALSE if it should not be opened due to a failure to initialise Purpose: The FrameSGallery PostCreate handler. This overrides the base class PostCreate function. It is called at the very end of the SuperGallery::Create method, after the window has been created and opened. ********************************************************************************************/ BOOL FrameSGallery::PostCreate(void) { Document *ParentDoc = Document::GetSelected(); if (ParentDoc != NULL) { SetBoolGadgetSelected(_R(IDC_BTN_MULTILAYER),!(ParentDoc->IsMultilayer() == 0)); SetBoolGadgetSelected(_R(IDC_BTN_ALLVISIBLE),!(ParentDoc->IsAllVisible() == 0)); } EnableGadget(_R(IDC_GALLERY_COPY),ParentDoc != NULL && !IsSelectedItemGuideLayer()); UpdateFrameRelatedButtons(); return(TRUE); } /******************************************************************************************** > virtual BOOL FrameSGallery::ApplyAction(SGActionType Action) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: Action - Indicates what action to apply Returns: TRUE to indicate successful handling of the action, or FALSE to indicate failure Purpose: Applies certain conventional gallery actions (usually associated with gallery buttons, for new, edit, delete, etc) SeeAlso: SGActionType ********************************************************************************************/ BOOL FrameSGallery::ApplyAction(SGActionType Action) { // No display tree? Better forget about it then! if (DisplayTree == NULL) return(FALSE); // Determine useful info - this is usually needed for most actions, so always get it Document *SelectedDoc = Document::GetSelected(); SGDisplayGroup *DocumentGroup = DisplayTree->FindSubtree(this, SelectedDoc, NULL); SGDisplayFrame *FirstSelected = NULL; if (DocumentGroup != NULL) FirstSelected = (SGDisplayFrame *) DocumentGroup->FindNextSelectedItem(NULL); // Now, process the action TO DO! - see Colour gallery for examples switch(Action) { case SGACTION_CREATE: DoCreateNewItem(); break; case SGACTION_EDIT: DoChangeName(); break; case SGACTION_DELETE: //if (PrepareToDelete()) // No warning on Frame gallery DoDeleteSelection(); break; // case SGACTION_APPLY: // case SGACTION_REDEFINE: // case SGACTION_DISPLAYMODECHANGED: // These operations are not provided by the layer gallery // break; default: return(SuperGallery::ApplyAction(Action)); } return(TRUE); } /******************************************************************************************** > virtual MsgResult FrameSGallery::Message(Msg* Message) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: Message - The message to handle Purpose: A standard message handler, really. Notes: Any messages that this does not handle must be passed down to the SuperGallery base class message handler. NOTE WELL that the SuperGallery base class handler does some funky things for us - see SuperGallery::Message - such as deleting our display subtree for any document which dies (which, uncannily, would explain why they go away like that when you close documents ;-), and shading the gallery when there are no documents present. [To override this behaviour in these cases, you should respond to the message, and return OK rather than calling the base class message handler] SeeAlso: SuperGallery::Message ********************************************************************************************/ MsgResult FrameSGallery::Message(Msg* Message) { if (IS_OUR_DIALOG_MSG(Message)) { DialogMsg* Msg = (DialogMsg*)Message; switch (Msg->DlgMsg) { case DIM_CREATE: SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFRAMEGALLERY, TRUE); break; case DIM_CANCEL: SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFRAMEGALLERY, FALSE); break; } } // If we have no displaytree, then we have not been shown, or something terrible has // happened, so we don't bother handling any of these messages. if (DisplayTree == NULL) return(SuperGallery::Message(Message)); if (IS_OUR_DIALOG_MSG(Message)) { DialogMsg* Msg = (DialogMsg*)Message; INT32 state; switch (Msg->DlgMsg) { case DIM_LFT_BN_CLICKED: //TRACE( _T("Gadget %d clicked\n"),Msg->GadgetID); switch(Msg->GadgetID) { case _R(IDC_BTN_MULTILAYER): state = GetLongGadgetValue(_R(IDC_BTN_MULTILAYER),0,1); DoChangeLayerState(NULL,FRAME_MULTILAYER,state); break; case _R(IDC_BTN_ALLVISIBLE): state = GetLongGadgetValue(_R(IDC_BTN_ALLVISIBLE),0,1); DoChangeLayerState(NULL,FRAME_ALLVISIBLE,state); break; case _R(IDC_GALLERY_UPONE): DoMoveLayer(MOVELAYER_UPONE); break; case _R(IDC_GALLERY_DOWNONE): DoMoveLayer(MOVELAYER_DOWNONE); break; case _R(IDC_GALLERY_NEW_NODLG): DoCreateNewItem(); break; case _R(IDC_GALLERY_COPY_NODLG): DoCopyLayer(); break; case _R(IDC_GALLERY_HELP): // Show help page HelpUserTopic(_R(IDS_HELPPATH_Gallery_Frame)); break; /* case _R(IDC_GALLERY_PROPERTIES): // Handled by optoken DoFrameProperties(); break; */ /* case _R(IDC_BMPGAL_SAVE): // Handled by optoken DoSaveAnimation(); break; */ /* case _R(IDC_BMPGAL_PREVIEW): // Handled by optoken DoPreviewAnimation(); break; */ /* case _R(IDC_FRAME_ANIMATION): // Handled by optoken // Implement **** break; */ } break; } } else if (MESSAGE_IS_A(Message, OpMsg)) { switch (((OpMsg*)Message)->MsgType) { case OpMsg::AFTER_UNDO: case OpMsg::AFTER_REDO: EnsureSelSpreadSelectionIntegrity(); break; } } else if (MESSAGE_IS_A(Message, SpreadMsg)) { SpreadMsg* pSpreadMsg = (SpreadMsg*) Message; switch (pSpreadMsg->Reason) { case SpreadMsg::SELCHANGED: NewSelectedSpread(pSpreadMsg->pNewSpread); // gets selected doc too if (pDoc != NULL && IsVisible()) { TRACEUSER( "Neville", _T("frame SpreadMsg::SELCHANGED CreateNewSubtree\n")); CreateNewSubtree(pDoc); ForceRedrawOfList(); } break; case SpreadMsg::LAYERCHANGES: if (IsVisible()) { if (pSpreadMsg->pNewSpread == pSpread) { if (pSpread->FindFirstLayer() != NULL) { EnsureActiveLayerIntegrity(); if (pDoc != NULL && IsVisible()) { TRACEUSER( "Neville", _T("frame SpreadMsg::LAYERCHANGES CreateNewSubtree\n")); CreateNewSubtree(pDoc); ForceRedrawOfList(); } } } } else { if (pSpreadMsg->pNewSpread->FindFirstLayer() != NULL) { pSpread = pSpreadMsg->pNewSpread; EnsureActiveLayerIntegrity(); } } break; } } else if (MESSAGE_IS_A(Message, DocChangingMsg)) { DocChangingMsg *Msg = (DocChangingMsg *) Message; switch (Msg->State) { case DocChangingMsg::DocState::TITLECHANGED: { // Showstopper removed, Jason, 28/3/96 // When the doc title changes, we simply need to redraw to update the group titles. // Calling CreateNewSubtree will destroy the existing tree - this is really really bad // when the document title changed as a result of us (e.g.) locking a layer, because the // message broadcats hits us while we're still in the middle of traversing the tree, // we then delete the tree out from under ourselves, and are then in a highly dodgy state! // CreateNewSubtree(Msg->pChangingDoc); ForceRedrawOfList(); break; } // This message is sent when a new or just opened document is stable. case DocChangingMsg::DocState::SELCHANGED: { if (Msg->pNewDoc == NULL) { // No documents around any more, so we must wipe the display tree // The base class will shade the gallery for us. TRACEUSER( "Neville", _T("frame DocChangingMsg CreateNewSubtree\n")); CreateNewSubtree(NULL); ForceRedrawOfList(); } else { #ifdef WEBSTER // There is an active document, so ensure the gallery is unshaded ShadeGallery(FALSE); #else //Do not process the message if it has been sent due to the creation of a new document. if (!GetNewDocBorn()) { // The document has changed, do we detect any non-frame layers? BOOL FrameMode = FALSE; // Get a ptr to the document. Document* pDoc = Msg->pNewDoc; // Ensure a valid ptr. if(pDoc) { // Determine the document mode. FrameMode = IsFrameMode(pDoc); // If we are no longer in Frame mode and the frame gallery is open, // then close the frame gallery and open the layer gallery. if( !FrameMode && IsVisible() ) { // Close the frame gallery. if(CloseFrameGallery()) { // Open the the layer gallery. OpenLayerGallery(); } } } } // If the gallery is visible, then ensure the gallery is unshaded. if(IsVisible()) { // There is an active document, so ensure the gallery is unshaded ShadeGallery(FALSE); } #endif } break; } #ifndef WEBSTER case DocChangingMsg::DocState::BORN: { // When a new document is created, a SELCHANGED // message is broadcasted, for Camelot2 frame/layer integration // we do not wish to process the message. // We therefore set this flag to notify us when a new document // is born. // Ensure the frame gallery is open. if( IsVisible() ) { // Set the flag to true. // This is set to false in BORNANDSTABLE. SetNewDocBorn(TRUE); } break; } case DocChangingMsg::DocState::BORNANDSTABLE: { // The document has changed, do we detect any non-frame layers? BOOL FrameMode = FALSE; BOOL GalleryClosed = FALSE; // Get a ptr to the document. Document* pChangingDoc = Msg->pChangingDoc; // Ensure a valid ptr. if(pChangingDoc) { // Determine the document mode. FrameMode = IsFrameMode(pChangingDoc); // If we are no longer in Frame mode then // close the frame gallery and open the layer gallery. if( !FrameMode && IsVisible() ) { // Close the frame gallery. if(CloseFrameGallery()) { // Open the Layer gallery. OpenLayerGallery(); // Now we have processed this message, it is safe to process SELCHANGED messages. SetNewDocBorn(FALSE); } } } break; } case DocChangingMsg::DocState::KILLED: case DocChangingMsg::DocState::ABOUTTODIE: { // The doc. is about to die, therefore, set this falg to false. SetNewDocBorn(FALSE); break; } #endif } } else if (MESSAGE_IS_A(Message, DocViewMsg)) { DocViewMsg *Msg = (DocViewMsg *) Message; switch (Msg->State) { case DocViewMsg::DocViewState::SELABOUTTOCHANGE: OldGuideLayerState = GetGuideLayerState(Msg->pNewDocView); break; case DocViewMsg::DocViewState::SELCHANGED: { if (IsVisible()) { NewGuideLayerState = GetGuideLayerState(Msg->pNewDocView); if (OldGuideLayerState != NewGuideLayerState) { TRACEUSER( "Neville", _T("frame DocViewMsg::DocViewState::SELCHANGED CreateNewSubtree\n")); CreateNewSubtree(Msg->pNewDocView->GetDoc()); ForceRedrawOfList(); } } } break; } } else if (MESSAGE_IS_A(Message, LayerMsg)) { LayerMsg *pMsg = (LayerMsg *) Message; switch ( pMsg->Reason ) { // The active layer has changed. case LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED: { EnableGadget(_R(IDC_GALLERY_COPY),pMsg->pNewLayer != NULL && !pMsg->pNewLayer->IsGuide()); UpdateFrameRelatedButtons(); } break; // The active layer has been changed externally to the gallery. case LayerMsg::LayerReason::UPDATE_ACTIVE_LAYER: { // We must now check whether the selected layer has been changed externally // to us. May happen if an animated GIF is being loaded onto layers SGDisplayLayer *pDisplayItem = NULL; if (DisplayForeground != NULL && IsVisible()) pDisplayItem = GetSelectedLayerGalItem(); if (pDisplayItem != NULL) { if (pMsg->pNewLayer != NULL && pDisplayItem->GetDisplayedLayer() != pMsg->pNewLayer) { Layer* pNewActiveLayer = pMsg->pNewLayer; // Search for the new display item to match this new active layer SGDisplayLayer *pWantedDispLayer = NULL; SGDisplayLayer *pDispLayer = ((SGDisplayLayer *) DisplayForeground->GetChild()); while (pDispLayer != NULL) { if (pDispLayer->GetDisplayedLayer() == pNewActiveLayer) pWantedDispLayer = pDispLayer; pDispLayer = ((SGDisplayLayer *)pDispLayer->GetNext()); } // If we found the required display item then go and select it if (pWantedDispLayer) { // Now update the selection states... SelectItems(FALSE); // Deselect everything else // Something has changed so we must go and select this new item pWantedDispLayer->SetSelected(TRUE); } } } } break; // The specified layer has been changed externally to the gallery. // So redraw the name. case LayerMsg::LayerReason::REDRAW_LAYER: { TRACEUSER( "Neville", _T("frame LayerMsg::LayerReason::REDRAW_LAYER\n")); Layer * pWantedLayer = pMsg->pNewLayer; if (pWantedLayer != NULL && DisplayForeground != NULL && IsVisible()) { // Search for the new display item to match this new active layer SGDisplayLayer *pWantedDispLayer = NULL; SGDisplayLayer *pDispLayer = ((SGDisplayLayer *) DisplayForeground->GetChild()); while (pDispLayer != NULL) { if (pDispLayer->GetDisplayedLayer() == pWantedLayer) pWantedDispLayer = pDispLayer; pDispLayer = ((SGDisplayLayer *)pDispLayer->GetNext()); } // If we found it then force a redraw if (pWantedDispLayer) pWantedDispLayer->ForceRedrawOfMyself(); } } break; } } return(SuperGallery::Message(Message)); } /*********************************************************************************************** > void FrameSGallery::EnsureSelSpreadSelectionIntegrity() Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Purpose: This makes sure that all the invisible and/or locked layers in the spread have no selection. It calls NodeRenderableInk::DeselectAllOnLayer() on each layer that should NOT have a selection, just in case. Currently only called after an undo or redo op, because it could be quite slow ***********************************************************************************************/ void FrameSGallery::EnsureSelSpreadSelectionIntegrity() { if (pSpread == NULL) return; // Get the first layer in the spread Layer* pLayer = pSpread->FindFirstLayer(); while (pLayer != NULL) { // If the layer is not visible OR the layer is locked, make sure there is no selection if (!pLayer->IsVisible() || pLayer->IsLocked()) NodeRenderableInk::DeselectAllOnLayer(pLayer); pLayer = pLayer->FindNextLayer(); } } #endif // EXCLUDE_GALS /*********************************************************************************************** > static void FrameSGallery::SetActive(Document* pDoc,Layer* pLayer,BOOL state) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: pDoc = ptr to doc containing layer pLayer = ptr that contains this layer state = TRUE means make active, FALSE means make inactive Outputs: - Returns: - Purpose: Calls pLayer->SetActive(state), redrawing and changing the layer's selection if necessary. DON'T CALL THIS FUNC!! USE MakeActiveLayer() INSTEAD!!!! ***********************************************************************************************/ void FrameSGallery::SetActive(Document* pDoc,Layer* pLayer,BOOL state) { // This flag is TRUE if the selection on the layer should be cleared BOOL ClearSelection = FALSE; // get state before active change BOOL PrevVisibleState = pLayer->IsVisible(); BOOL PrevLockedState = pLayer->IsLocked(); // Change active state pLayer->SetActive(state); // get state after active change BOOL PostVisibleState = pLayer->IsVisible(); BOOL PostLockedState = pLayer->IsLocked(); if (PrevVisibleState != PostVisibleState) { // If the visible state has changed, redraw the layer FrameSGallery::ForceRedrawLayer(pDoc,pLayer); // If it has just become invisible, clear the selection ClearSelection = (ClearSelection || !PostVisibleState); } // if it has just become locked, clear the selection if (PrevLockedState != PostLockedState) ClearSelection = (ClearSelection || PostLockedState); // Clear the selection if needed if (ClearSelection) NodeRenderableInk::DeselectAllOnLayer(pLayer); } /*********************************************************************************************** > static void FrameSGallery::MakeActiveLayer(Layer* pNewActiveLayer, UndoableOperation * pUndoOp = NULL) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: pNewActiveLayer = ptr to the layer you want to be active pUndoOp = if non null, the default, will do the change undoably Outputs: - Returns: - Purpose: Makes the layer active. Firstly it will inactivate any other active layers, forcing it to redraw if necessary Then it will set this layer to be active, again forcing a redraw if necessary If the given new layer is already active, nothing happens Note: pNewActiveLayer must be in the currect doc ***********************************************************************************************/ void FrameSGallery::MakeActiveLayer(Layer* pNewActiveLayer, UndoableOperation * pUndoOp) { Spread* pSpread = pNewActiveLayer->FindParentSpread(); ERROR3IF(pSpread == NULL,"Eh up, the layer has no parent spread"); if (pSpread == NULL) return; Document *pDoc = pSpread->FindParentDocument(); if (pDoc == NULL) return; { // Remove any other active layers, redrawing if necessary. Layer* pLayer = pSpread->FindFirstLayer(); while (pLayer != NULL) { if (pLayer->IsActive() && pLayer != pNewActiveLayer) { if (pUndoOp == NULL) FrameSGallery::SetActive(pDoc,pLayer,FALSE); else { // Make layer active undoably OpLayerGalParam Param(LAYER_ACTIVE, pSpread); Param.NewState = FALSE; Param.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } } pLayer = pLayer->FindNextLayer(); } } // Go though the layers from the new active layer downwards and set // all previous layers non-visible and non-selected FixOtherLayersFromActive(pNewActiveLayer, pUndoOp); // Make sure the new layer is active, redrawing if necessary /* if (!pNewActiveLayer->IsActive()) { if (pUndoOp == NULL) FrameSGallery::SetActive(pDoc,pNewActiveLayer,TRUE); else { // Make layer active undoably OpLayerGalParam Param(LAYER_ACTIVE, pSpread); Param.NewState = TRUE; Param.pLayer = pNewActiveLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } } */ if (pUndoOp == NULL) { if (!pNewActiveLayer->IsActive()) FrameSGallery::SetActive(pDoc,pNewActiveLayer,TRUE); } else { // Make layer active undoably OpLayerGalParam Param(LAYER_ACTIVE, pSpread); Param.NewState = TRUE; Param.pLayer = pNewActiveLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } #if defined(EXCLUDE_FROM_RALPH) //ERROR3("FrameSGallery::MakeActiveLayer supressed broadcast - bad !"); #else BROADCAST_TO_ALL(LayerMsg(pNewActiveLayer,LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); #endif } /*********************************************************************************************** > static void FrameSGallery::FixOtherLayers() Author: Neville_Humphrys (Xara Group Ltd) Created: 17/4/97 Inputs: pSpread = ptr to spread Outputs: - Returns: - Purpose: A layer flag such as overlay or solid has been changed and so we need to go and find the active layer and ensure that the other layers above and below this have the correct visibility and locked settings. ***********************************************************************************************/ void FrameSGallery::FixOtherLayers(Spread* pSpread) { // Check that the class variable storing the current/selected spread is ok if (pSpread == NULL) return; // Get the first layer in the spread Layer* pFirstLayer = pSpread->FindFirstLayer(); // Not found an active layer yet Layer* pActiveLayer = NULL; // Start the search from the first layer Layer* pLayer = pFirstLayer; while (pLayer != NULL && pActiveLayer == NULL) { if (pLayer->IsActive()) pActiveLayer = pLayer; // Found the active layer, so make a note of it pLayer = pLayer->FindNextLayer(); } if (pActiveLayer) FixOtherLayersFromActive(pActiveLayer); } /*********************************************************************************************** > static void FrameSGallery::FixOtherLayersFromActive(Layer * pActiveLayer, UndoableOperation * pUndoOp = NULL) Author: Neville_Humphrys (Xara Group Ltd) Created: 17/4/97 Inputs: pActiveLayer = the current active layer pUndoOp = if non null, the default, will do the change undoably Purpose: A layer flag such as overlay or solid has been changed and so we need take the passed in current active layer and then ensure that the other layers above and below this have the correct visibility and locked settings. ***********************************************************************************************/ void FrameSGallery::FixOtherLayersFromActive(Layer * pActiveLayer, UndoableOperation * pUndoOp) { // This might be the new active layer that we are setting and so // it might not have been made active yet! if (pActiveLayer == NULL) // || !pActiveLayer->IsActive()) { ERROR3("FixOtherLayersFromActive has been given a bad active layer!"); return; } // Only need a spread pointer in the undoable case Spread * pSpread = NULL; if (pUndoOp != NULL) pSpread = pActiveLayer->FindParentSpread(); // Ensure that the new active layer is going to be visible and unlocked // Assume code is called from make active code which will force the redraw // and selection changes as required. So do it the simple way if (pUndoOp == NULL || pSpread == NULL) { LayerSGallery::DoChangeVisible(pActiveLayer,TRUE); LayerSGallery::DoChangeLocked(pActiveLayer,FALSE); } else { // Make visible and locked // Only change if required as otherwise we will get an unwanted undo step // if (!pActiveLayer->IsVisible()) { OpLayerGalParam Param(LAYER_VISIBLE, pSpread); Param.NewState = TRUE; Param.pLayer = pActiveLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } // Only change if required as otherwise we will get an unwanted undo step // if (pActiveLayer->IsLocked()) { OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); LockedParam.NewState = FALSE; LockedParam.pLayer = pActiveLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); } } // Go though the layers from the new active layer downwards and set // all previous layers non-visible and non-selected Layer* pLayer = pActiveLayer->FindPrevLayer(); BOOL FoundSolid = pActiveLayer->IsSolid(); BOOL OverlayPrevious = FALSE; // Solid flag overrides the overlay flag if (!FoundSolid) OverlayPrevious = pActiveLayer->IsOverlay(); while (pLayer != NULL) { if (pLayer->IsPseudoFrame()) { if (pLayer->IsSolid() && !FoundSolid) { // Stop any later solid frames having any effect FoundSolid = TRUE; // Stop any overlay having an effect OverlayPrevious = FALSE; if (pUndoOp == NULL || pSpread == NULL) { LayerSGallery::DoChangeVisible(pLayer,TRUE); LayerSGallery::DoChangeLocked(pLayer,TRUE); } else { // Only change if required as otherwise we will get an unwanted undo step // if (!pLayer->IsVisible()) { OpLayerGalParam Param(LAYER_VISIBLE, pSpread); Param.NewState = TRUE; Param.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } // Only change if required as otherwise we will get an unwanted undo step // if (!pLayer->IsLocked()) { OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); LockedParam.NewState = TRUE; LockedParam.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); } } } else { BOOL NewVisibleState = TRUE; if (OverlayPrevious) NewVisibleState = TRUE; else NewVisibleState = FALSE; if (pUndoOp == NULL || pSpread == NULL) { LayerSGallery::DoChangeVisible(pLayer,NewVisibleState); LayerSGallery::DoChangeLocked(pLayer,TRUE); } else { // Only change if required as otherwise we will get an unwanted undo step // if (pLayer->IsVisible() != NewVisibleState) { OpLayerGalParam Param(LAYER_VISIBLE, pSpread); Param.NewState = NewVisibleState; Param.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } // Only change if required as otherwise we will get an unwanted undo step // if (!pLayer->IsLocked()) { OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); LockedParam.NewState = TRUE; LockedParam.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); } } // If we are currently overlaying and this frame // is overlay as well then keep overlay on, otherwise // turn it off. if (OverlayPrevious && pLayer->IsOverlay()) OverlayPrevious = TRUE; else OverlayPrevious = FALSE; } // Overlay should only affect the previous frame //if (!pLayer->IsSolid() && pLayer->IsOverlay()) // OverlayPrevious = TRUE; //else // OverlayPrevious = FALSE; } pLayer = pLayer->FindPrevLayer(); } // Go though the layers from the new active layer upwards and set // all layers above to be non-visible and non-selected pLayer = pActiveLayer->FindNextLayer(); while (pLayer != NULL) { if (pLayer->IsPseudoFrame()) { if (pUndoOp == NULL || pSpread == NULL) { LayerSGallery::DoChangeVisible(pLayer,FALSE); LayerSGallery::DoChangeLocked(pLayer,TRUE); } else { // Only change if required as otherwise we will get an unwanted undo step // if (pLayer->IsVisible()) { OpLayerGalParam Param(LAYER_VISIBLE, pSpread); Param.NewState = FALSE; Param.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), Param); } // Only change if required as otherwise we will get an unwanted undo step // if (!pLayer->IsLocked()) { OpLayerGalParam LockedParam(LAYER_LOCKED, pSpread); LockedParam.NewState = TRUE; LockedParam.pLayer = pLayer; LayerStateAction::Init(pUndoOp, pUndoOp->GetUndoActions(), LockedParam); } } } pLayer = pLayer->FindNextLayer(); } } /*********************************************************************************************** > static void FrameSGallery::EnsureActiveLayerIntegrity(Spread* pSpread,Layer** ppActiveLayer = NULL) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: pSpread = ptr to spread Outputs: - Returns: - Purpose: This checks that there is one and only one active layer in the given spread. If there isn't an active layer, the first layer is made active. If there is more than on active layer, all but the first active layer are made inactive. ***********************************************************************************************/ /* void FrameSGallery::EnsureActiveLayerIntegrity(Spread* pSpread,Layer** ppActiveLayer) { if (pSpread == NULL) return; // Get the first layer in the spread Layer* pFirstLayer = pSpread->FindFirstLayer(); // Not found an active layer yet Layer* pActiveLayer = NULL; // Start the search from the first layer Layer* pLayer = pFirstLayer; while (pLayer != NULL && pActiveLayer == NULL) { if (pLayer->IsActive()) pActiveLayer = pLayer; // Found the active layer, so make a note of it pLayer = pLayer->FindNextLayer(); } // If we haven't found any active layers, make the last (top) one active if (pActiveLayer == NULL) pActiveLayer = pSpread->FindLastLayer(); // If we have an active layer, ensure that it really is the one and only active layer if (pActiveLayer != NULL) FrameSGallery::MakeActiveLayer(pActiveLayer); // If caller wants the ptr to the active layer if (ppActiveLayer != NULL) *ppActiveLayer = pActiveLayer; } */ /******************************************************************************************** > static BOOL FrameSGallery::EnsureFrameLayerIntegrity(Spread* pSpread) Author: Neville_Humphrys (Xara Group Ltd) Created: 21/5/97 Returns: True if worked ok, False otherwise. Purpose: This function should be called before any frame related actions are carried out It will ensure that all the visible layers are frame layers. Errors: - SeeAlso: - ********************************************************************************************/ BOOL FrameSGallery::EnsureFrameLayerIntegrity(Spread* pSpread) { ERROR2IF(pSpread == NULL,FALSE,"EnsureFrameLayerIntegrity null spread passed in"); // For the present moment just ensure that the active layer is a frame layer //Layer * pActiveLayer = pSpread->FindActiveLayer(); //if (pActiveLayer) // pActiveLayer->SetFrame(TRUE); /* #if _DEBUG // Find out whether the operation thinks it is required or not String_256 ShadeReason; OpState State; State = OpCombineLayersToFrameLayer::GetState(&ShadeReason, NULL); if (!State.Greyed) { // Try and find the operation we want to use OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_COMBINELAYERSTOFRAMELAYER); if (pOpDesc != NULL) { // We found it, so invoke it with the spread we were given OpParam Param; Param.Param1 = (INT32)pSpread; pOpDesc->Invoke(&Param); } else { ERROR3("Couldn't find OPTOKEN_COMBINELAYERSTOFRAMELAYER op descriptor"); } } */ /* #if 0 //_DEBUG // WARNING only do this in Webster builds as otherwise may be corrupting layers that are in the // undo buffer which could lead to immense problems. // This leads to problems in the undo e.g. draw object, import doc with layers and undo back to start // can mean no layers in doc. // In Camelot do nothing #ifdef WEBSTER // Ensure that all other non-guide and non-background layers are frame layers UINT32 NonFrameLayersFound = 0; Layer* pCurrentLayer = pSpread->FindFirstLayer(); Layer* pNonFrameLayer = NULL; while (pCurrentLayer != NULL) { if (!pCurrentLayer->IsBackground() && !pCurrentLayer->IsGuide() && !pCurrentLayer->IsPageBackground() && !pCurrentLayer->IsFrame()) { // Note that we have found a non-frame layer. pNonFrameLayer = pCurrentLayer; NonFrameLayersFound++; } pCurrentLayer = pCurrentLayer->FindNextLayer(); } if (NonFrameLayersFound > 0 && pNonFrameLayer != NULL) { TRACEUSER( "Neville", _T("++++++++++EnsureFrameLayerIntegrity found %d non-frame layers\n"),NonFrameLayersFound); // Right, we need to move all the nodes from the all non-frame layers and move them // to one of the non-frame layers and make this one a frame layer. The user should // therefore notice no difference in appearance of the document as they would have // been seeing one frame representing all the non-frame layers in the frame gallery. // First, mark the non-frame layer found in the above search as a frame layer as this // is the one that we are going to use as out destination. Then all other non-frame // searches will not find it. Also, mark it as edited. pNonFrameLayer->SetFrame(TRUE); pNonFrameLayer->SetEdited(TRUE); // Start a progress bar Progress CombiningProgress(_R(IDS_COMBINING_LAYERS)); CombiningProgress.Update(); BOOL UpdateSelection = FALSE; Layer* pLayer = pSpread->FindFirstLayer(); while (pLayer != NULL) { if (!pLayer->IsBackground() && !pLayer->IsGuide() && !pLayer->IsPageBackground() && !pLayer->IsFrame()) { // Move all the top level nodes to the new layer // We MUST include hidden nodes as these will be in undo records Node * pNode = pLayer->FindFirstChild(); while (pNode) { // Note the node to move Node* pNodeToMove = pNode; // and the next node in the tree pNode = pNode->FindNext(); // Now move hide the node (should hide it but we are not undoable) UpdateSelection = pNodeToMove->IsSelected(); //if (!DoHideNode(pNodeToMove, FALSE, NULL, FALSE)) // Find the insertion point, which will be after the last child but // BEFORE the insertion node, if present. Node * pInsertPoint = pNonFrameLayer->FindLastChild(TRUE); if (pInsertPoint) pNodeToMove->MoveNode(pInsertPoint, NEXT); else pNodeToMove->MoveNode(pNonFrameLayer, LASTCHILD); // Update the progress display to show we have done something CombiningProgress.Update(); } // Finally, go and hide that layer Layer * pLayerToHide = pLayer; // First, invalidate the bounding rect pLayerToHide->InvalidateBoundingRect(); // note the next layer pLayer = pLayer->FindNextLayer(); // and hide the layer itself. // Have to do this ourselves as we are not undoable pLayerToHide->CascadeDelete(); delete pLayerToHide; pLayerToHide = NULL; } else pLayer = pLayer->FindNextLayer(); // Update the progress display to show we have done something CombiningProgress.Update(); } // Make sure that our new frame layer is up to date pNonFrameLayer->InvalidateBoundingRect(); // If we have changed a selected node then update the selection if (UpdateSelection) { // Update the selection range Camelot.UpdateSelection(); } // We need to update the display as one or more layer items have changed status // So tell ourselves about the change. (We are static and so cannot do it directly!) BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::SpreadReason::LAYERCHANGES)); // Update the progress display to show we have done something CombiningProgress.Update(); } #endif // WEBSTER #endif // DEBUG */ // In Webster ensure that all layers are actually frames // In Camelot do nothing #ifdef WEBSTER // Ensure that all other non-guide and non-background layers are frame layers UINT32 NonFrameLayersFound = 0; Layer* pCurrentLayer = pSpread->FindFirstLayer(); while (pCurrentLayer != NULL) { if (pCurrentLayer->IsPseudoFrame() && !pCurrentLayer->IsFrame()) { pCurrentLayer->SetFrame(TRUE); NonFrameLayersFound++; } pCurrentLayer = pCurrentLayer->FindNextLayer(); } if (NonFrameLayersFound > 0) { TRACEUSER( "Neville", _T("++++++++++EnsureFrameLayerIntegrity found %d non-frame layers\n"),NonFrameLayersFound); // We need to update the display as one or more layer items have changed status // So tell ourselves about the change. (We are static and so cannot do it directly!) BROADCAST_TO_ALL(SpreadMsg(pSpread, SpreadMsg::SpreadReason::LAYERCHANGES)); } #endif // WEBSTER return TRUE; } /******************************************************************************************** > static BOOL FrameSGallery::DoHideNode(Node* pNodeToHide) Author: Neville_Humphrys (Xara Group Ltd) Created: 21/5/97 Returns: True if worked ok, False otherwise. Purpose: This function tries to hide the specified node. Copy of the undoable operation version as we are not undoable and don't have an op. Hide it as it may be mentioned in the undo history. Note: This would be safer than deleting the layer nodes but if we use this, which should be the same as the DoHideNode in undoable operation does, then it leaks the hidden nodes and layers that are being hidden. So there must be something sneaky going on. ********************************************************************************************/ /* BOOL FrameSGallery::DoHideNode(Node* pNodeToHide) { ERROR2IF(pNodeToHide == NULL,FALSE,"FrameSGallery::DoHideNode Bad node speicifed"); // Try to hide the Node NodeHidden* pHidden = new NodeHidden(pNodeToHide); if (pHidden == NULL) { return FALSE; } return TRUE; } */ /******************************************************************************************** > static String_256 FrameSGallery::CreateUniqueLayerID(Spread* pSpread, const String_256 * pBaseName) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: pSpread - the spread to use when checking pBaseName - the name to use as the basis of the layer name, defaults to just 'Frame' Returns: A LayerID which is unique for the layer galleries spread. Purpose: Used to generate a LayerID which is unique for the spread. The name generated is normally of the form "Layer n", where n is the number of layers in the spread + 1. If "Layer n" already exists on the spread then "Layer m" is generated where m is the smallest integer greater than n such that the id is unique. Errors: - SeeAlso: - ********************************************************************************************/ String_256 FrameSGallery::CreateUniqueLayerID(Spread* pSpread, const String_256 * pBaseName) { if (pSpread == NULL) return String_256(""); String_256 UniqueLayerID; INT32 NumLayers = 0; Layer* pLayer = pSpread->FindFirstLayer(); // Calculate how many layers are on the current spread while (pLayer != NULL) { NumLayers++; pLayer = pLayer->FindNextLayer(); } INT32 NewLayerNum = NumLayers; if (NewLayerNum == 0) NewLayerNum = 1; // Always start at one BOOL Unique; // Flag used to indicate if the id generated is unique or not String_256 LayerName(_R(IDS_DEFAULTFRAMENAME)); // If the caller suggested a base name then use this instead. if (pBaseName != NULL) LayerName = *pBaseName; do { // Construct a first attempt at a unique layer id 'Layer n' // where n = the number of layers on the current spread + 1 UniqueLayerID.MakeMsg(_R(IDS_FRAMENAMEUNIQUEFORM), (TCHAR *)LayerName, NewLayerNum); //UniqueLayerID.MakeMsg(_R(IDS_SGLAYER_LAYER_NUM), /*TEXT("Layer #1%ld"),*/NewLayerNum); // Check that UniqueLayerID is indeed unique Unique = TRUE; // Until we know better pLayer = pSpread->FindFirstLayer(); while (pLayer != NULL) { if (UniqueLayerID == pLayer->GetLayerID()) { Unique = FALSE; // UniqueLayerID is not unique so increment NewLayerNum and try again NewLayerNum++; break; } pLayer = pLayer->FindNextLayer(); } } while (!Unique); return(UniqueLayerID); } #ifndef EXCLUDE_GALS /*********************************************************************************************** > SGDisplayFrame *FrameSGallery::GetSelectedLayerGalItem() Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Returns: A ptr to the selected layer gallery item. NULL if there is no selectet item Purpose: Gets the selected layer gallery item In debug builds, an ENSURE will go off if there is no selected gal item ***********************************************************************************************/ SGDisplayLayer *FrameSGallery::GetSelectedLayerGalItem() { SGDisplayFrame* pDispLayer = NULL; if (CheckVarsAreValid()) { ERROR3IF(DisplayForeground == NULL,"Foreground group is NULL"); if (DisplayForeground == NULL) return NULL; // Look in the foreground group first pDispLayer = ((SGDisplayFrame *) DisplayForeground->FindNextSelectedItem(NULL)); ERROR3IF(pDispLayer == NULL,"Can't find the selected layer item in the layer gallery"); } return(pDispLayer); } /*********************************************************************************************** > BOOL FrameSGallery::DoDeleteSelection(void) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Returns: FALSE if it couldn't delete the selection. (This should, if at all possible leave the entire selection undeleted in this case) Purpose: FORCIBLY deletes the active layer/frame. SeeAlso: FrameSGallery::PrepareToDelete; ColourManager::HideColours ***********************************************************************************************/ BOOL FrameSGallery::DoDeleteSelection(void) { OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_DELETEFRAME); if (pOpDesc != NULL) pOpDesc->Invoke(); else { ERROR3("Couldn't find OPTOKEN_FRAME_DELETEFRAME op descriptor"); } return TRUE; } /*********************************************************************************************** > void FrameSGallery::DoCreateNewItem(void) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Purpose: This function is meant to be overridden in derived classes It creates a new item and adds it to the Gallery DisplayList The item may be created by cloning/deriving/basing-on the selected item, depending on the type of Gallery concerned. ***********************************************************************************************/ void FrameSGallery::DoCreateNewItem(void) { OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_NEWFRAME); if (pOpDesc != NULL) pOpDesc->Invoke(); else { ERROR3("Couldn't find OPTOKEN_FRAME_NEWFRAME op descriptor"); } } /*********************************************************************************************** > void FrameSGallery::DoCopyLayer() Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: - Returns: - Purpose: Copies the active layer creating a new one with a default frame name. ***********************************************************************************************/ void FrameSGallery::DoCopyLayer() { OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_COPYFRAME); if (pOpDesc != NULL) pOpDesc->Invoke(); else { ERROR3("Couldn't find OPTOKEN_FRAME_COPYFRAME op descriptor"); } } /*********************************************************************************************** > static void FrameSGallery::DoChangeSoild(Layer* pLayer,BOOL Solid) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: pLayer = the layer to change Solid - TRUE means make the displayed layer Solid FALSE means make Solid Returns: - Purpose: Called when the Solid button is clicked in a layer gallery item. Changes the Solidness of the displayed layer. Notes: Does not redraw the layer in the display list ***********************************************************************************************/ void FrameSGallery::DoChangeSolid(Layer* pLayer,BOOL Solid) { ERROR3IF(pLayer == NULL,"pLayer == NULL"); if (pLayer == NULL) return; BOOL PrevSolid = pLayer->IsSolid(); pLayer->SetSolid(Solid); BOOL PostSolid = pLayer->IsSolid(); /* if (PrevSolid != PostSolid) { // Force a redraw if the layer's visibility has changed FrameSGallery::ForceRedrawLayer(pLayer->FindDocument(), pLayer); // If layer has just become invisible, remove the selections on the layer if (!PostSolid) NodeRenderableInk::DeselectAllOnLayer(pLayer); } */ if (PrevSolid != PostSolid) { // Mark all frames above this as edited until we reach the last frame // OR we hit a solid/background layer. // Previewing all the frames copes with dependent frames // Previwing single frames does not if you preview the solid frame. Layer * pFrame = pLayer->FindNextFrameLayer(); while (pFrame != NULL && !pFrame->IsSolid()) { // Mark that frame as edited pFrame->SetEdited(TRUE); pFrame = pFrame->FindNextFrameLayer(); } Spread* pSpread = pLayer->FindParentSpread(); // Go and fix the status of other layers according to this new setting FixOtherLayers(pSpread); // Ensure that the buttons are in the correct state BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); } } /*********************************************************************************************** > static void FrameSGallery::DoChangeOverlay(Layer* pLayer,BOOL Overlay) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: pLayer = the layer to change Overlay - TRUE means make the displayed layer Overlayed FALSE means make the displayed layer non-Overlayed Returns: - Purpose: Called when the Overlay button is clicked in a layer gallery item. Changes the Overlayness of the displayed layer. Notes: Does not redraw the layer in the display list ***********************************************************************************************/ void FrameSGallery::DoChangeOverlay(Layer* pLayer,BOOL Overlay) { ERROR3IF(pLayer == NULL,"pLayer == NULL"); if (pLayer == NULL) return; BOOL PrevOverlay = pLayer->IsOverlay(); pLayer->SetOverlay(Overlay); BOOL PostOverlay = pLayer->IsOverlay(); //if (PrevOverlay != PostOverlay) // NodeRenderableInk::DeselectAllOnLayer(pLayer); if (PrevOverlay != PostOverlay) { Spread* pSpread = pLayer->FindParentSpread(); // Go and fix the status of other layers according to this new setting FixOtherLayers(pSpread); // Ensure that the buttons are in the correct state BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); } } /*********************************************************************************************** > void FrameSGallery::DoMoveLayer(MoveLayerType Reason) Author: Neville_Humphrys (Xara Group Ltd) (Based on Mark N's function in the Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: Reason = how the layer should be moved Returns: - Purpose: Called when the Locked button is clicked in the layers gallery. Changes the lockedness of the selected layer, if there is one. Note: Same as LayerSGallery version but uses FRAME_MOVE ***********************************************************************************************/ void FrameSGallery::DoMoveLayer(MoveLayerType Reason) { SGDisplayLayer* pLayerGalItem = GetSelectedLayerGalItem(); if (pLayerGalItem != NULL) { OpLayerGalParam Param(FRAME_MOVE, pSpread); Param.pLayer = pLayerGalItem->GetDisplayedLayer(); switch (Reason) { case (MOVELAYER_UPONE) : Param.pContextNode = Param.pLayer->FindNextLayer(); Param.AttDir = NEXT; break; case (MOVELAYER_DOWNONE) : Param.pContextNode = Param.pLayer->FindPrevLayer(); Param.AttDir = PREV; break; default: ERROR3("Unrecognised MoveLayer reason"); break; } if (Param.pContextNode != NULL) { // Redraw after the op if both this layer and the one it's moving in front/behind // is also visible Param.MoveRedraw = ((Layer*)Param.pContextNode)->IsVisible() && Param.pLayer->IsVisible(); // The above won't work in an undo or redo, so always redraw Param.MoveRedraw = TRUE; OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_LAYERGALCHANGE); if (pOpDesc != NULL) pOpDesc->Invoke((OpParam*)&Param); else { ERROR3("Couldn't find OPTOKEN_LAYERGALCHANGE op descriptor"); } } } } /*********************************************************************************************** > void FrameSGallery::DoShadeGallery(BOOL ShadeIt) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: ShadeIt - TRUE if the gallery is being shaded FALSE if the gallery is being unshaded Purpose: Called by the base class whenever the shaded status of the gallery is changed, to allow derived galleries to shade/unshade any extra controls that they provide in the window. ONLY called if the gallery is actually open/visible. Notes: Need not be overridden - the default action is to do nothing extra to the normal shade/unshade operation. SeeAlso: Gallery::ShadeGallery; Gallery::UnshadeGallery ***********************************************************************************************/ void FrameSGallery::DoShadeGallery(BOOL ShadeIt) { EnableGadget(_R(IDC_GALLERY_UPONE), !ShadeIt); EnableGadget(_R(IDC_GALLERY_DOWNONE), !ShadeIt); EnableGadget(_R(IDC_GALLERY_PROPERTIES),!ShadeIt); EnableGadget(_R(IDC_GALLERY_COPY), !ShadeIt && !IsSelectedItemGuideLayer()); EnableGadget(_R(IDC_FRAME_DELETE), !ShadeIt); EnableGadget(_R(IDC_BTN_MULTILAYER), !ShadeIt); EnableGadget(_R(IDC_BTN_ALLVISIBLE), !ShadeIt); //EnableGadget(_R(IDC_GALLERY_NAME), !ShadeIt); EnableGadget(_R(IDC_GALLERY_COPY), !ShadeIt && !IsSelectedItemGuideLayer()); UpdateFrameRelatedButtons(); } /******************************************************************************************** > virtual BOOL FrameSGallery::InitMenuCommands(void) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Returns: TRUE for success Purpose: Initialises any menu commands that this gallery needs. Notes: Will only create the menu commands once - further calls in the future will return TRUE immediately wihtout doing anything. ********************************************************************************************/ BOOL FrameSGallery::InitMenuCommands(void) { static BOOL MenusInitialised = FALSE; BOOL ok = TRUE; if (!MenusInitialised) { // Initialise menu command Ops // "Special" entries for over-list menu ok = ok && InitMenuCommand((StringBase *) &SGCmd_Copy, _R(IDS_COPYFRAME)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Delete, _R(IDS_DELETEFRAME)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_New, _R(IDS_NEWFRAME)); // _R(IDS_SGMENU_NEW) // ok = ok && InitMenuCommand((StringBase *) &SGCmd_Animation, _R(IDS_SGMENU_ANIMATION)); // ok = ok && InitMenuCommand((StringBase *) &SGCmd_Save, _R(IDS_SGMENU_SAVE)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Preview, _R(IDS_GRABFRAME)); // _R(IDS_SGMENU_PREVIEW)); // ok = ok && InitMenuCommand((StringBase *) &SGCmd_Browser, _R(IDS_SGMENU_BROWSER)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Properties,_R(IDS_FRAMEPROPERTIES)); //_R(IDS_SGMENU_FRAMEPROPS)); // ok = ok && InitMenuCommand((StringBase *) &SGCmd_FrameProps,_R(IDS_SGMENU_FRAMEPROPS)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Show, _R(IDS_SGMENU_SHOWFRAME)); MenusInitialised = TRUE; } return(ok); } /******************************************************************************************** > virtual BOOL FrameSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: TheMenu - The menu to add commands to MenuID - The type of menu (over-list or from-options-button) to create Returns: TRUE if it succeeded Purpose: To build a menu of commands to be popped up over the gallery. Notes: The Layer gallery provides only a simple item-pop-up menu ********************************************************************************************/ BOOL FrameSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID) { BOOL ok = TRUE; if (MenuID == SGMENU_OVERITEM) { // Over-list menu SGDisplayLayer* pLayerGalItem = GetSelectedLayerGalItem(); #ifndef STANDALONE // no layer properties tab present on standalone version if (pLayerGalItem != NULL) { GIFAnimationPropertyTabs * pTabHandler = GIFAnimationPropertyTabsDlg::GetGIFAnimationPropertiesTabs(); //LayerPropertyTabs * pTabHandler = LayerPropertyTabsDlg::GetLayerPropertiesTabs(); if (pTabHandler) { pTabHandler->SetCurrentLayer(pLayerGalItem->GetDisplayedLayer()); } } #endif ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_New); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Copy); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Delete,TRUE); #ifndef STANDALONE // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Animation); // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Save); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Preview); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Properties); // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_FrameProps); // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Browser); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Show); #endif } return(ok); } /******************************************************************************************** > virtual OpState FrameSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: CommandID - TheString ID of the command Outputs: ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled ion with the reason that the item is shaded/greyed. Returns: An OpState indicating the current menu item state. Purpose: To determine the state of a given menu item. This method is an exact parallel to an Op's GetState method (in fact, it is called by an Op's GetState) Notes: Override this method to provide state info for your special commands Call the base class for unknown commands to allow it to handle them for you The base class handles all of these (maybe more - see the base class help) Properties, Sort, Find; New, Edit, Delete, Redefine; NextGroup, PrevGroup, FoldGroup, UnfoldGroup; ********************************************************************************************/ OpState FrameSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason) { OpState State; if (AmShaded) // No commands available while the gallery is shaded { State.Greyed = TRUE; return(State); } if (*CommandID == SGCmd_Copy || // --- Copy/Delete/Properties // *CommandID == SGCmd_Delete || *CommandID == SGCmd_Show // *CommandID == SGCmd_Properties || // *CommandID == SGCmd_Animation || // *CommandID == SGCmd_Browser || // *CommandID == SGCmd_FrameProps ) { SGDisplayLayer* pItem = GetSelectedLayerGalItem(); if (pItem == NULL) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_SINGLECOL)); } else if (*CommandID == SGCmd_Copy) // Can't copy Guide layers State.Greyed = IsSelectedItemGuideLayer(); else if (*CommandID == SGCmd_Show) // Can't hide Guide layers { State.Greyed = IsSelectedItemGuideLayer(); Layer * pLayer = pItem->GetDisplayedLayer(); if (pLayer) State.Ticked = !pLayer->IsHiddenFrame(); else State.Greyed = TRUE; } /* #ifndef STANDALONE else if (*CommandID == SGCmd_Properties) // Shade when dlg is open { //State.Greyed = (LayerPropertyTabs::GetTabbedDlg() != NULL); LayerPropertyTabs * pTabHandler = LayerPropertyTabsDlg::GetLayerPropertiesTabs(); if (pTabHandler) State.Greyed = (pTabHandler->GetTabbedDlg() != NULL); else State.Greyed = TRUE; } #endif */ } /* #if _DEBUG else if (*CommandID == SGCmd_Save) { // Just call the GetState function for the op directly return OpSaveAnimatedGIF::GetState(ShadeReason, NULL); } #endif */ else if (*CommandID == SGCmd_Preview) { // Just call the GetState function for the op directly return OpGrabAllFrames::GetState(ShadeReason, NULL); } else if (*CommandID == SGCmd_FrameProps || *CommandID == SGCmd_Properties) { // Call the GetState function for the frame properties op. return OpFrameProperties::GetState(ShadeReason, NULL); } else if (*CommandID == SGCmd_Delete) { // Call the GetState function for the frame delete op. return OpDeleteFrame::GetState(ShadeReason, NULL); } // Don't call the base class 'cos we don't want any other commands return(State); } /******************************************************************************************** > virtual void FrameSGallery::DoCommand(StringBase *CommandID) Author: Neville_Humphrys (Xara Group Ltd) (Based on Jason's Layer gallery code) Created: 16/4/97 (Based on Jason's Layer gallery code) Inputs: CommandID - The String ID of the command Purpose: To apply a given command when it is chosen from the menu. Notes: Override this method to provide handling for your special commands. Call the base class if you don't recognise the command, so that it can handle standard commands. The base class handles all of these (maybe more - see the base class help) Properties, Sort, Find; New, Edit, Delete, Redefine; (it calls ApplyAction as appropriate) NextGroup, PrevGroup, FoldGroup, UnfoldGroup; ********************************************************************************************/ void FrameSGallery::DoCommand(StringBase *CommandID) { if (*CommandID == SGCmd_Copy) DoCopyLayer(); else if (*CommandID == SGCmd_New) DoCreateNewItem(); else if (*CommandID == SGCmd_Delete) { //if (PrepareToDelete()) // No warning on Frame gallery DoDeleteSelection(); } // else if (*CommandID == SGCmd_Properties) // DoFrameProperties(); else if (*CommandID == SGCmd_Preview) { DoPreviewAnimation(); } else if (*CommandID == SGCmd_FrameProps || *CommandID == SGCmd_Properties) { // Open the Animation properties dlg with the "Frame properties" page selected. DoFrameProperties(); } else if (*CommandID == SGCmd_Show) { // Toggle the state of the show frame in animation flag SGDisplayLayer* pItem = GetSelectedLayerGalItem(); Layer * pLayer = NULL; if (pItem) pLayer = pItem->GetDisplayedLayer(); if (pLayer) { BOOL CurrentState = pLayer->IsHiddenFrame(); pLayer->SetHiddenFrame(!CurrentState); if (pItem) pItem->ForceRedrawOfMyself(); // Ensure that the buttons are in the correct state BROADCAST_TO_ALL(LayerMsg(pLayer, LayerMsg::LayerReason::ACTIVE_LAYER_CHANGED)); } } // else if (*CommandID == SGCmd_Save) // DoSaveAnimation(); // Implement **** // *CommandID == SGCmd_Animation // *CommandID == SGCmd_Browser // Don't call the base class 'cos we don't want any other commands } /*********************************************************************************************** > virtual BOOL FrameSGallery::DoSaveAnimation() Author: Neville_Humphrys (Xara Group Ltd) Created: 30/4/97 Inputs: - Returns: True if worked ok, False otherwise Purpose: Saves out the current animation to file. ***********************************************************************************************/ BOOL FrameSGallery::DoSaveAnimation() { // Not required at present /* OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_SAVEANIMATEDGIF); if (pOpDesc != NULL) pOpDesc->Invoke(); else { ERROR3("Couldn't find OPTOKEN_FRAME_COPYFRAME op descriptor"); } */ return TRUE; } /*********************************************************************************************** > virtual BOOL FrameSGallery::DoPreviewAnimation() Author: Neville_Humphrys (Xara Group Ltd) Created: 30/4/97 Inputs: - Returns: True if worked ok, False otherwise Purpose: Previews the current animation. ***********************************************************************************************/ BOOL FrameSGallery::DoPreviewAnimation() { // Check to see if the operation is available // No longer required as the button is hooked into the real op //String_256 ShadeReason; //OpState State; //State = OpGrabAllFrames::GetState(&ShadeReason, NULL); //if (State.Greyed) // return FALSE; // Normally we want to invoke the grab frame, but we will sneak in that // if the shift key is pressed then we will grab all frames. OpDescriptor* pOpDesc = NULL; // Is the shift key pressed? if (KeyPress::IsAdjustPressed()) pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABALLFRAMES); else pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABFRAME); if (pOpDesc != NULL) pOpDesc->Invoke(); else { ERROR3("Couldn't find OPTOKEN_FRAME_GRABFRAME/_GRABALLFRAMES op descriptor"); } return TRUE; } /*********************************************************************************************** > BOOL FrameSGallery::DoRegenerateSingleFrame() Author: Ranbir_Rana (Xara Group Ltd) Created: 14/05/97 Inputs: - Returns: True if worked ok, False otherwise Purpose: While previewing an animation, if the frame layer properties are changed we neeed to regenerate the active frame. This function invokes the correct Op. *************************************************************************************************/ BOOL FrameSGallery::DoRegenerateSingleFrame() { OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABFRAME); GIFAnimationExportParam Param; if (pOpDesc != NULL) pOpDesc->Invoke(&Param); else { ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor"); } return TRUE; } /*********************************************************************************************** > BOOL FrameSGallery::DoRegenerateFrames() Author: Ranbir_Rana (Xara Group Ltd) Created: 14/05/97 Inputs: - Returns: True if worked ok, False otherwise Purpose: While previewing an animation, if the spread properties are changed we neeed to regenerate the frame layers. This function invokes the correct Op. *************************************************************************************************/ BOOL FrameSGallery::DoRegenerateFrames() { OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABALLFRAMES); if (pOpDesc != NULL) pOpDesc->Invoke(); else { ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor"); } return TRUE; } /*********************************************************************************************** > BOOL FrameSGallery::DoFrameProperties() Author: Neville_Humphrys (Xara Group Ltd) Created: 22/5/97 Inputs: - Returns: True if worked ok, False otherwise Purpose: Opens the frame properties dlg ***********************************************************************************************/ BOOL FrameSGallery::DoFrameProperties() { OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFANIMPROPERTYTABS); if (pOpDesc != NULL) { // Select the "Frame properties tab". GIFAnimationPropertyTabsDlg::SetPageToOpen(GIFAnimationPropertyTabs::FramePropertiesTabNumber); String_256 Str; OpState State = pOpDesc->GetOpsState(&Str); if (!State.Greyed) pOpDesc->Invoke(); else { GIFAnimationPropertyTabs * pTabHandler = GIFAnimationPropertyTabsDlg::GetGIFAnimationPropertiesTabs(); if (pTabHandler) { DialogTabOp* pDlg = pTabHandler->GetTabbedDlg(); if (pDlg != NULL) pDlg->Open(); } } } return TRUE; } /*********************************************************************************************** > BOOL FrameSGallery::UpdateFrameRelatedButtons() Author: Neville_Humphrys (Xara Group Ltd) Created: 29/5/97 Inputs: - Returns: True if worked ok, False otherwise Purpose: Ensures that they buttons on the gallery up to date in their greying/ungreying status. ***********************************************************************************************/ BOOL FrameSGallery::UpdateFrameRelatedButtons() { // This is no longer required for the present as we have hooked the buttons // into the real ops that we have. // String_256 ShadeReason; // OpState State; // State = OpGrabAllFrames::GetState(&ShadeReason, NULL); // EnableGadget(_R(IDC_BMPGAL_PREVIEW), !State.Greyed); // State = OpFrameProperties::GetState(&ShadeReason, NULL); // EnableGadget(_R(IDC_GALLERY_PROPERTIES), !State.Greyed); return TRUE; } /******************************************************************************************** > BOOL FrameSGallery::CloseFrameGallery() Author: Ranbir_Rana (Xara Group Ltd) Created: 21/10/97 Inputs: - Returns: TRUE if sucessful, else FALSE. ********************************************************************************************/ BOOL FrameSGallery::CloseFrameGallery() { String_32 Name(_R(IDS_FRAMEGAL_GALLNAME)); DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(Name); // Ensure a valid ptr. if (pDialogBarOp == NULL) return FALSE; if (pDialogBarOp->GetRuntimeClass() == CC_RUNTIME_CLASS(FrameSGallery)) { GIFAnimationPropertyTabs::SetFrameGalleryOpen(FALSE); // Toggle the visible state of the gallery window pDialogBarOp->SetVisibility( FALSE ); } else { ERROR3("Got the frame gallery but it's not of the LayerSGallery class"); } SGInit::UpdateGalleryButton(OPTOKEN_DISPLAYFRAMEGALLERY, FALSE); GIFAnimationPropertyTabs::SetFrameGalleryOpen(FALSE); // Everything ok. return TRUE; } /******************************************************************************************** > BOOL FrameSGallery::OpenLayerGallery() Author: Ranbir_Rana (Xara Group Ltd) Created: 21/10/97 Inputs: - Returns: TRUE if the document is Frame based, else FALSE. ********************************************************************************************/ BOOL FrameSGallery::OpenLayerGallery() { // Find the OP. for the Layer gallery. OpDescriptor* OpDesc; OpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_DISPLAYLAYERGALLERY); // Ensure we get a ptr to the OP. if(!OpDesc) return FALSE; // ok, now open the layergallery. OpDesc->Invoke(); // Lets go back. return TRUE; } /******************************************************************************************** > BOOL FrameSGallery::IsFrameMode() Author: Ranbir_Rana (Xara Group Ltd) Created: 21/10/97 Inputs: Pointer to the document. Returns: TRUE if the document is Frame based, else FALSE. ********************************************************************************************/ BOOL FrameSGallery::IsFrameMode(Document* pDoc) { ERROR3IF(pDoc == NULL,"pDoc == NULL"); // flag to determine the document mode. BOOL FrameMode = FALSE; // Get a ptr to the selected spread Spread* pSpread = pDoc->GetSelectedSpread(); // Ensure a valid spread ptr. if(pSpread) { // Are there any frame layers? Layer* pFrameLayer = pSpread->FindFirstFrameLayer(); //If a frame layer exists, then this is an animation doc. if (pFrameLayer) FrameMode = TRUE; } // return the document mode. return FrameMode; } #endif // EXCLUDE_GALS