// $Id: sgbitmap.cpp 1664 2006-08-04 10:06:16Z gerry $ /* @@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============================ */ // SGBitmap.cpp - Bitmap SuperGallery classes - BitmapSGallery and SGDisplayBitmap #include "camtypes.h" //#include "app.h" // For GetApplication() - in camtypes.h [AUTOMATICALLY REMOVED] //nclude "gallery.h" // For _R(IDC_GALLERY_LISTBOX) //#include "galstr.h" //#include "galres.h" #include "sgbitmap.h" #include "sginit.h" #include "sgmenu.h" //nclude "ccdc.h" // For render-into-dialogue support //nclude "fillval.h" //nclude "grnddib.h" //#include "will.h" // For OpShowBitmapGallery ID's //nclude "bitmap.h" #include "bitmpinf.h" //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] //nclude "attrmgr.h" #include "nodebmp.h" //nclude "convert.h" //#include "resource.h" // For _R(IDS_CANCEL) #include "dragmgr.h" #include "dragbmp.h" //nclude "viewrc.h" // FOR _R(IDC_CANDROPONPAGE) //#include "docview.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] #include "tracedlg.h" #include "bfxdlg.h" //nclude "bfxalu.h" //nclude "bitmapfx.h" #include "impexpop.h" // Import/Export ops //#include "scrcamvw.h" //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] //nclude "sglib.h" //#include "richard2.h" // extra resource strings #include "bmpcomp.h" //#include "will3.h" //#include "phil.h" #include "comattrmsg.h" #include "bmpsdlg.h" //#include "bmpdlgr.h" //#include "bmpsdlgr.h" #include "giffiltr.h" #include "bmpsrc.h" #include "plugop.h" // PlugInsContextMenu #include "backgrnd.h" // OpBackground #include "keypress.h" // KeyPress #include "impexpop.h" // BitmapExportParam #include "prevwdlg.h" // PreviewDialog::Init() #include "bmpexprw.h" // BitmapExportPreviewDialog::Init() #include "helpuser.h" //For the help button //#include "xshelpid.h" //For the help button //#include "helppath.h" //#include "xpehost.h" // For OPTOKEN_XPE_EDIT #include "qualattr.h" #include "bfxop.h" // useful BFX plug-in related operations #include "fillattr2.h" #ifdef PHOTOSHOPPLUGINS #include "plugmngr.h" // CheckHaveDetailsOnPlugIns #endif //PHOTOSHOPPLUGINS #include "camview.h" // Implement the dynamic class bits... CC_IMPLEMENT_DYNCREATE(BitmapSGallery, SuperGallery) CC_IMPLEMENT_DYNAMIC(SGDisplayKernelBitmap, SGDisplayItem) CC_IMPLEMENT_DYNCREATE(OpDisplayBitmapGallery,Operation); CC_IMPLEMENT_DYNAMIC(SGBitmapDragTarget, SGListDragTarget); CC_IMPLEMENT_DYNCREATE(GalleryBitmapDragInfo, BitmapDragInformation) // Enable Background redraw in the bitmap gallery... //#define SGBITMAP_BACKGROUND_REDRAW // This line mustn't go before any CC_IMPLEMENT_... macros #define new CAM_DEBUG_NEW BOOL BitmapSGallery::IgnoreBmpListChange = FALSE; /******************************************************************************************** > SGBitmapDragTarget::SGBitmapDragTarget(DialogOp *TheDialog, CGadgetID TheGadget = NULL) Author: Will_Cowling (Xara Group Ltd) Created: 25/3/95 Inputs: TheDialog - The kernel dialog in which the target exists TheGadget - The gadget within that dialogue which is the target Purpose: Constructor ********************************************************************************************/ SGBitmapDragTarget::SGBitmapDragTarget(DialogOp *TheDialog, CGadgetID TheGadget) : SGListDragTarget(TheDialog, TheGadget) { ERROR3IF(!TheDialog->IsKindOf(CC_RUNTIME_CLASS(BitmapSGallery)), "You can only use SGBitmapDragTargets with BitmapSGallery dialogues!"); } /******************************************************************************************** BOOL SGBitmapDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo, OilCoord *pMousePos, KeyPress* pKeyPress) Author: Will_Cowling (Xara Group Ltd) Created: 25/3/95 Inputs: Event - Indicates what has happened pDragInfo - points to drag information describing this drag. This should be a BitmapDragInformation or derivation thereof pMousePos - points to information on the current mouse position, in OIL coords pKeyPress - NULL, or if for a keypress event, keypress information Returns: TRUE to claim the event, FALSE to let it through to other targets Purpose: Event Handler for SuperGallery listitem drag events. Overrides the base class handler to enable it to sort out the node being dragged for Bitmap drags. ********************************************************************************************/ BOOL SGBitmapDragTarget::ProcessEvent(DragEventType Event, DragInformation *pDragInfo, OilCoord *pMousePos, KeyPress* pKeyPress) { if (!pDragInfo->IsKindOf(CC_RUNTIME_CLASS(BitmapDragInformation))) return(FALSE); SGDisplayNode *DraggedNode = NULL; BOOL IsSimpleBitmapDrag = TRUE; // Only one bitmap is being dragged if (IS_A(pDragInfo, GalleryBitmapDragInfo)) { DraggedNode = ((GalleryBitmapDragInfo *)pDragInfo)->GetDraggedBitmap(); IsSimpleBitmapDrag = FALSE; // We started the drag, so we will accept multiple // bitmaps being dragged in a single operation } if (DraggedNode != NULL) { switch(Event) { case DRAGEVENT_COMPLETED: HandleDragCompleted((SuperGallery *) TargetDialog, DraggedNode, pMousePos, IsSimpleBitmapDrag); return(TRUE); case DRAGEVENT_MOUSESTOPPED: case DRAGEVENT_MOUSEMOVED: case DRAGEVENT_MOUSEIDLE: // Call a subroutine to work out and set our current cursor shape return(DetermineCursorShape((SuperGallery *) TargetDialog, DraggedNode, pMousePos)); default: break; } } // Otherwise, we aren't interested in the event, so we don't claim it return(FALSE); } /******************************************************************************************** > void GalleryBitmapDragInfo::GalleryBitmapDragInfo() Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Purpose: Default constructor - do not call this constructor ********************************************************************************************/ GalleryBitmapDragInfo::GalleryBitmapDragInfo() { ERROR3("Default GalleryBitmapDragInfo constructor called"); } /******************************************************************************************** > GalleryBitmapDragInfo::GalleryBitmapDragInfo(SGDisplayKernelBitmap *pSourceItem, SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo, BOOL IsAdjust = FALSE) Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Inputs: pSourceItem - The gallery item from which the drag originated pMouseInfo - The mouse info which made the item start the drag pMiscInfo - The MiscInfo which accompanied the mouse event IsAdjust - TRUE if this is an adjust (line-Bitmap) drag Purpose: Constructor ********************************************************************************************/ GalleryBitmapDragInfo::GalleryBitmapDragInfo(SGDisplayKernelBitmap *pSourceItem, SGMouseInfo *pMouseInfo, SGMiscInfo *pMiscInfo, BOOL IsAdjust) : BitmapDragInformation(pSourceItem->GetDisplayedKernelBitmap(), 120, 0, 0, 0, IsAdjust) { SourceItem = pSourceItem; // Copy the source item pointer MouseInfo = *pMouseInfo; // Duplicate the structures (they may cease to exist MiscInfo = *pMiscInfo; // soon after the drag is started) } /******************************************************************************************** > GalleryBitmapDragInfo::~GalleryBitmapDragInfo() Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Purpose: Destructor ********************************************************************************************/ GalleryBitmapDragInfo::~GalleryBitmapDragInfo() { } /******************************************************************************************** > void GalleryBitmapDragInfo::OnClick(INT32 Flags,POINT Point) Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Inputs: - Outputs: - Returns: - Purpose: This is called if a drag was attempted but never started because it was a click all along. It calls back the SourceItem SGDisplayBitmap, to get it to handle the click. Errors: - SeeAlso: - ********************************************************************************************/ void GalleryBitmapDragInfo::OnClick(INT32 Flags ,POINT Point) { if (SourceItem != NULL) SourceItem->DragWasReallyAClick(&MouseInfo, &MiscInfo); } /******************************************************************************************** > void GalleryBitmapDragInfo::GetCursorID(DragTarget* pDragTarget) Author: Will_Cowling (Xara Group Ltd) Created: 25/3/95 Purpose: Set cursor over this target ********************************************************************************************/ UINT32 GalleryBitmapDragInfo::GetCursorID(DragTarget* pDragTarget) { if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget)) { PageDropInfo PageDropInfo; ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo); NodeRenderableInk* pObjectHit = PageDropInfo.pObjectHit; ObjectDragTarget TargetHit = PageDropInfo.TargetHit; if (pObjectHit && pObjectHit->IS_KIND_OF(NodeBitmap)) TargetHit = NO_TARGET; // Ignore NodeBitmap objects ClickModifiers ClickMods = ClickModifiers::GetClickModifiers(); BOOL IsInside = ClickMods.Constrain; if (!IsInside && pObjectHit && pObjectHit->IsCompound()) { TargetHit = MANY_TARGET; } UINT32 CanFill = IsInside ? _R(IDC_DROPINSIDEONFILL) : _R(IDC_CANDROPONFILL); switch (TargetHit) { case FILL_TARGET: case LINE_TARGET: case STARTCOL_TARGET: case ENDCOL_TARGET: case ENDCOL2_TARGET: case ENDCOL3_TARGET: case MANY_TARGET: return CanFill; case NO_TARGET: // bitmap gallery - drop = add bitmap, CTRL + drop = page fill return IsInside ? _R(IDC_CANFILLPAGE) : _R(IDC_CANDROPONPAGE); //return _R(IDC_CANDROPONPAGE); }; return _R(IDC_CANDROPONPAGE); } return _R(IDC_CANTDROP); } /******************************************************************************************** > virtual BOOL GalleryBitmapDragInfo::GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget) Author: Will_Cowling (Xara Group Ltd) Created: 25/3/95 Returns: Whether String is valid Purpose: provide status line text for this target ********************************************************************************************/ BOOL GalleryBitmapDragInfo::GetStatusLineText(String_256 * TheText, DragTarget* pDragTarget) { ERROR2IF(TheText==NULL,FALSE,"NULL string in GetStatusLineText()"); if (TheBitmap == NULL || TheBitmap->ActualBitmap == NULL) return FALSE; String_256 DragString; String_256 BmpName(TheBitmap->ActualBitmap->GetName()); DragString.MakeMsg(_R(IDS_SGBITMAP_DRAGGING_BITMAP), (TCHAR *)BmpName); // "Dragging Bitmap 'Bitmap' : "); if (pDragTarget && pDragTarget->IS_KIND_OF(ViewDragTarget)) { PageDropInfo PageDropInfo; ((ViewDragTarget*)pDragTarget)->GetDropInfo(&PageDropInfo); NodeRenderableInk* pObjectHit = PageDropInfo.pObjectHit; ObjectDragTarget TargetHit = PageDropInfo.TargetHit; String_256 ObjectDesc = String_32(_R(IDS_SGBITMAP_THIS_OBJECT)); // " this object"; if (pObjectHit) { ObjectDesc = pObjectHit->Describe(FALSE); } if (pObjectHit && pObjectHit->IS_KIND_OF(NodeBitmap)) TargetHit = NO_TARGET; // Ignore NodeBitmap objects ClickModifiers ClickMods = ClickModifiers::GetClickModifiers(); BOOL IsInside = ClickMods.Constrain; if (!IsInside && pObjectHit && pObjectHit->IsCompound()) { TargetHit = MANY_TARGET; } switch (TargetHit) { case FILL_TARGET: case LINE_TARGET: case STARTCOL_TARGET: case ENDCOL_TARGET: case ENDCOL2_TARGET: case ENDCOL3_TARGET: DragString += String_256(_R(IDS_SGBITMAP_DROP_APPLY_FILL)); // "Drop to apply a Bitmap fill to this "; DragString += ObjectDesc; if (IsInside) DragString += String_16(_R(IDS_SGBITMAP_ALONE)); // " alone"; break; case MANY_TARGET: DragString += String_256(_R(IDS_SGBITMAP_DROP_APPLY_FILL)); // "Drop to apply a Bitmap fill to this "; DragString += ObjectDesc; DragString += String_256(_R(IDS_SGBITMAP_CONTROL_DROP_INSIDE)); // "; Press 'Control' to drop 'Inside'"; break; case NO_TARGET: if (IsInside) { DragString += String_256(_R(IDS_DRAGBMP_DROP_SETPAGEBACKGROUND)); // "Drop to set the Bitmap fill of the page background"; } else { DragString += String_256(_R(IDS_SGBITMAP_DROP_INSERT_BITMAP)); // "Drop to Insert a new Bitmap object on the Page"; } break; }; *TheText = DragString; return TRUE; } return FALSE; } /******************************************************************************************** > BOOL GalleryBitmapDragInfo::OnPageDrop(ViewDragTarget* pDragTarget) Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Inputs: - Outputs: - Returns: - Purpose: Called when a bitmap is dropped onto the page. Errors: - SeeAlso: - ********************************************************************************************/ BOOL GalleryBitmapDragInfo::OnPageDrop(ViewDragTarget* pDragTarget) { PageDropInfo ThePageDropInfo; ((ViewDragTarget*)pDragTarget)->GetDropInfo(&ThePageDropInfo); NodeRenderableInk* pObjectHit = ThePageDropInfo.pObjectHit; // Find the bitmap to apply KernelBitmap* BitmapToApply = TheBitmap; TheBitmap = NULL; if(BitmapToApply == NULL) return FALSE; // See if the user dropped the bitmap onto an object(s) on the page // If so then try and apply that bitmap as a fill to that object(s). if (pObjectHit && !pObjectHit->IS_KIND_OF(NodeBitmap)) { // Fill the object(s) with the dropped bitmap AttrBitmapColourFill* Attrib = new AttrBitmapColourFill; if (Attrib == NULL) return FALSE; Attrib->AttachBitmap(BitmapToApply); AttributeManager::ApplyAttribToNode(pObjectHit, Attrib); } else { // Not dropped onto an object on the page // See if the control key is pressed BOOL Constrain = KeyPress::IsConstrainPressed(); if (Constrain) { // If the control key is pressed then apply the bitmap as a new background // We should use the document given to us by the page info class Document * pDocument = ThePageDropInfo.pDoc; if (pDocument == NULL) return FALSE; OpBackgroundParam Param; Param.pBitmap = BitmapToApply; Param.pDoc = pDocument; Param.pSpread = ThePageDropInfo.pSpread; // Obtain a pointer to the op descriptor for the create operation OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_BACKGROUND); // Invoke the operation, passing in our parameters if (pOpDesc) pOpDesc->Invoke(&Param); } else { // Create a new bitmap on the page at the drop point // Obtain a pointer to the op descriptor for the create operation OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpCreateNodeBitmap)); if (OpDesc) { // Invoke the operation, passing DocView and Pos as parameters OpParam param((void *)BitmapToApply,(void *)&ThePageDropInfo); OpDesc->Invoke(¶m); } } } return TRUE; } /*********************************************************************************************** > SGDisplayKernelBitmap::SGDisplayKernelBitmap() Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Purpose: SGDisplayKernelBitmap constructor DON'T call this constructor. It ERROR3's. Call the other constructor ***********************************************************************************************/ SGDisplayKernelBitmap::SGDisplayKernelBitmap() { ERROR3("Illegal call on default SGDisplayKernelBitmap constructor - call the other one!"); TheKernelBitmap = NULL; } /*********************************************************************************************** > SGDisplayKernelBitmap::SGDisplayKernelBitmap(KernelBitmap *KernelBitmapToDisplay) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Inputs: KernelBitmapToDisplay - The KernelBitmap this item will display Purpose: SGDisplayKernelBitmap constructor ***********************************************************************************************/ SGDisplayKernelBitmap::SGDisplayKernelBitmap(KernelBitmap *KernelBitmapToDisplay) { ERROR3IF(KernelBitmapToDisplay == NULL, "SGDisplayKernelBitmap - trying to construct me with a NULL parameter is bad"); TheKernelBitmap = KernelBitmapToDisplay; } /*********************************************************************************************** > virtual void SGDisplayKernelBitmap::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Inputs: FormatInfo - The formatting info from which to calculate my position/size MiscInfo - As usual, the useful misc info struct Outputs: member variable FormatRect - is returned filled in with the size/position of this KernelBitmap item's display area. This is dependent upon the current display mode and format state FormatInfo will be updated as a result of the formatting operation Purpose: Shared code for KernelBitmap items to calculate where they will appear in the grand scheme of things Notes: KernelBitmaps supply only one display mode ("full info") Scope: private (for use of SGDisplayKernelBitmap class only) ***********************************************************************************************/ void SGDisplayKernelBitmap::CalculateMyRect(SGFormatInfo *FormatInfo, SGMiscInfo *MiscInfo) { INT32 XSize; INT32 YSize; switch (MiscInfo->DisplayMode) { case 1: // 1 - Small full info XSize = GridLock(MiscInfo, SG_InfiniteWidth); YSize = GridLock(MiscInfo, SG_DefaultSmallBmp); break; case 2: // 2 - Large icon with name XSize = GridLock(MiscInfo, SG_DefaultLargeBmpText); YSize = GridLock(MiscInfo, SG_DefaultLargeBmp); break; default: // 0 - Full Info XSize = GridLock(MiscInfo, SG_InfiniteWidth); YSize = GridLock(MiscInfo, SG_DefaultLargeBmp); break; } BitmapInfo Info; INT32 MaxYSize = YSize; if (TheKernelBitmap->ActualBitmap && TheKernelBitmap->ActualBitmap->GetInfo( &Info ) ) { // We will adjust the Height of the format rect // according to the Height of the bitmap. double BitmapWidth = Info.RecommendedWidth; double BitmapHeight = Info.RecommendedHeight; // Calculate the spect ratio of the bitmap double Ratio = BitmapHeight/BitmapWidth; YSize = INT32(YSize * Ratio); // ... set a minimum height for each item INT32 SelHeight = 16000; if (YSize < SelHeight*3) YSize = SelHeight*3; if (YSize > MaxYSize) YSize = MaxYSize; } CalculateFormatRect(FormatInfo, MiscInfo, XSize, YSize); } /*********************************************************************************************** > virtual void SGDisplayKernelBitmap::HandleRedraw(SGRedrawInfo *RedrawInfo, SGFormatInfo *FormatInfo) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) 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: SGDisplayKernelBitmap item redraw method - removed from the main HandleEvent method merely to make the code tidier. Scope: private ***********************************************************************************************/ void SGDisplayKernelBitmap::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo) { if (TheKernelBitmap == NULL || TheKernelBitmap->ActualBitmap == NULL) return; StartRendering(RedrawInfo, MiscInfo); DocRect MyRect(FormatRect); // Get my redraw position from the cached FormatRect // Is this a valid format rectangle ? if (MyRect.IsEmpty() || !MyRect.IsValid()) { // No, so just ignore it // Erroring here is not good, as we are in the middle of a redraw loop StopRendering(RedrawInfo, MiscInfo); return; } // Check the rectangle is at least our minimum height, // and adjust it if not //INT32 SelHeight = 16000; // Changed to allow a third line of text. INT32 SelHeight = 23000; if (MyRect.Height() < SelHeight*3) { INT32 diff = SelHeight*3 - MyRect.Height(); MyRect.Inflate(0, diff); } RenderRegion *Renderer = RedrawInfo->Renderer; INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1); INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2); INT32 ThreePixels = (INT32) DevicePixels(MiscInfo, 3); Renderer->SetLineWidth(0); Renderer->SetLineColour(RedrawInfo->Transparent); // Now calculate the rectangle to plot the bitmap into DocRect IconRect(MyRect); BitmapInfo Info; BOOL bScaleDown = FALSE; if (TheKernelBitmap->ActualBitmap && TheKernelBitmap->ActualBitmap->GetInfo( &Info )) { // We will try and make all the bitmaps the same width on screen. double BitmapWidth = Info.RecommendedWidth; double BitmapHeight = Info.RecommendedHeight; // Calculate the spect ratio of the bitmap double Ratio = BitmapWidth/BitmapHeight; INT32 IconWidth = INT32(IconRect.Height() * Ratio); INT32 YSize; switch (MiscInfo->DisplayMode) { case 1: // 1 - Small full info YSize = GridLock(MiscInfo, SG_DefaultSmallBmp); break; case 2: // 2 - Large icon with name YSize = GridLock(MiscInfo, SG_DefaultLargeBmp); break; default: // 0 - Full Info YSize = GridLock(MiscInfo, SG_DefaultLargeBmp); break; } // If the bitmap is very Wide and Thin, then we need to scale it // so it fits into out maximum icon width if (IconWidth > YSize) { Matrix Scale; Ratio = double(IconWidth)/double(YSize); Scale = Matrix(FIXED16(1)/Ratio, FIXED16(1)/Ratio); DocCoord Centre; Centre.x = IconRect.lo.x; Centre.y = IconRect.lo.y + IconRect.Height()/2; // Scale the bitmap rectangle about the Left Middle so // that it is always 'YSize' in Width IconRect.Translate(-Centre.x, -Centre.y); Scale.transform(&IconRect.lo); Scale.transform(&IconRect.hi); IconRect.Translate(Centre.x, Centre.y); IconWidth = YSize; bScaleDown = TRUE; } INT32 RightSpace = 0; if (IconWidth < YSize) { INT32 LeftSpace = TwoPixels * 4; RightSpace = YSize - IconWidth - LeftSpace; IconRect.Translate(LeftSpace, 0); // Move it over a bit } // Now setup the IconRect IconRect.hi.x = IconRect.lo.x + IconWidth; MyRect.lo.x = IconRect.hi.x + RightSpace + TwoPixels; // And exclude it from 'MyRect' MyRect.lo.x += TwoPixels; // Now check the Icon isn't too tall INT32 MaxYSize = YSize; INT32 IconHeight = IconRect.Height(); if (IconHeight > MaxYSize) { Matrix Scale; Ratio = double(IconHeight)/double(YSize); Scale = Matrix(FIXED16(1)/Ratio, FIXED16(1)/Ratio); DocCoord Centre; Centre.x = IconRect.lo.x + IconRect.Width()/2; Centre.y = IconRect.hi.y; // Scale the bitmap rectangle about the Middle so // that it is always 'YSize' in Height IconRect.Translate(-Centre.x, -Centre.y); Scale.transform(&IconRect.lo); Scale.transform(&IconRect.hi); IconRect.Translate(Centre.x, Centre.y); MyRect.lo.y = IconRect.lo.y; MyRect.hi.y = IconRect.hi.y; bScaleDown = TRUE; } } // This section doesn't currently do anything special as we // have gone back to using an OSRenderRegion // If the display quality is too bad then we should modify // this code to render a high quality thumbnail and store it // for future use, rendering the thumbnail into an OSRenderRegion /* Renderer->SetUsingSmoothedBitmaps(bScaleDown); if (bScaleDown) { Quality qual; qual.SetQuality(QUALITY_MAX); QualityAttribute *pQuality = new QualityAttribute(qual); Renderer->SetQuality(pQuality, TRUE); // Temp } else { Quality qual; // QUALITY_DEFAULT is implied QualityAttribute *pQuality = new QualityAttribute(qual); Renderer->SetQuality(pQuality, TRUE); // Temp }*/ GridLockRect(MiscInfo, &MyRect); // Ensure the new 'MyRect' is pixel-grid-aligned // If we can, we need to leave a little space around the // edges of the bitmap rect, so we can see the 'Selected' rectangle // behind it. We only try this if the rectangle is big enough // otherwise the Inflate routine will create an invalid rectangle. if (IconRect.Height() > ThreePixels * 2) IconRect.Inflate(0, -ThreePixels); // Leave a bit of space around the edge if (IconRect.Width() > ThreePixels * 2) IconRect.Inflate(-ThreePixels, 0); // Leave a bit of space around the edge GridLockRect(MiscInfo, &IconRect); // Ensure it maps exactly to specific pixels // Need to remember the icon rect size before the selection rectangle takes over... DocRect ThumbnailRect(IconRect); // In the bitmap gallery, it's better to show something than nothing // So if the thumbnail has become so thin as to be invisible // We will bodge it back into shape even if that distorts things a bit if (ThumbnailRect.Width()==0) ThumbnailRect.hi.x = ThumbnailRect.lo.x + OnePixel; if (ThumbnailRect.Height()==0) ThumbnailRect.hi.y = ThumbnailRect.lo.y + OnePixel; // Set up the colours for rendering our text, and fill the background if selected if (Flags.Selected) { // This Item is 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(RedrawInfo->SelBackground); Renderer->SetFillColour(COLOUR_BLACK); IconRect.Inflate(ThreePixels); // Draw a Three Pixel wide rectangle around the edge of the bitmap // (Actually we're plotting a filled rectangle which is three pixels // bigger than the bitmap rectangle) Renderer->DrawRect(&IconRect); // If the icon rect is wider than the gallery, then MyRect could have become invalid, // so we only try to draw the selection background if any of it is actually visible if (MyRect.IsValid()) { DocRect SelRect(MyRect); if (SelHeight > MyRect.Height()/2) SelHeight = MyRect.Height()/2; SelRect.hi.y = MyRect.lo.y + MyRect.Height()/2 + SelHeight; SelRect.lo.y = MyRect.lo.y + MyRect.Height()/2 - SelHeight; SelRect.lo.x += ThreePixels; GridLockRect(MiscInfo, &SelRect); // Ensure it maps exactly to specific pixels Renderer->SetFillColour(RedrawInfo->SelBackground); Renderer->DrawRect(&SelRect); } Renderer->SetFixedSystemTextColours(&RedrawInfo->SelForeground, &RedrawInfo->SelBackground); } else { // This Item is Not Selected Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background); } #ifdef SGBITMAP_BACKGROUND_REDRAW BOOL DrawnBitmap = FALSE; if (ShouldIDrawForeground(DrawnBitmap)) { if(!DrawnBitmap) { // Now we need to create a temporary NodeBitmap, which we will // use to render the bitmap preview. NodeBitmap* DummyBmp = new NodeBitmap(); if (DummyBmp == NULL) { // Just exit if we're out of memory SGLibDisplayItem::DrawNullBitmapRect(Renderer, MiscInfo, &ThumbnailRect, FALSE); StopRendering(RedrawInfo, MiscInfo); return; } // Set the NodeBitmap path to be our IconRect, // and attach the Bitmap to it. DummyBmp->SetUpPath(); DummyBmp->CreateShape(ThumbnailRect); DummyBmp->GetBitmapRef()->SetBitmap(TheKernelBitmap); // Now render the bitmap preview DummyBmp->Render(Renderer); delete DummyBmp; } } else { // We should background render, so we just draw a blank grey box if(!DrawnBitmap) SGLibDisplayItem::DrawNullBitmapRect(Renderer, MiscInfo, &ThumbnailRect, TRUE); } #else // Now we need to create a temporary NodeBitmap, which we will // use to render the bitmap preview. NodeBitmap* DummyBmp = new NodeBitmap(); if (DummyBmp == NULL) { // Just exit if we're out of memory StopRendering(RedrawInfo, MiscInfo); return; } // Set the NodeBitmap path to be our IconRect, // and attach the Bitmap to it. DummyBmp->SetUpPath(); DummyBmp->CreateShape(ThumbnailRect); DummyBmp->GetBitmapRef()->SetBitmap(TheKernelBitmap); // Now render the bitmap preview DummyBmp->Render(Renderer); delete DummyBmp; #endif // Leave a small gap before text begins MyRect.lo.x += SG_GapBeforeText*2; // And now render the text describing the bitmap // ...but only if there is any space left (i.e. MyRect is still valid) if (MyRect.IsValid()) { // First get the name of the bitmap String_256 BitmapName = TheKernelBitmap->ActualBitmap->GetName(); // Now find how many colours it has String_256 BitmapCols; INT32 bpp = TheKernelBitmap->GetBPP(); BOOL HasTransparency = FALSE; if (bpp <= 8) { // Check to see if this is a masked bitmap INT32 Index; if (TheKernelBitmap->GetTransparencyIndex(&Index)) HasTransparency = TRUE; } switch (bpp) { case 1: if (HasTransparency) BitmapCols = _R(IDS_SGBITMAP_MONOCHROME_T); // "Monochrome, transparent"; else BitmapCols = _R(IDS_SGBITMAP_MONOCHROME); // "Monochrome"; break; case 2: if (HasTransparency) BitmapCols = _R(IDS_SGBITMAP_4COLOURS_T); // "3 colours, transparent"; else BitmapCols = _R(IDS_SGBITMAP_4COLOURS); // "4 colours"; break; case 4: if (HasTransparency) BitmapCols = _R(IDS_SGBITMAP_16COLOURS_T); // "15 colours, transparent"; else BitmapCols = _R(IDS_SGBITMAP_16COLOURS); // "16 colours"; break; case 8: if (HasTransparency) BitmapCols = _R(IDS_SGBITMAP_256COLOURS_T); // "255 colours, transparent"; else BitmapCols = _R(IDS_SGBITMAP_256COLOURS); // "256 colours"; break; case 16: BitmapCols = _R(IDS_SGBITMAP_65COLOURS); // "65K colours"; break; case 24: BitmapCols = _R(IDS_SGBITMAP_MILLIONS_COLOURS); // "Millions of colours"; break; case 32: BitmapCols = _R(IDS_SGBITMAP_32_BIT); // "Millions of colours"; break; default: BitmapCols = ""; break; } // Now get its pixel Width and Height String_256 BitmapWidth; Convert::LongToString(Info.PixelWidth, &BitmapWidth); String_256 BitmapHeight; Convert::LongToString(Info.PixelHeight, &BitmapHeight); // Find the delay value; UINT32 BitmapDelay = TheKernelBitmap->ActualBitmap->GetBitmapAnimDelay(); String_256 Delay; Convert::LongToString(BitmapDelay, &Delay); // And finally, work out how much memory it is using // The memory size depends on whether this is a bitmap or JPEG. INT32 Bytes = 0; BitmapSource* pSource = NULL; BaseBitmapFilter* pDummyFilter; PORTNOTE("other", "Removed XPE hook") #ifndef EXCLUDE_FROM_XARALX KernelBitmap* pMaster = NULL; IXMLDOMDocumentPtr pEdits = NULL; TheKernelBitmap->GetXPEInfo(pMaster, pEdits); BOOL bIsXPE = (pMaster!=NULL && pEdits!=NULL); #else BOOL bIsXPE = FALSE; #endif BOOL OriginalSourcePresent = TheKernelBitmap->GetOriginalSource(&pSource, &pDummyFilter); String_256 BitmapFormat; if(OriginalSourcePresent) { if (pSource != NULL) { if (pSource->IsJPEG()) { Bytes = pSource->GetSize(); BitmapFormat = _R(IDS_FORMAT_JPEG); } } } else if (bIsXPE) { BitmapFormat = _R(IDS_FORMAT_XPE); } else { Bytes = (Info.PixelWidth * Info.PixelHeight * bpp)/8; BitmapFormat = _R(IDS_FORMAT_BITMAP); } String_256 MemoryUsed; Convert::BytesToString(&MemoryUsed, Bytes); if (!BaseCamelotFilter::ShouldSaveXPEBitmaps() && bIsXPE) { // If the bitmap is generated from a Master and edit list // Then don't show size in bytes 'cos it's meaningless MemoryUsed.Load(_R(IDS_SGBITMAP_XPE)); } // Now we are going to plot all that information // split into two lines of text DocRect TopRect(MyRect); DocRect MiddleRect(MyRect); DocRect BottomRect(MyRect); //TopRect.lo.y += 11000; TopRect.lo.y += 18000; MiddleRect.hi.y -= 5000; //MiddleRect.hi.y -= 16000; Down BottomRect.hi.y -= 26000; // Plot the Name and Memory used on the Top Line String_256 TopLine; // = "'"+BitmapName+"', "+BitmapFormat", "+MemoryUsed; TopLine.MakeMsg(_R(IDS_SGBITMAP_FULLINFO_TOPLINE),(TCHAR *)BitmapName,(TCHAR*)BitmapFormat,(TCHAR *)MemoryUsed); Renderer->DrawFixedSystemText(&TopLine, TopRect); // Plot the Dimensions and Colours on the Bottom Line String_256 MiddleLine; // = BitmapWidth+" by "+BitmapHeight+" pixels, "+BitmapCols; // Calculate the dpi of the original winbitmap... UINT32 hdpi = TheKernelBitmap->ActualBitmap->GetHorizontalDPI(); UINT32 vdpi = TheKernelBitmap->ActualBitmap->GetVerticalDPI(); if (hdpi == vdpi) { String_256 dpitext; Convert::LongToString(hdpi, &dpitext); MiddleLine.MakeMsg(_R(IDS_SGBITMAP_FULLINFO_BOTTOMLINE), (TCHAR *)BitmapWidth, (TCHAR *)BitmapHeight, (TCHAR *)BitmapCols, (TCHAR *)dpitext); } else { String_256 dpitext; camSnprintf(dpitext, 256, _T("%u x %u"), hdpi, vdpi); MiddleLine.MakeMsg(_R(IDS_SGBITMAP_FULLINFO_BOTTOMLINE), (TCHAR *)BitmapWidth, (TCHAR *)BitmapHeight, (TCHAR *)BitmapCols, (TCHAR *)dpitext); } Renderer->DrawFixedSystemText(&MiddleLine, MiddleRect); // Find the Restore type GIFDisposalMethod RestoreType = TheKernelBitmap->ActualBitmap->GetAnimationRestoreType(); switch(RestoreType) { case GDM_NONE: { String_256 BottomLine; String_256 Nothing(_R(IDS_NOTHING)); BottomLine.MakeMsg(_R(IDS_SGBITMAP_DELAY_RESTORE_BOTTOMLINE), (TCHAR*)Delay, (TCHAR*)Nothing); Renderer->DrawFixedSystemText(&BottomLine, BottomRect); } break; case GDM_LEAVE: { String_256 BottomLine; String_256 Leave(_R(IDS_LEAVE)); BottomLine.MakeMsg(_R(IDS_SGBITMAP_DELAY_RESTORE_BOTTOMLINE), (TCHAR*)Delay, (TCHAR*)Leave); Renderer->DrawFixedSystemText(&BottomLine, BottomRect); } break; case GDM_BACKTOBACK: { String_256 BottomLine; String_256 Back(_R(IDS_BACKGROUND)); BottomLine.MakeMsg(_R(IDS_SGBITMAP_DELAY_RESTORE_BOTTOMLINE), (TCHAR*)Delay, (TCHAR*)Back); Renderer->DrawFixedSystemText(&BottomLine, BottomRect); } break; case GDM_PREVIOUS: { String_256 BottomLine; String_256 Previous(_R(IDS_PREVIOUS)); BottomLine.MakeMsg(_R(IDS_SGBITMAP_DELAY_RESTORE_BOTTOMLINE), (TCHAR*)Delay, (TCHAR*)Previous); Renderer->DrawFixedSystemText(&BottomLine, BottomRect); } break; default: break; } } StopRendering(RedrawInfo, MiscInfo); } /*********************************************************************************************** > virtual void SGDisplayKernelBitmap::DragWasReallyAClick(SGMouseInfo *Mouse, SGMiscInfo *MiscInfo) Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Inputs: Mouse - The mouse info passed to the original click handler MiscInfo - The misc info passed to the original click handler Purpose: Handles a mouse click event. This is a callback function - drags of bitmaps from galleries will call this function back if the drag turns out to just be a click. SeeAlso: SGDisplayKernelBitmap::HandleEvent; GalleryBitmapDragInfo::OnClick ***********************************************************************************************/ void SGDisplayKernelBitmap::DragWasReallyAClick(SGMouseInfo *Mouse, SGMiscInfo *MiscInfo) { // Just get default selection action to be applied for this click DefaultClickHandler(Mouse, MiscInfo, TRUE); } /*********************************************************************************************** > virtual BOOL SGDisplayKernelBitmap::HandleEvent(SGEventType EventType, void *EventInfo, SGMiscInfo *MiscInfo) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) 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 SGDisplayKernelBitmap::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); if (FormatRect.ContainsCoord(Mouse->Position)) { // If the colour is in the selected document, then it is safe to // do a colour drag - for now, it will only allow drags for the // selected doc. // Otherwise, the normal click action takes place. // If the drag fails (turns into a click) then the normal click action // takes place, passed on by the GalleryColourDragInfo::OnClick handler // SGDisplayGroup *Parent = (SGDisplayGroup *) GetParent(); if (Mouse->DoubleClick) // || Parent->GetParentDocument() != Document::GetSelected()) { // Send bitmap to Xara Photo Editor /* OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_XPE_EDIT); if (pOpDesc) { pOpDesc->Invoke(); return TRUE; } else */ DefaultClickHandler(Mouse, MiscInfo); } else { DefaultPreDragHandler(Mouse, MiscInfo); GalleryBitmapDragInfo *DragBmp; DragBmp = new GalleryBitmapDragInfo(this, Mouse, MiscInfo, Mouse->MenuClick); if (DragBmp != NULL) DragManagerOp::StartDrag(DragBmp, GetListWindow()); } return(TRUE); // Claim this event - nobody else can own this click } } break; default: 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); } /******************************************************************************************** > virtual void SGDisplayKernelBitmap::GetNameText(String_256 *Result) Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Outputs: On exit, the string pointed at by Result will contain either a blank string, or the name text associated with this item (if any) Purpose: To determine a name string for this node. Generally, this is used for a simple mechanism which searches for display items whose names match given search parameters in some way. It is also used in libraries to provide default redraw methods. SeeAlso: SGDisplayKernelBitmap::GetFullInfoText ********************************************************************************************/ void SGDisplayKernelBitmap::GetNameText(String_256 *Result) { ERROR3IF(Result == NULL, "Illegal NULL param"); *Result = TheKernelBitmap->ActualBitmap->GetName(); } /******************************************************************************************** > virtual void SGDisplayKernelBitmap::GetFullInfoText(String_256 *Result) Author: Will_Cowling (Xara Group Ltd) Created: 19/3/95 Outputs: On exit, the string pointed at by Result will contain either a blank string, or the full-information text associated with this item (if any) Purpose: To determine a full-info string for this node. Generally, this is used for a simple mechanism which searches for display items whose info matches given search parameters in some way. It is also used in libraries to provide default redraw methods. SeeAlso: SGDisplayKernelBitmap::GetNameText ********************************************************************************************/ void SGDisplayKernelBitmap::GetFullInfoText(String_256 *Result) { ERROR3IF(Result == NULL, "Illegal NULL param"); *Result = TheKernelBitmap->ActualBitmap->GetName(); } /*********************************************************************************************** > virtual void SGDisplayKernelBitmap::MoveAfter(SGDisplayNode *NodeToMove) Author: Will_Cowling (Xara Group Ltd) Created: 30/3/95 Inputs: NodeToMove - the node to move Purpose: MOVES the given node (to a different position in the DisplayTree) as the previous (left) sibling of this node. If the node is not linked into a tree, it is effectively just inserted. Notes: This base class method simply delinks the item and relinks it elsewhere in the display tree. However, derived classes will override this method so that moving display items can have a further effect of also rearranging the displayed "real" items. Before/After moving the real item, the derived class can then call this baseclass method to complete the action. Take care when moving items between groups (e.g. if an item is "moved" from one docuemnt to another, it could be a bad thing, so be very careful in derived classes to take appropriate action) Any attempt to move an item after *itself* is queitly ignored Errors: ERROR3 and quiet exit if NodeToMove == NULL SeeAlso: SGDisplayKernelBitmap::MoveBefore ***********************************************************************************************/ void SGDisplayKernelBitmap::MoveAfter(SGDisplayNode *NodeToMove) { ERROR3IF(NodeToMove == NULL, "Illegal NULL param"); if (NodeToMove == this) return; KernelBitmap *BitmapToMove = ((SGDisplayKernelBitmap *) NodeToMove)->GetDisplayedKernelBitmap(); ERROR3IF(BitmapToMove == NULL, "NULL displayed bitmap?!"); Document *ScopeDoc = ((SGDisplayGroup *) GetParent())->GetParentDocument(); ERROR3IF(ScopeDoc == NULL, "No parent document?!"); if ( ((SGDisplayGroup *) ( ((SGDisplayKernelBitmap *)NodeToMove)->GetParent() ) )->GetParentDocument() != ScopeDoc) { ERROR2RAW("Attempt to MOVE a bitmap between documents!"); return; } BitmapSGallery::IgnoreBmpListChange = TRUE; // And get the bitmap list BitmapList* BmpList = ScopeDoc->GetBitmapList(); ERROR3IF(BmpList == NULL, "A document with no bitmap list?!"); BmpList->MoveAfter(GetDisplayedKernelBitmap(), BitmapToMove); SGDisplayNode::MoveAfter(NodeToMove); BitmapSGallery::IgnoreBmpListChange = FALSE; } /*********************************************************************************************** > virtual void SGDisplayKernelBitmap::MoveBefore(SGDisplayNode *NodeToMove) Author: Will_Cowling (Xara Group Ltd) Created: 30/3/95 Inputs: NodeToMove - the node to move Purpose: MOVES the given node (to a different position in the DisplayTree) as the previous (left) sibling of this node. If the node is not linked into a tree, it is effectively just inserted. Notes: This base class method simply delinks the item and relinks it elsewhere in the display tree. However, derived classes will override this method so that moving display items can have a further effect of also rearranging the displayed "real" items. Before/After moving the real item, the derived class can then call this baseclass method to complete the action. Take care when moving items between groups (e.g. if an item is "moved" from one docuemnt to another, it could be a bad thing, so be very careful in derived classes to take appropriate action) Any attempt to move an item Before *itself* is queitly ignored Errors: ERROR3 and quiet exit if NodeToMove == NULL SeeAlso: SGDisplayKernelBitmap::MoveBefore ***********************************************************************************************/ void SGDisplayKernelBitmap::MoveBefore(SGDisplayNode *NodeToMove) { ERROR3IF(NodeToMove == NULL, "Illegal NULL param"); if (NodeToMove == this) return; KernelBitmap *BitmapToMove = ((SGDisplayKernelBitmap *) NodeToMove)->GetDisplayedKernelBitmap(); ERROR3IF(BitmapToMove == NULL, "NULL displayed bitmap?!"); Document *ScopeDoc = ((SGDisplayGroup *) GetParent())->GetParentDocument(); ERROR3IF(ScopeDoc == NULL, "No parent document?!"); if ( ((SGDisplayGroup *) ( ((SGDisplayKernelBitmap *)NodeToMove)->GetParent() ) )->GetParentDocument() != ScopeDoc) { ERROR2RAW("Attempt to MOVE a bitmap between documents!"); return; } BitmapSGallery::IgnoreBmpListChange = TRUE; // And get the bitmap list BitmapList* BmpList = ScopeDoc->GetBitmapList(); ERROR3IF(BmpList == NULL, "A document with no bitmap list?!"); BmpList->MoveBefore(GetDisplayedKernelBitmap(), BitmapToMove); SGDisplayNode::MoveBefore(NodeToMove); BitmapSGallery::IgnoreBmpListChange = FALSE; } /******************************************************************************************** > virtual BOOL SGDisplayKernelBitmap::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result) Author: Will_Cowling (Xara Group Ltd) Created: 9/7/95 Inputs: MousePos - The current mouse position. This will generally be expected to lie inside this item's FormatRect. With it, this item can provide help on specific areas of an item. Outputs: On exit, if the return value is TRUE, the string pointed at by Result will contain a status line help string for this item Returns: TRUE if it filled in the string, FALSE if it did not Purpose: Called by the parent gallery when status line help is needed. The parent gallery will do a hit test to determine which node contains the pointer, and will then ask that node to supply bubble/status-line help. Notes: The base class returns FALSE (i.e. provides no help) If you can provide help, then override the base class method to do so. ********************************************************************************************/ BOOL SGDisplayKernelBitmap::GetStatusLineHelp(DocCoord *MousePos, String_256 *Result) { ERROR3IF(MousePos == NULL || Result == NULL, "Invalid NULL params"); String_256 Name; GetNameText(&Name); // "'Bitmapname'" Result->MakeMsg(_R(IDS_SGBITMAP_STATLINE), (TCHAR *)Name); /* Double click, or drag and drop to apply as a fill*/ *Result += String_256(_R(IDS_SGBITMAP_DOUBLE_CLICK)); //"; Double click, or drag and drop to apply this bitmap"); return(TRUE); } /******************************************************************************************** > BitmapSGallery::BitmapSGallery() Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Purpose: BitmapSGallery default constructor ********************************************************************************************/ BitmapSGallery::BitmapSGallery() { DlgResID = _R(IDD_BITMAPSGALLERY); // WEBSTER - markn 9/12/96 // Default gallery size #ifdef WEBSTER CSize Size(333, 256); SetGallerySize(Size); #endif } /******************************************************************************************** > BitmapSGallery::~BitmapSGallery() Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Purpose: BitmapSGallery destructor. ********************************************************************************************/ BitmapSGallery::~BitmapSGallery() { } /******************************************************************************************** > void BitmapSGallery::CreateNewSubtree(Document *ParentDoc, SGDisplayGroup *ExistingGroup) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) 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 KernelBitmap 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 BitmapSGallery::CreateNewSubtree(Document *ParentDoc, SGDisplayGroup *ExistingGroup) { ERROR3IF(ParentDoc == NULL, "BitmapSGallery::CreateNewSubtree - NULL parameter passed in"); if (ParentDoc == NULL || DisplayTree == NULL) return; SGDisplayGroup *DisplayDocument; SGDisplayKernelBitmap *DisplayKernelBitmap; if (ExistingGroup != NULL) { ERROR3IF(ExistingGroup->GetParentDocument() != ParentDoc, "This group is not for that document! What's going down, dude?"); DisplayDocument = ExistingGroup; // Use existing group DisplayDocument->DestroySubtree(FALSE); // Wipe any existing KernelBitmap display items } else { DisplayDocument = new SGDisplayGroup(this, ParentDoc,NULL); // Create new Group if (DisplayDocument == NULL) // Total failure - abort return; DisplayDocument->Flags.CanSelect = TRUE; // Groups are selectable DisplayTree->AddItem(DisplayDocument); // Add new group to tree } // Lets generate some SGDisplayKernelBitmaps to be displayed ... // Get the bitmap list BitmapList* Bitmaps = ParentDoc->GetBitmapList(); // now iterate though the list, creating display items for each bitmap KernelBitmap* Ptr = (KernelBitmap*)Bitmaps->GetHead(); while (Ptr != NULL) { // Ignore bitmaps that have been deleted if (!Ptr->GetActualBitmap()->IsHiddenInGallery()) { DisplayKernelBitmap = new SGDisplayKernelBitmap(Ptr); if (DisplayKernelBitmap != NULL) DisplayDocument->AddItem(DisplayKernelBitmap); } Ptr = (KernelBitmap*)Bitmaps->GetNext(Ptr); } } /******************************************************************************************** > BOOL BitmapSGallery::PreCreate(void) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Returns: TRUE if the Gallery initialised successfully FALSE if it should not be opened due to a failure to initialise Purpose: The BitmapSGallery PreCreate handler. This overrides the base class PreCreate function. It is called at the very end of the SuperGallery::Create method, after the window has been created. ********************************************************************************************/ BOOL BitmapSGallery::PreCreate(void) { // If there isn't already one, create a DisplayTree if (DisplayTree == NULL) { DisplayTree = new SGDisplayRootScroll(this); // New root node, with a scrollbar if (DisplayTree == NULL) return(FALSE); } // Next, call CreateNewSubtree to scan all the available documents and build a // display list for each of them. Document *ParentDoc = (Document *) GetApplication()->Documents.GetTail(); while (ParentDoc != NULL) { SGDisplayNode *Ptr = DisplayTree->FindSubtree(this, ParentDoc, NULL); CreateNewSubtree(ParentDoc, (SGDisplayGroup *) Ptr); ParentDoc = (Document *) GetApplication()->Documents.GetPrev(ParentDoc); } // We're opening the window, so we fold all groups except that for the Selected document SGDisplayGroup *Group = (SGDisplayGroup *) DisplayTree->GetChild(); while (Group != NULL) { // Set the group's folded state, but don't bother trying to redraw, because we know // that the window is not currently visible, and that we are doing this to multiple groups. Group->SetFoldedState((Group->GetParentDocument() != Document::GetSelected()), FALSE); Group = (SGDisplayGroup *) Group->GetNext(); } return(TRUE); } /******************************************************************************************** > void BitmapSGallery::SetSelectionFromDocument(BOOL AlwaysScroll = FALSE) Author: Will_Cowling (Xara Group Ltd) Created: 30/8/96 (copied from ColourGallery) Inputs: AlwaysScroll - TRUE if you always want to autoscroll, regardless of the preference setting. (This is used when opening the gallery, as there is no point in not auto-scrolling somewhere useful) Purpose: Sets the bitmap gallery listbox selection state based upon the currently selected object(s) in the document. Scope: private ********************************************************************************************/ void BitmapSGallery::SetSelectionFromDocument(BOOL AlwaysScroll) { if (DisplayTree == NULL || !IsVisible()) return; SGDisplayGroup *DocGroup = DisplayTree->FindSubtree(this, Document::GetSelected(), NULL); SelectItems(FALSE); // Clear the current selection // This needs to be a preference if we ever make this gallery show the // currently selected bitmaps. BOOL AutoScrollSelection = FALSE; DocRect ScrollToRect; BOOL HaveSelected = FALSE; BOOL ScrollToBottom = FALSE; // TRUE if it is more important that the bottom of // ScrollToRect, rather than the top, is visible if (DocGroup != NULL) ForceGroupFolded(DocGroup, FALSE); // Ensure group is unfolded ReformatNow(TRUE); // Ensure the tree format information is up to date if (AutoScrollSelection || AlwaysScroll) { if (AlwaysScroll && !HaveSelected && DocGroup != NULL) { // We didn't select anything in the gallery. In that case, scroll to the top // of the document display DocRect TempRect; //DocGroup->GetFormatRect(&TempRect); DocGroup->GetChildArea(&ScrollToRect); //ScrollToRect = ScrollToRect.Union(TempRect); HaveSelected = TRUE; ScrollToBottom = FALSE; } if (HaveSelected) ScrollToShow(&ScrollToRect, ScrollToBottom); } // scroll to make seln visible on screen SelectionHasChanged(); // Update for the new selection } /******************************************************************************************** > virtual SGDisplayItem *BitmapSGallery::CopyDisplayItem(SGDisplayItem *SourceItem, SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition = NULL) Author: Jason_Williams (Xara Group Ltd) Created: 14/3/95 Inputs: SourceItem - The item to copy elsewhere in the tree (see below) DestGroup - The group into which the item should be inserted TargetPosition - NULL (to add the copied item to the end of the sibling list), or points to an item BEFORE which the copied item will be inserted. Returns: NULL (failed) or a pointer to the new (copied) display item Purpose: "Copies" the existing node in the tree in an appropriate fashion. This method is normally called when a gallery-organising drag completes, and it is discovered that the dragged item(s) have been dragged to a different display group. Notes: This method should be overridden by derived galleries to provide appropriate behaviour (some galleries (e.g colour) will copy the real-item that the given display-item references to the new group (document), while other galleries (layer) may just move the item after all). Note the handy InsertCopiedItem and MoveBefore/After methods which are available to take all of the hard work out of copying/moving items! See the body of this method in the source code for example pseudocode. For real code, see the Colour Gallery (sgcolour.cpp) SeeAlso: SuperGallery::InsertCopiedItem; SGDisplayItem::MoveBefore; SGDisplayItem::MoveAfter; SGColour::CopyDisplayItem ********************************************************************************************/ SGDisplayItem *BitmapSGallery::CopyDisplayItem(SGDisplayItem *SourceItem, SGDisplayGroup *DestGroup, SGDisplayItem *TargetPosition) { ERROR3IF(SourceItem == NULL || DestGroup == NULL, "Illegal NULL param"); return(NULL); /**** Example psuedocode **** // Find the real item (Thingy) to be moved/copied Thingy *ThingyToCopy = ((SGDisplayThingy *)SourceItem)->GetDisplayedThingy(); if (we really want to copy the items, rather than just move them) { // Just copy the items... // First, copy the real-item associated with the display item ThingyType *NewThingy = new ThingyType(ThingyToCopy); // Add the copied item to your 'real item' list or whatever. DocThingyList = DestGroup->GetParentDocument()->FindThingyList(); if (TargetPosition == NULL) DocThingyList->AddTail(NewThingy); else { Thingy *TargetPos = ((SGDisplayThingy *)TargetPosition)->GetDisplayedThingy(); if (TargetPos == NULL) DocThingyList->AddTail(NewThingy); else DocThingyList->InsertBefore(TargetPos, NewThingy); } // Now, create a new display item for the copied Thingy, and call the // base class helper method to insert it as appropriate. SGDisplayThingy *NewThingyDisplayItem = new SGDisplayThingy(NewThingy); if (NewThingyDisplayItem != NULL) SuperGallery::InsertCopiedItem(NewThingyDisplayItem, DestGroup, TargetPosition); return(NewThingyDisplayItem); } else { // Just move the items // This code will be much the same as the above, but instead of copying the // real-item, you will have to move it as appropriate. Instead of making // a new DisplayItem to pass on to InsertCopiedItem, simply delink it from the // DisplayTree, and then pass it to InsertCopiedItem as follows: SourceItem->RemoveFromTree(); // Delink from current displaytree position SuperGallery::InsertCopiedItem(SourceItem, DestGroup, TargetPosition); return(SourceItem); } ****/ } KernelBitmap* BitmapSGallery::GetSelectedBitmap() { // 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); SGDisplayKernelBitmap *FirstSelected = NULL; // Lets see if any of our Items are selected Document *ParentDoc = (Document *) GetApplication()->Documents.GetHead(); while (ParentDoc != NULL) { SGDisplayGroup *DocGroup = DisplayTree->FindSubtree(this, ParentDoc, NULL); if (DocGroup != NULL) FirstSelected = (SGDisplayKernelBitmap *) DocGroup->FindNextSelectedItem(NULL); if (FirstSelected) break; ParentDoc = (Document *) GetApplication()->Documents.GetNext(ParentDoc); } KernelBitmap *SelectedBitmap = NULL; if (FirstSelected != NULL) { SelectedBitmap = FirstSelected->GetDisplayedKernelBitmap(); } return SelectedBitmap; } /******************************************************************************************** > virtual BOOL BitmapSGallery::ApplyAction(SGActionType Action) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) Inputs: Action - Indicates what action to apply Returns: TRUE to indicate successful handling of the action, or FALSE to indicate failure (NOTE that this is not necessarily an error, but may simply be that we don't support the given action. e.g. if we don't handle APPLYADJUST, we'll be called again with a normal APPLY call) Purpose: Applies certain conventional gallery actions (usually associated with gallery buttons, for new, edit, delete, etc) SeeAlso: SGActionType ********************************************************************************************/ BOOL BitmapSGallery::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); SGDisplayKernelBitmap *FirstSelected = NULL; // Lets see if any of our Items are selected Document *ParentDoc = (Document *) GetApplication()->Documents.GetHead(); while (ParentDoc != NULL) { SGDisplayGroup *DocGroup = DisplayTree->FindSubtree(this, ParentDoc, NULL); if (DocGroup != NULL) FirstSelected = (SGDisplayKernelBitmap *) DocGroup->FindNextSelectedItem(NULL); if (FirstSelected) break; ParentDoc = (Document *) GetApplication()->Documents.GetNext(ParentDoc); } KernelBitmap *SelectedBitmap = NULL; if (FirstSelected != NULL) { SelectedBitmap = FirstSelected->GetDisplayedKernelBitmap(); } // Now, process the action TO DO! - see Colour gallery for examples switch(Action) { case SGACTION_APPLY: if (SelectedBitmap != NULL) { // Fill colour selected so create a fill colour attribute NodeAttribute *Attrib = new AttrBitmapColourFill; if (Attrib == NULL) return(FALSE); ((AttrBitmapColourFill *)Attrib)->AttachBitmap(SelectedBitmap); // AttributeSelected knows what to do with a selected attribute AttributeManager::AttributeSelected(NULL, Attrib); } break; case SGACTION_DELETE: return DeleteSelection(); break; case SGACTION_SETOPTIONS: // Set values in the options dialogue as it is opened if (CurrentOptionsDlg == NULL) return(FALSE); // Display Modes CurrentOptionsDlg->AddDisplayModeName(_R(IDS_GALLERYDM_FULLINFO)); // 0 break; case SGACTION_DISPLAYMODECHANGED: if (DisplayMode < 0 || DisplayMode > 1) DisplayMode = 0; break; default: // Unknown/unsupported command (e.g. CREATE, APPLYADJUST), so we failed to do it return(FALSE); } return(TRUE); } /******************************************************************************************** > BOOL BitmapSGallery::DeleteSelection() Author: Will_Cowling (Xara Group Ltd) Created: 16/2/95 Purpose: Deletes the selected bitmaps. ********************************************************************************************/ BOOL BitmapSGallery::DeleteSelection() { INT32 ButtonPressed = 2; ButtonPressed = AskQuestion(_R(IDS_BMPGAL_BMPINUSE), _R(IDS_BMPGAL_KILL), _R(IDS_CANCEL), 0, 0, 2, 2); // CANCEL=default, CANCEL=cancel if (ButtonPressed == 2) // Delete was cancelled - return FALSE return(FALSE); if (ButtonPressed == 1) // Force-delete all items, so go ahead and delete { BOOL DeletedBitmaps = FALSE; IgnoreBmpListChange = TRUE; GlobalBitmapList* pGlobalBmpList = GetApplication()->GetGlobalBitmapList(); Document *ParentDoc = (Document *) GetApplication()->Documents.GetHead(); while (ParentDoc != NULL) { // Get the bitmap list BitmapList* pDocBitmaps = ParentDoc->GetBitmapList(); SGDisplayKernelBitmap* Selected = NULL; SGDisplayGroup *DocGroup = DisplayTree->FindSubtree(this, ParentDoc, NULL); if (DocGroup != NULL) Selected = (SGDisplayKernelBitmap *) DocGroup->FindNextSelectedItem(NULL); while (Selected != NULL) { KernelBitmap* SelectedBitmap = Selected->GetDisplayedKernelBitmap(); // Get the next one before we delete this one Selected = (SGDisplayKernelBitmap*)DocGroup->FindNextSelectedItem(Selected); // Is this Kernel bitmap pointer still valid ? if (!pDocBitmaps->IsEmpty() && pDocBitmaps->FindPosition(SelectedBitmap) != NOT_IN_LIST) { if (SelectedBitmap->ActualBitmap != OILBitmap::Default) { // Is this Actual bitmap pointer still valid ? if (!pGlobalBmpList->IsEmpty() && pGlobalBmpList->FindPosition(SelectedBitmap->ActualBitmap) != NOT_IN_LIST) { OpDeleteBitmap* pOp = new OpDeleteBitmap(); if (pOp) { pOp->DoDelete(SelectedBitmap->ActualBitmap); DeletedBitmaps = TRUE; } } } else { // Shouldn't we be using an error from the resource file here?? Error::SetError(0, _T("You cannot delete the Default Bitmap"),0); InformError(); } } } ParentDoc = (Document *) GetApplication()->Documents.GetNext(ParentDoc); } IgnoreBmpListChange = FALSE; if (DeletedBitmaps) { Document *ParentDoc = (Document *) GetApplication()->Documents.GetHead(); while (ParentDoc != NULL) { SGDisplayNode *Ptr = DisplayTree->FindSubtree(this, ParentDoc, NULL); CreateNewSubtree(ParentDoc, (SGDisplayGroup *) Ptr); ParentDoc = (Document *) GetApplication()->Documents.GetNext(ParentDoc); } // And force a redraw of the entire list ForceRedrawOfList(); SelectionHasChanged(); } } return TRUE; } /******************************************************************************************** > KernelBitmap* BitmapSGallery::CheckTextureBitmap(KernelBitmap* pBitmap) Author: Will_Cowling (Xara Group Ltd) Created: 16/2/95 Purpose: Checks a bitmap to see if can be applied as a texture, and gives the option to create a grey level version if not. ********************************************************************************************/ KernelBitmap* BitmapSGallery::CheckTextureBitmap(KernelBitmap* pBitmap) { return NodeBitmap::CheckGreyscaleBitmap(pBitmap, _R(IDS_BMPGAL_MAKEGREY), _R(IDS_BMPGAL_DOGREY)); /* if (!BfxALU::IsGreyscaleBitmap(pBitmap)) // Should do proper Grey Level check here { INT32 ButtonPressed = 1; ButtonPressed = AskQuestion(_R(IDS_BMPGAL_MAKEGREY), _R(IDS_BMPGAL_DOGREY), _R(IDS_CANCEL), 0, 0, 1, 1); // CANCEL=default, CANCEL=cancel if (ButtonPressed == 2) // Apply was cancelled - return NULL return NULL; if (ButtonPressed == 1) { // Make a new grey level version of the bitmap, and apply that instead ABFXMakeGreyscale GSBfx; KernelBitmap* pNewBitmap = GSBfx.GetProcessedBitmap(pBitmap); if (pNewBitmap == NULL) { InformError(); return NULL; } // We need to check the Document bitmap list to see if // there is already a grey-level version. BitmapList* pBmpList = pBitmap->GetParentBitmapList(); ListItem* pItem = pBmpList->GetHead(); while (pItem != NULL) { KernelBitmap* pBmp = (KernelBitmap*)pItem; if (pBmp->ActualBitmap != pNewBitmap->ActualBitmap && *pBmp->ActualBitmap == *pNewBitmap->ActualBitmap) { pNewBitmap->ActualBitmap->Detach(); delete pNewBitmap; return pBmp; } pItem = pBmpList->GetNext(pItem); } // There is no grey level version in this document, // but there might be one in another document somewhere // so we'll have a look in the global list. GlobalBitmapList* pGlobalBmpList = GetApplication()->GetGlobalBitmapList(); pItem = pGlobalBmpList->GetHead(); while (pItem != NULL) { OILBitmap* pBmp = (OILBitmap*)pItem; if (pBmp != pNewBitmap->ActualBitmap && *pBmp == *pNewBitmap->ActualBitmap) { pNewBitmap->ActualBitmap->Detach(); delete pNewBitmap; return new KernelBitmap(pBmp); } pItem = pGlobalBmpList->GetNext(pItem); } String_256 NewName = pBitmap->ActualBitmap->GetName(); NewName += " (Greyscale)"; pNewBitmap->ActualBitmap->SetName(NewName); return pNewBitmap; } } return pBitmap; */ } /******************************************************************************************** > virtual void BitmapSGallery::SelectionHasChanged(void); Author: Jason_Williams (Xara Group Ltd) Created: 27/1/95 Purpose: To inform the gallery that the selection has changed in some way. The base gallery class will do the following things: MonoOn - If the selection is not exactly one item, the following standard buttons are shaded: Apply, Redefine, Edit - If the selection is greater than 1 item, the New button will shade - If the selection is zero items, then the Delete button will shade MonoOff Notes: If this default action is unsuitable, derived galleries may override it. If they add their own special buttons, they may need to override this method to ensure that their buttons also behave correctly on sel change. This method is called after creation of the window (immediately after the PostCreate upcall) to ensure the window state is correct ********************************************************************************************/ void BitmapSGallery::SelectionHasChanged(void) { if (DisplayTree == NULL || AmShaded || !IsVisible()) return; INT32 Count = DisplayTree->GetSelectedItemCount(); EnableGadget(_R(IDC_BMPGAL_CREATE), (Count == 1)); EnableGadget(_R(IDC_BMPGAL_FILL), (Count == 1)); EnableGadget(_R(IDC_BMPGAL_TEXTURE), (Count == 1)); EnableGadget(_R(IDC_BMPGAL_XPE_EDIT), (Count == 1)); EnableGadget(_R(IDC_BMPGAL_TRACE), (Count == 1)); // EnableGadget(_R(IDC_BMPGAL_EFFECTS), (Count == 1)); #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present EnableGadget(_R(IDC_BMPGAL_PLUGINS), (Count == 1)); #endif EnableGadget(_R(IDC_BMPGAL_BACKGROUND), (Count == 1)); // Now that we handle multiple images we enable as long as there is a selection EnableGadget(_R(IDC_BMPGAL_SAVE), (Count > 0)); EnableGadget(_R(IDC_BMPGAL_PROPS),(Count > 0)); //#if _DEBUG // Now that we handle multiple images we enable as long as there is a selection EnableGadget(_R(IDC_BMPGAL_PREVIEW), (Count > 0)); //#endif if (Count == 1 && GetSelectedBitmap()->ActualBitmap == OILBitmap::Default) { EnableGadget(_R(IDC_GALLERY_DELETE), FALSE); } else { EnableGadget(_R(IDC_GALLERY_DELETE), (Count > 0)); } EnableGadget(_R(IDC_GALLERY_MENU), TRUE); } /*********************************************************************************************** > void BitmapSGallery::DoShadeGallery(BOOL ShadeIt) Author: Neville_Humphrys (Xara Group Ltd) Created: 4/7/97 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 BitmapSGallery::DoShadeGallery(BOOL ShadeIt) { // Shade any non-standard buttons that we have on the gallery EnableGadget(_R(IDC_BMPGAL_SAVE), !ShadeIt); EnableGadget(_R(IDC_BMPGAL_PROPS), !ShadeIt); EnableGadget(_R(IDC_BMPGAL_BACKGROUND), !ShadeIt); #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present EnableGadget(_R(IDC_BMPGAL_PLUGINS), !ShadeIt); #endif //#if _DEBUG EnableGadget(_R(IDC_BMPGAL_PREVIEW), !ShadeIt); //#endif EnableGadget(_R(IDC_BMPGAL_CREATE), !ShadeIt); EnableGadget(_R(IDC_BMPGAL_FILL), !ShadeIt); EnableGadget(_R(IDC_BMPGAL_TEXTURE), !ShadeIt); EnableGadget(_R(IDC_BMPGAL_TRACE), !ShadeIt); EnableGadget(_R(IDC_BMPGAL_XPE_EDIT), !ShadeIt); //EnableGadget(_R(IDC_BMPGAL_EFFECTS), !ShadeIt); } /******************************************************************************************** > virtual MsgResult BitmapSGallery::Message(Msg* Message) Author: Will_Cowling (Xara Group Ltd) Created: 27/1/95 (base generated in sgbase.cpp) 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 BitmapSGallery::Message(Msg* Message) { if (IS_OUR_DIALOG_MSG(Message)) { DialogMsg* Msg = (DialogMsg*)Message; KernelBitmap* SelectedBitmap; switch (Msg->DlgMsg) { case DIM_CREATE: SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAYBITMAPGALLERY), TRUE); SetSelectionFromDocument(TRUE); break; case DIM_CANCEL: SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAYBITMAPGALLERY), FALSE); break; case DIM_LFT_BN_CLICKED: if (FALSE) {} else if (Msg->GadgetID == _R(IDC_BMPGAL_CREATE)) { SelectedBitmap = GetSelectedBitmap(); if (SelectedBitmap != NULL) { PageDropInfo DropInfo; DropInfo.pDocView = DocView::GetSelected(); DropInfo.pDoc = Document::GetSelected(); DropInfo.pSpread = Document::GetSelectedSpread(); FindCentreInsertionPosition(&DropInfo.pSpread, &DropInfo.DropPos); // Obtain a pointer to the op descriptor for the create operation OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpCreateNodeBitmap)); // Invoke the operation, passing DocView and Pos as parameters OpParam param((void *)SelectedBitmap,(void *)&DropInfo); OpDesc->Invoke(¶m); } } else if (Msg->GadgetID == _R(IDC_BMPGAL_FILL)) { SelectedBitmap = GetSelectedBitmap(); if (SelectedBitmap != NULL) { // Fill colour selected so create a fill colour attribute NodeAttribute *Attrib = new AttrBitmapColourFill; if (Attrib == NULL) return(SuperGallery::Message(Message)); ((AttrBitmapColourFill *)Attrib)->AttachBitmap(SelectedBitmap); // AttributeSelected knows what to do with a selected attribute AttributeManager::AttributeSelected(NULL, Attrib); } } else if (Msg->GadgetID == _R(IDC_BMPGAL_TEXTURE)) { SelectedBitmap = GetSelectedBitmap(); if (SelectedBitmap != NULL) { SelectedBitmap = CheckTextureBitmap(SelectedBitmap); AttributeManager::HaveAskedAboutContoneColours = FALSE; AttributeManager::UserCancelledContoneColours = FALSE; if (SelectedBitmap == NULL) return(SuperGallery::Message(Message)); // Fill colour selected so create a fill colour attribute NodeAttribute *Attrib = new AttrBitmapTranspFill; if (Attrib == NULL) return(SuperGallery::Message(Message)); ((AttrBitmapTranspFill *)Attrib)->AttachBitmap(SelectedBitmap); // AttributeSelected knows what to do with a selected attribute AttributeManager::AttributeSelected(NULL, Attrib); } } PORTNOTE("other", "Remove XPE hooks") #ifndef EXCLUDE_FROM_XARALX else if (Msg->GadgetID == _R(IDC_BMPGAL_XPE_EDIT)) { SelectedBitmap = GetSelectedBitmap(); if (SelectedBitmap != NULL) { // Obtain a pointer to the op descriptor for the create operation OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(XPEEditItemOp)); // Invoke the operation, passing DocView and Pos as parameters OpParam param((void *)SelectedBitmap, NULL); OpDesc->Invoke(¶m); } } #endif else if (Msg->GadgetID == _R(IDC_BMPGAL_TRACE)) { SelectedBitmap = GetSelectedBitmap(); // WEBSTER-Martin-09/01/97 we don't trace stuff #ifndef WEBSTER if (SelectedBitmap != NULL) { TraceMsg::OpenOrUse(SelectedBitmap); } #endif //webster } /* else if (Msg->GadgetID == _R(IDC_BMPGAL_EFFECTS)) { SelectedBitmap = GetSelectedBitmap(); // WEBSTER-Martin-09/01/97 #ifndef WEBSTER if (SelectedBitmap != NULL) { BfxMsg::OpenOrUse(SelectedBitmap); } #endif //webster break; } */ else if (Msg->GadgetID == _R(IDC_BMPGAL_SAVE)) { // Generate a list of the selected bitmaps UINT32 ListSize = 0; KernelBitmap** pList = NULL; if (!GetSelectedBitmaps(&pList, &ListSize)) InformError(); else { if (ListSize != 0) { BmpDlgParam BmpDlgParam; GetBmpInfo(&BmpDlgParam); // Save the Bitmap deatils for use in the bitmap export code.# BmpDlgParam.SetBitmapList(pList); BmpDlgParam.SetListSize(ListSize); BitmapExportParam ExportList(ListSize, pList, &BmpDlgParam); // Invoke the export operation OpDescriptor* OpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpMenuExport)); OpDesc->Invoke(&ExportList); SetBmpInfo(&BmpDlgParam); ForceRedrawOfList(); } else ERROR3("No bitmaps were selected - how come the option wasn't greyed"); } if (pList != NULL) CCFree(pList); } else if (Msg->GadgetID == _R(IDC_BMPGAL_HELP)) { // HelpUserTopic(_R(IDH_Gallery_Bitmap)); HelpUserTopic(_R(IDS_HELPPATH_Gallery_Bitmap)); break; } else if (Msg->GadgetID == _R(IDC_BMPGAL_PREVIEW)) { // Generate a list of the selected bitmaps UINT32 ListSize = 0; KernelBitmap** pList = NULL; if (!GetSelectedBitmaps(&pList, &ListSize)) InformError(); else { if (ListSize != 0) { BmpDlgParam BmpDlgParam; GetBmpInfo(&BmpDlgParam); // Save the Bitmap deatils for use in the bitmap export code.# BmpDlgParam.SetBitmapList(pList); BmpDlgParam.SetListSize(ListSize); BitmapExportParam ExportList(ListSize, pList, &BmpDlgParam); // Invoke the preview operation // Check if there is a Preview Dialog present. PreviewDialog* pPreviewDialog = PreviewDialog::GetPreviewDialog(); if (!pPreviewDialog) { OpDescriptor* OpDesc; //if (KeyPress::IsAdjustPressed()) // OpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_BITMAPPREVIEWDIALOG); //else OpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_PREVIEWDIALOG); if (OpDesc) { PreviewDialog::ToggleViaBitmapGallery (TRUE); OpDesc->Invoke(&ExportList); pPreviewDialog->SetDelay (100); pPreviewDialog = PreviewDialog::GetPreviewDialog(); // pPreviewDialog->ToggleViaBitmapGallery (TRUE); } } else { // If the animation is playing, stop the animation before we pass // it our new list of bitmaps. if(pPreviewDialog->GetPlayAnimation()) pPreviewDialog->SetPlayAnimation(FALSE); PreviewDialog::ToggleViaBitmapGallery (TRUE); pPreviewDialog->SetBitmapList(&ExportList); // pPreviewDialog->ToggleViaBitmapGallery (TRUE); pPreviewDialog->SetDelay (100); // Call the dialog box so that it sets up the necessary states pPreviewDialog->ReInitDialog(); } SetBmpInfo(&BmpDlgParam); ForceRedrawOfList(); } else ERROR3("No bitmaps were selected - how come the option wasn't greyed"); } if (pList != NULL) CCFree(pList); } #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present else if (Msg->GadgetID == _R(IDC_BMPGAL_PLUGINS)) { // Need to say which document and more importantly which bitmap we // want the menu to apply to. SelectedBitmap = GetSelectedBitmap(); // Now find out what the selected group is, which will be the document group SGDisplayNode * FirstSelected = DisplayTree->FindNextSelectedItem(NULL); Document *pDocument = NULL; if (FirstSelected == NULL) pDocument = Document::GetSelected(); else pDocument = ((SGDisplayGroup *) FirstSelected->GetParent())->GetParentDocument(); ERROR3IF(pDocument == NULL, "No parent document?!"); if (SelectedBitmap != NULL && pDocument != NULL) { // replaced menu with direct invocation of Bfx:Special Effects operation since this was // the only option left on menu - all the other plug-in options have been superseded // by the new Live Effects implementation. Fixes #11376. OpDescriptor *pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_BFX_SPECIALEFFECTS); if(pOpDesc) { // Inform the Bfx operation what bitmap and document it will be working on BfxPlugInOp::SetBitmapAndDocument(SelectedBitmap, pDocument); // and invoke it immediately pOpDesc->Invoke(); } else { ERROR2RAW("Unable to find BFX:Special Effects operation"); } } } #endif else if (Msg->GadgetID == _R(IDC_BMPGAL_BACKGROUND)) { // Need to say which document and more importantly which bitmap we // want the menu to apply to. SelectedBitmap = GetSelectedBitmap(); // Now find out what the selected group is, which will be the document group SGDisplayNode * FirstSelected = DisplayTree->FindNextSelectedItem(NULL); Document *pDocument = NULL; if (FirstSelected == NULL) pDocument = Document::GetSelected(); else pDocument = ((SGDisplayGroup *) FirstSelected->GetParent())->GetParentDocument(); ERROR3IF(pDocument == NULL, "No parent document?!"); if (SelectedBitmap != NULL && pDocument != NULL) { // Apply the bitmap as the new background OpBackgroundParam Param; Param.pBitmap = SelectedBitmap; Param.pDoc = pDocument; // Obtain a pointer to the op descriptor for the create operation OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_BACKGROUND); // Invoke the operation, passing in our parameters pOpDesc->Invoke(&Param); } } else if (Msg->GadgetID == _R(IDC_BMPGAL_PROPS)) { // Generate a list of the selected bitmaps UINT32 ListSize = 0; KernelBitmap** pList = NULL; if (!GetSelectedBitmaps(&pList, &ListSize)) InformError(); else { if (ListSize != 0) { // Opens the Bitmap Properties Dialog, from the Bitmap Gallery. BmpDlgParam BmpDlgParam; GetBmpInfo(&BmpDlgParam); BmpDlg::InvokeBmpDlg(&BmpDlgParam); SetBmpInfo(&BmpDlgParam); ForceRedrawOfList(); } else ERROR3("No bitmaps were selected - how come the option wasn't greyed"); } if (pList != NULL) CCFree(pList); } break; default: break; } return(SuperGallery::Message(Message)); } // 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 || !IsVisible()) return(SuperGallery::Message(Message)); if (IsVisible() && MESSAGE_IS_A(Message, DocChangingMsg)) { DocChangingMsg *TheMsg = (DocChangingMsg *) Message; switch ( TheMsg->State ) { case DocChangingMsg::BORN: // New document - add to display tree { INT32 Extent = GetDisplayExtent(); // Remember previous list extent CreateNewSubtree(TheMsg->pChangingDoc); // Add a subtree for this doc ShadeGallery(FALSE); // Unshade the gallery InvalidateCachedFormat(); // And redraw what is necessary RedrawEverythingBelow(-Extent); } break; // Pass this message on to the base class as well default: break; } } if (MESSAGE_IS_A(Message, BitmapListChangedMsg) && !IgnoreBmpListChange) { BitmapListChangedMsg *TheMsg = (BitmapListChangedMsg *) Message; // First, try to find the document which owns the changed list Document *ScopeDoc = (Document *)TheMsg->pChangedBmpList->GetParentDocument(); // Just check that the bi-directional link is sane! ERROR3IF(ScopeDoc == NULL, "A Document bitmap list is invalid"); // If we found it, recreate the display subtree for it if (ScopeDoc != NULL) { SGDisplayNode *Ptr = DisplayTree->FindSubtree(this, ScopeDoc, NULL); if (Ptr != NULL) { CreateNewSubtree(ScopeDoc, (SGDisplayGroup *) Ptr); // And force a redraw of the entire list ForceRedrawOfList(); // The above will loose the selection, so we can listen out for the special // form of the message which says which bitmap to reselect. if ((TheMsg->State == BitmapListChangedMsg::SELECTNEWBITMAP) && (TheMsg->pNewBitmap != NULL)) { // We have been sent a message that a new bitmap has been added and // this is the one we should go and select. SelectItems(FALSE); // Clear the current selection SGDisplayGroup *DocGroup = DisplayTree->FindSubtree(this, ScopeDoc, NULL); SGDisplayKernelBitmap* pCurrentItem = NULL; if (DocGroup != NULL) pCurrentItem = (SGDisplayKernelBitmap *) DocGroup->GetChild(); //Selected = (SGDisplayKernelBitmap *) DocGroup->FindNextSelectedItem(NULL); // Ensure the tree format information is up to date, ready for when we sample it ReformatNow(TRUE); BOOL HaveSelected = FALSE; DocRect ScrollToRect; while (pCurrentItem != NULL) { KernelBitmap* CurrentBitmap = pCurrentItem->GetDisplayedKernelBitmap(); if (CurrentBitmap == TheMsg->pNewBitmap) { pCurrentItem->SetSelected(TRUE); HaveSelected = TRUE; pCurrentItem->GetFormatRect(&ScrollToRect); break; } // Get the next one in the list pCurrentItem = (SGDisplayKernelBitmap *) pCurrentItem->GetNext(); } // Try and scroll to the selected item, if we have one if (HaveSelected) { BOOL ScrollToBottom = TRUE; ScrollToShow(&ScrollToRect, ScrollToBottom); } } // Was not present before 20/12/96, safest to have it present as this action // will lose the selection. SelectionHasChanged(); } } } if (MESSAGE_IS_A(Message, CommonAttrsChangedMsg)) { if (!AmShaded) // If we're open & active, set listbox selection SetSelectionFromDocument(); } return(SuperGallery::Message(Message)); } /******************************************************************************************** > virtual void BitmapSGallery::HandleDragStart(DragMessage *DragMsg) Author: Will_Cowling (Xara Group Ltd) Created: 25/3/95 Inputs: DragMsg - The DRAGSTARTED message that we've just recieved, indicating the type of drag being started Purpose: Checks a DragMessage to see if it is a bitmap drag. If it is, then it creates a drag target for this gallerys listbox. Notes: Overrides the default base-class action. Calls down to the base class if it is not a colour drag, so that dragging of gallery groups is allowed ********************************************************************************************/ void BitmapSGallery::HandleDragStart(DragMessage *DragMsg) { // If it's a bitmap drag, add a target for our window. If not, let the base class // have a look at it (to see if it is a gallery item being dragged) if (DragMsg->pInfo->IsKindOf(CC_RUNTIME_CLASS(GalleryBitmapDragInfo))) /* SGBitmapDragTarget *NewTarget =*/ new SGBitmapDragTarget(this, GetListGadgetID()); else SuperGallery::HandleDragStart(DragMsg); } /******************************************************************************************** > BOOL BitmapSGallery::FindCentreInsertionPosition(Spread** Spread, DocCoord* Position) Author: Simon_Maneggio (Xara Group Ltd) Created: 28/7/94 Inputs: - Outputs: Spread: The spread to place the clipboard objects on Position:The centre of the view (Spread coords) Returns: - Purpose: Finds the centre insertion position for clipboard objects Errors: - Scope: private SeeAlso: - ********************************************************************************************/ BOOL BitmapSGallery::FindCentreInsertionPosition(Spread** Spread, DocCoord* Position) { // --------------------------------------------------------------------------------- // Find out which spread is in the centre of the view // this is the spread that the pasted objects will be placed on // Obtain the current DocView DocView* CurDocView = DocView::GetCurrent(); ENSURE(CurDocView != NULL, "The current DocView is NULL"); if (CurDocView == NULL) { return FALSE; // No DocView } // Get the view rect WorkRect WrkViewRect = CurDocView->GetViewRect(); if (WrkViewRect.IsEmpty() || (!WrkViewRect.IsValid()) ) { return FALSE; // Defensive } // Determine the centre of the view WorkCoord WrkCentreOfView; WrkCentreOfView.x = WrkViewRect.lo.x + (WrkViewRect.Width()/2); WrkCentreOfView.y = WrkViewRect.lo.y + (WrkViewRect.Height()/2); // FindEnclosing spread requires an OilCoord OilCoord OilCentreOfView = WrkCentreOfView.ToOil(CurDocView->GetScrollOffsets()); // Find out which spread to insert the pasteboard objects onto (*Spread) = CurDocView->FindEnclosingSpread(OilCentreOfView); if ((*Spread) == NULL) { // There is no spread return FALSE; } // Phew // --------------------------------------------------------------------------------- // Now lets find the spread coordinate of the centre of the view DocRect DocViewRect = CurDocView->GetDocViewRect(*Spread); if ( DocViewRect.IsEmpty() || (!DocViewRect.IsValid()) ) { return FALSE; // Defensive } ENSURE( ( (!DocViewRect.IsEmpty()) && DocViewRect.IsValid()), "DocViewRect is invalid" ); // Find the centre of the DocViewRect DocCoord DocCentreOfView; DocCentreOfView.x = DocViewRect.lo.x + (DocViewRect.Width()/2); DocCentreOfView.y = DocViewRect.lo.y + (DocViewRect.Height()/2); // Now convert from DocCoords to spread coords (*Spread)->DocCoordToSpreadCoord(&DocCentreOfView); // Finally, fill in the return value *Position = DocCentreOfView; return TRUE; } /******************************************************************************************** > virtual RenderRegion *BitmapSGallery::CreateRenderRegion(DocRect *VirtualSize, ReDrawInfoType *DlgRedrawInfo) Author: Jason_Williams (Xara Group Ltd) Created: 29/3/95 Purpose: An overridable veneer to the DialogOp CreateOSRenderRegion method. This can be overriden to use a different type of renderregion for all of your rendering. If you override this, you MUST also override DestroyRenderRegion! SeeAlso: SuperGallery::DestroyRenderRegion ********************************************************************************************/ RenderRegion *BitmapSGallery::CreateRenderRegion(DocRect *VirtualSize, ReDrawInfoType *DlgRedrawInfo) { return(CreateOSRenderRegion(VirtualSize, DlgRedrawInfo)); } /******************************************************************************************** > virtual void BitmapSGallery::DestroyRenderRegion(RenderRegion *pRender) Author: Jason_Williams (Xara Group Ltd) Created: 29/3/95 Purpose: An overridable veneer to the DialogOp DestroyOSRenderRegion method. This can be overriden to use a different type of renderregion for all of your rendering. If you override this, you MUST also override CreateRenderRegion! SeeAlso: SuperGallery::CreateRenderRegion ********************************************************************************************/ void BitmapSGallery::DestroyRenderRegion(RenderRegion *pRender) { DestroyOSRenderRegion(pRender); } /******************************************************************************************** > virtual BOOL BitmapSGallery::PreContextMenu(void) Author: Neville_Humphrys (Xara Group Ltd) Created: 28/10/97 Returns: TRUE for success Purpose: Give the gallery a chance to do something before popping up the context menu. Called before the context menu is popped up on a right click. At present, used by the bitmap gallery to ensure that the plug-ins have all been parsed. ********************************************************************************************/ BOOL BitmapSGallery::PreContextMenu(void) { #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present // As we are just about to invoke UI, check that the plug-in manager has its list // of available plug-ins otherwise, go and get it now as we are just about to need it. // Must do it now before even the hint of a context menu is started as the context // menus stack the automatic menu id and then restore it after they are destroyed. // This is bad if our main menu ids are in this range! PlugInManager* pManager = GetApplication()->GetPlugInManager(); if (pManager) pManager->CheckHaveDetailsOnPlugIns(); #endif // PHOTOSHOPPLUGINS return(TRUE); } /******************************************************************************************** > virtual BOOL BitmapSGallery::InitMenuCommands(void) Author: Jason_Williams (Xara Group Ltd) Created: 18/9/95 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 without doing anything. ********************************************************************************************/ BOOL BitmapSGallery::InitMenuCommands(void) { static BOOL MenusInitialised = FALSE; BOOL ok = TRUE; if (!MenusInitialised) { // Initialise menu command Ops // "Standard" entries for options menu ok = ok && InitMenuCommand((StringBase *) &SGCmd_Find, _R(IDS_SGMENU_FIND)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Sort, _R(IDS_SGMENU_SORT)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Properties, _R(IDS_SGMENU_PROPERTIES)); // "Special" entries for over-list menu ok = ok && InitMenuCommand((StringBase *) &SGCmd_Insert, _R(IDS_SGMENU_INSERT)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Fill, _R(IDS_SGMENU_FILL)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Transp, _R(IDS_SGMENU_TRANSP)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_XPE_Edit, _R(IDS_SGMENU_XPE_EDIT)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Delete, _R(IDS_SGMENU_DELETE)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Save, _R(IDS_SGMENU_SAVE)); //#if _DEBUG ok = ok && InitMenuCommand((StringBase *) &SGCmd_Preview, _R(IDS_SGMENU_PREVIEW)); //#endif // WEBSTER-ranbirr-22/11/96 #ifndef WEBSTER ok = ok && InitMenuCommand((StringBase *) &SGCmd_Trace, _R(IDS_SGMENU_TRACE)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_Effects, _R(IDS_SGMENU_EFFECTS)); #endif //webster #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present ok = ok && InitMenuCommand((StringBase *) &SGCmd_PlugIns, _R(IDS_SGMENU_PLUGINS)); #endif ok = ok && InitMenuCommand((StringBase *) &SGCmd_SetBackground, _R(IDS_SGMENU_SETBACKGROUND)); // WEBSTER-ranbirr-22/11/96 ok = ok && InitMenuCommand((StringBase *) &SGCmd_Props, _R(IDS_SGMENU_PROPS)); // "Standard" commands for over-list menu ok = ok && InitMenuCommand((StringBase *) &SGCmd_FoldGroup, _R(IDS_SGMENU_FOLD)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_UnfoldGroup, _R(IDS_SGMENU_UNFOLD)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_NextGroup, _R(IDS_SGMENU_NEXTGROUP)); ok = ok && InitMenuCommand((StringBase *) &SGCmd_PrevGroup, _R(IDS_SGMENU_PREVGROUP)); MenusInitialised = TRUE; } return(ok); } /******************************************************************************************** > virtual BOOL BitmapSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID) Author: Jason_Williams (Xara Group Ltd) Created: 15/9/95 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: Override this method to stop the default menus being built ********************************************************************************************/ BOOL BitmapSGallery::BuildCommandMenu(GalleryContextMenu *TheMenu, SGMenuID MenuID) { BOOL ok = TRUE; if (MenuID == SGMENU_OPTIONS) { // Options menu ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Find); // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Sort); // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Properties); } else { // Over-list menu ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Insert); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Fill); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Transp,TRUE); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Delete); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Save); //#if _DEBUG ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Preview); //#endif // WEBSTER-ranbirr-22/11/96 #ifndef WEBSTER ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_XPE_Edit); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Trace); // ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Effects); #endif //webster #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present // Need to say which document and more importantly which bitmap we // want the menu to apply to. KernelBitmap * pSelectedBitmap = GetSelectedBitmap(); // Now find out what the selected group is, which will be the document group SGDisplayNode * FirstSelected = DisplayTree->FindNextSelectedItem(NULL); Document *pDocument = NULL; if (FirstSelected == NULL) pDocument = Document::GetSelected(); else pDocument = ((SGDisplayGroup *) FirstSelected->GetParent())->GetParentDocument(); ERROR3IF(pDocument == NULL, "No parent document?!"); // Add plug-in ("Special Effects" is the only one still used since Live Effects) to the // main menu, not a submenu. Fixes #11376 // Well, in fact we will ask the PlugInsContextMenu to do it for us! ok = ok && PlugInsContextMenu::BuildMenu(pSelectedBitmap, pDocument, TheMenu, NULL, TRUE); #endif // WEBSTER-ranbirr-22/11/96 ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_Props,TRUE); // This is the set background menu option ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_SetBackground, TRUE); // With separator // Add the fold and unfold group items SGDisplayGroup *TheGroup = FindCommandGroup(); // Fold or unfold as appropriate if (TheGroup == NULL || !TheGroup->Flags.Folded) ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_FoldGroup); else ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_UnfoldGroup); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_PrevGroup); ok = ok && AddCommand(TheMenu, (StringBase *) &SGCmd_NextGroup); } return(ok); } /******************************************************************************************** > virtual OpState BitmapSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason) Author: Jason_Williams (Xara Group Ltd) Created: 15/9/95 Inputs: CommandID - TheString ID of the command Outputs: ShadeReason - If you return (OpState.Greyed == TRUE) then this should be filled in 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 BitmapSGallery::GetCommandState(StringBase *CommandID, String_256 *ShadeReason) { OpState State; if (*CommandID == SGCmd_Properties || *CommandID == SGCmd_Sort) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOTSUPPORTED)); } else if (*CommandID == SGCmd_Delete) { INT32 Count = GetSelectedItemCount(); if (Count == 0) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL)); } else if (Count == 1 && GetSelectedBitmap()->ActualBitmap == OILBitmap::Default) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_NODELBITMAP)); } } else if (*CommandID == SGCmd_Insert || *CommandID == SGCmd_Fill // WEBSTER-ranbirr-22/11/96 #ifndef WEBSTER || *CommandID == SGCmd_Transp || *CommandID == SGCmd_Trace || *CommandID == SGCmd_XPE_Edit || *CommandID == SGCmd_Effects || *CommandID == SGCmd_SetBackground #endif //Webster #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present || *CommandID == SGCmd_PlugIns #endif ) { if (GetSelectedItemCount() != 1) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_SINGLE)); } } else if (*CommandID == SGCmd_Save) { if (GetSelectedItemCount() == 0) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL)); } } else if (*CommandID == SGCmd_Preview) { if (GetSelectedItemCount() == 0) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL)); } } else if (*CommandID == SGCmd_Props) { if (GetSelectedItemCount() == 0) { State.Greyed = TRUE; ShadeReason->MakeMsg(_R(IDS_SGSHADE_NOSEL)); } } else return(SuperGallery::GetCommandState(CommandID, ShadeReason)); // Unknown command- pass to baseclass return(State); } /******************************************************************************************** > virtual void BitmapSGallery::DoCommand(StringBase *CommandID) Author: Jason_Williams (Xara Group Ltd) Created: 15/9/95 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 BitmapSGallery::DoCommand(StringBase *CommandID) { if (*CommandID == SGCmd_Insert) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_CREATE)); Message(&Bob); } else if (*CommandID == SGCmd_Fill) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_FILL)); Message(&Bob); } // WEBSTER-ranbirr-22/11/96 #ifndef WEBSTER else if (*CommandID == SGCmd_Transp) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_TEXTURE)); Message(&Bob); } #endif //webster else if (*CommandID == SGCmd_Save) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_SAVE)); Message(&Bob); } else if (*CommandID == SGCmd_Preview) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_PREVIEW)); Message(&Bob); } else if (*CommandID == SGCmd_XPE_Edit) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_XPE_EDIT)); Message(&Bob); } // WEBSTER-ranbirr-22/11/96 #ifndef WEBSTER else if (*CommandID == SGCmd_Trace) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_TRACE)); Message(&Bob); } /* else if (*CommandID == SGCmd_Effects) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_EFFECTS)); Message(&Bob); } */ #endif //webster #ifdef PHOTOSHOPPLUGINS // Only add in if required - general plug-in removal at present else if (*CommandID == SGCmd_PlugIns) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_PLUGINS)); Message(&Bob); } #endif else if (*CommandID == SGCmd_SetBackground) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_BACKGROUND)); Message(&Bob); } // WEBSTER-ranbirr-22/11/96 else if (*CommandID == SGCmd_Props) { // Fake a button click message to ourself DialogMsg Bob(WindowID, DIM_LFT_BN_CLICKED, _R(IDC_BMPGAL_PROPS)); Message(&Bob); } else SuperGallery::DoCommand(CommandID); // Unknown command- pass to the base class } //----------------------------------------------------------------------------------------------- // OpDisplayBitmapGallery - the operation that is used to display the bitmap gallery /******************************************************************************************** > BOOL OpDisplayBitmapGallery::Init() Author: Will_Cowling (Xara Group Ltd) Created: 31/1/95 Inputs: - Outputs: - Returns: TRUE if the operation could be successfully initialised FALSE if no more memory could be allocated Purpose: OpDisplayBitmapGallery initialiser method Errors: ERROR will be called if there was insufficient memory to allocate the operation. SeeAlso: - ********************************************************************************************/ BOOL OpDisplayBitmapGallery::Init() { return ( RegisterOpDescriptor( 0, _R(IDS_DISPLAY_BITMAP_GALLERY), CC_RUNTIME_CLASS(OpDisplayBitmapGallery), OPTOKEN_DISPLAYBITMAPGALLERY, OpDisplayBitmapGallery::GetState, 0, /* help ID */ _R(IDBBL_DISPLAY_BITMAP_GALLERY), _R(IDC_BTN_SGBITMAP), // UINT32 resourceID = 0, // resource ID _R(IDC_BTN_SGBITMAP), // UINT32 controlID = 0, // control ID SYSTEMBAR_ILLEGAL, // SystemBarType GroupBarID = SYSTEMBAR_ILLEGAL, // group bar ID TRUE, // BOOL ReceiveMessages = TRUE, // BODGE FALSE, // BOOL Smart = FALSE, TRUE, // BOOL Clean = TRUE, NULL, // OpDescriptor *pVertOpDesc = NULL, 0, // UINT32 OneOpenInstID = 0, 0, // UINT32 AutoStateFlags = 0, TRUE // BOOL fCheckable = FALSE ) PORTNOTE("other", "Removed BitmapExportPreviewDialog") #ifndef EXCLUDE_FROM_XARALX //#if _DEBUG && BitmapExportPreviewDialog::Init() //#endif #endif && PreviewDialog::Init() ); } /******************************************************************************************** > OpState OpDisplayBitmapGallery::GetState(String_256*, OpDescriptor*) Author: Will_Cowling (Xara Group Ltd) Created: 31/1/95 Inputs: - Outputs: - Returns: The state of the OpDisplayBitmapGallery operation Purpose: For finding the OpDisplayBitmapGallery's state. Errors: - SeeAlso: - ********************************************************************************************/ OpState OpDisplayBitmapGallery::GetState(String_256* UIDescription, OpDescriptor*) { OpState OpSt; // If the gallery is currenty open, then the menu item should be ticked SuperGallery* pSuperGallery = SuperGallery::FindSuperGallery(_R(IDD_BITMAPSGALLERY)); if (pSuperGallery != NULL) { if (pSuperGallery->GetRuntimeClass() == CC_RUNTIME_CLASS(BitmapSGallery)) OpSt.Ticked = pSuperGallery->IsVisible(); } // If there are no open documents, you can't toggle the gallery OpSt.Greyed = (Document::GetSelected() == NULL); return(OpSt); } /******************************************************************************************** > void OpDisplayBitmapGallery::Do(OpDescriptor*) Author: Will_Cowling (Xara Group Ltd) Created: 31/1/95 Inputs: - Outputs: - Returns: - Purpose: Displays the bitmap gallery Errors: - SeeAlso: - ********************************************************************************************/ void OpDisplayBitmapGallery::Do(OpDescriptor*) { SuperGallery* pSuperGallery = SuperGallery::FindSuperGallery(_R(IDD_BITMAPSGALLERY)); if (!pSuperGallery) pSuperGallery = new BitmapSGallery(); if (pSuperGallery != NULL) { if (pSuperGallery->GetRuntimeClass() == CC_RUNTIME_CLASS(BitmapSGallery)) { // Toggle the visibility of the gallery window pSuperGallery->SetVisibility( !pSuperGallery->IsVisible() ); // And update the gallery button state SGInit::UpdateGalleryButton(_R(OPTOKEN_DISPLAYBITMAPGALLERY), pSuperGallery->IsVisible()); } #if _DEBUG else ERROR3("The Bitmap Gallery isn't a BitmapSGallery! Woss goin' on?"); #endif } ERROR3IF(pSuperGallery == NULL,"Couldn't find the bitmap gallery bar"); End(); } /******************************************************************************************** > BOOL BitmapSGallery::GetSelectedBitmaps(KernelBitmap** pOutputArray, UINT32* pOutputCount) Author: Peter_Arnold (Xara Group Ltd) Created: 11/6/96 Inputs: see Outputs Outputs: pOutputArray - list of selected KernelBitmaps pOutputCount - the length of the list Returns: TRUE/FALSE for success/error Purpose: Generates a list of all the selected bitmaps in the gallery. Note that the generated array becomes the callers responsibility if TRUE is returned; the caller must CCFree it. SeeAlso: BitmapSGallery::GetSelectedBitmap ********************************************************************************************/ BOOL BitmapSGallery::GetSelectedBitmaps(KernelBitmap*** pOutputArray, UINT32* pOutputCount) { // Init vars ERROR2IF(pOutputArray==NULL || pOutputCount==NULL, FALSE, "NULL output param"); KernelBitmap** pBuildingArray = NULL; // UINT32 BuildingCount = 0; // Lets see if any of our items are selected Document* ParentDoc = (Document*) GetApplication()->Documents.GetHead(); BOOL ok = TRUE; while (ParentDoc!=NULL && ok) { SGDisplayGroup *DocGroup = DisplayTree->FindSubtree(this, ParentDoc, NULL); if (DocGroup != NULL) { // Note the selected items in this group SGDisplayKernelBitmap* pCurrent = (SGDisplayKernelBitmap*)DocGroup->FindNextSelectedItem(NULL); while (pCurrent!=NULL && ok) { if (pBuildingArray==NULL) { // Claim selected space pBuildingArray = (KernelBitmap**) CCMalloc(sizeof(KernelBitmap*)); if (pBuildingArray == NULL) ok = FALSE; else pBuildingArray[0] = pCurrent->GetDisplayedKernelBitmap(); *pOutputCount = 1; } else { // Add to end of selection KernelBitmap** pTemp = (KernelBitmap**) CCRealloc(pBuildingArray, ((*pOutputCount)+1)*sizeof(KernelBitmap*)); if (pTemp == NULL) ok = FALSE; else { pBuildingArray = pTemp; pBuildingArray[*pOutputCount] = pCurrent->GetDisplayedKernelBitmap(); } (*pOutputCount)++; } pCurrent = (SGDisplayKernelBitmap*)DocGroup->FindNextSelectedItem(pCurrent); } } ParentDoc = (Document *) GetApplication()->Documents.GetNext(ParentDoc); } if (!ok) { CCFree(pBuildingArray); *pOutputArray = NULL; *pOutputCount = 0; } else *pOutputArray = pBuildingArray; return ok; } /******************************************************************************************** BOOL BitmapSGallery::GetBmpInfo(BmpDlgPara Param) Author: Ranbir_Rana (Xara Group Ltd) Created: 05/01/96 Inputs: Param - Allows the transfer of data to and from the bitmap poperties dialog. Outputs: - Returns: TRUE if Successful, else FALSE. Purpose: Retrieves inforamtion from Bitmaps selected in the Bitmaps Gallery. SeeAlso: - ********************************************************************************************/ BOOL BitmapSGallery::GetBmpInfo(BmpDlgParam* Param) { ERROR2IF(Param == NULL,FALSE,"Param is NULL"); UINT32 ListSize = 0; KernelBitmap** pList = NULL; // BOOL Done = FALSE; if (!GetSelectedBitmaps(&pList, &ListSize)) return FALSE; //Pass these values to our Param class, for use in the dialog code Param->SetBitmapList(pList); Param->SetListSize(ListSize); if (ListSize>1) { Param->SetMany(TRUE); } String_256* BitmapCols = new String_256[ListSize]; String_256* Width = new String_256[ListSize]; String_256* Height = new String_256[ListSize]; String_256* BitmapFormat = new String_256[ListSize]; UINT32* Delay = new UINT32[ListSize]; BOOL* Interpolation = new BOOL[ListSize]; GIFDisposalMethod* DisposalMethod = new GIFDisposalMethod[ListSize]; UINT32* TranspType = new UINT32[ListSize]; if ( !BitmapCols || !Width || !Height || !BitmapFormat || !Delay || !DisposalMethod || !TranspType ) return FALSE; UINT32 i=0; // Loop index UINT32 TempListSize=ListSize; // Keep a record of our list size. INT32 Bytes =0; // Holds the bitmap Memory info. while (ListSize>0) { ListSize--; KernelBitmap* pKernelBitmap = pList[ListSize]; if (pKernelBitmap == NULL) return FALSE; OILBitmap* pOILBitmap = pKernelBitmap->GetActualBitmap(); if (pOILBitmap == NULL) return FALSE; PORTNOTE("other", "Removed XPE hooks") #ifndef EXCLUDE_FROM_XARALX IXMLDOMDocumentPtr pEditsList = NULL; KernelBitmap* pMaster = NULL; pKernelBitmap->GetXPEInfo(pMaster, pEditsList); BOOL bIsXPE = (pMaster!=NULL && pEditsList!=NULL); #else BOOL bIsXPE = FALSE; #endif // Get the bitmap name details. Param->SetBitmapName(pOILBitmap->GetName()); // Is this bitmap a compressed JPEG? IsJPEG(pList,ListSize,Param,&Bytes); // Set the format field - JPEG\Bitmap. if(Param->GetIsJPEG()) { Param->SetBitmapFormat(_R(IDS_FORMAT_JPEG)); } else if (bIsXPE) { Param->SetBitmapFormat(_R(IDS_FORMAT_XPE)); } else { Param->SetBitmapFormat(_R(IDS_FORMAT_BITMAP)); } // Get the Delay for the selected bitmap. Param->SetAnimDelay(pKernelBitmap->GetDelay()); // Get the 'smooth when scaled up?' setting Param->SetInterpolation(pKernelBitmap->GetInterpolation()); // Now find how many colours it has? INT32 bpp = pKernelBitmap->GetBPP(); Param->SetBitmapTranspType(_R(IDS_BITMAPTRANSPTYPE_NONE)); UINT32 ttype = TT_NoTranspType; if (bpp <= 8) { // Check to see if this is a masked bitmap. INT32 Index=0; if(pKernelBitmap->GetTransparencyIndex(&Index)) { Param->SetBitmapTranspType(_R(IDS_BITMAPTRANSPTYPE_MASKED)); ttype = TT_Mix; } } else if (bpp<32) { Param->SetBitmapTranspType(_R(IDS_BITMAPTRANSPTYPE_NONE)); } else { Param->SetBitmapTranspType(_R(IDS_BITMAPTRANSPTYPE_ALPHA)); ttype = TT_StainGlass; } switch (bpp) { case 1: Param->SetBitmapCols(_R(IDS_SGBITMAP_MONOCHROME)); // "Monochrome"; break; case 2: Param->SetBitmapCols(_R(IDS_SGBITMAP_4COLOURS)); // "4 colours"; break; case 4: Param->SetBitmapCols(_R(IDS_SGBITMAP_16COLOURS)); // "16 colours"; break; case 8: Param->SetBitmapCols(_R(IDS_SGBITMAP_256COLOURS)); // "256 colours"; break; case 16: Param->SetBitmapCols(_R(IDS_SGBITMAP_65COLOURS)); // "65K colours"; break; case 24: Param->SetBitmapCols(_R(IDS_SGBITMAP_MILLIONS_COLOURS)); // "Millions of colours"; break; case 32: Param->SetBitmapCols(_R(IDS_SGBITMAP_32_BIT)); // "Millions of colours"; break; default: Param->SetBitmapCols (""); break; } // Get the bitmap Dimensions. BitmapInfo Info; if(pOILBitmap->GetInfo(&Info)) { // Get its pixel Width and Height. Convert::LongToString(Info.PixelWidth, &Param->GetBitmapWidth()); Convert::LongToString(Info.PixelHeight, &Param->GetBitmapHeight()); // If this bitmap is not have a compressed JPEG, then calculate the memeory used by the bitmap. if(!Param->GetIsJPEG() && !bIsXPE) { // Work out how much memory it is using. Bytes += (Info.PixelWidth * Info.PixelHeight * bpp)/8; } } // Get the bitmap Animation Restore details. Param->SetRestoreType(pOILBitmap->GetAnimationRestoreType()); // Keep a record of the details. BitmapCols[i] = Param->GetBitmapCols(); Width[i] = Param->GetBitmapWidth(); Height[i] = Param->GetBitmapHeight(); BitmapFormat[i] = Param->GetBitmapFormat(); Delay[i] = Param->GetAnimDelay(); Interpolation[i]= Param->GetInterpolation(); DisposalMethod[i] = Param->GetRestoreType(); TranspType[i] = ttype; i++; } // ok, we have no more bitmaps\JPEGS, so convert the memory (Bytes), into a string. Convert::BytesToString(&Param->GetMemoryUsed(),(INT32)Bytes); // Compare the bitmap colors,Dimensions,Transparency and Format fields and set their flags appropriately. // i.e. If for any one field, all the bitmaps are not the same, then we output "-", instead of the details. // Only do this if more than one bitmap is selected.. if (TempListSize>1) { for(i=0; iSetSameColors(FALSE); if (Width[i] != Width[e]) Param->SetSameDimensions(FALSE); if (Height[i] != Height[e]) Param->SetSameDimensions(FALSE); if (BitmapFormat[i] != BitmapFormat[e]) Param->SetSameFormat(FALSE); if (DisposalMethod[i] != DisposalMethod[e]) Param->SetSameRestoreType(FALSE); if (Delay[i] != Delay[e]) Param->SetAreDelayValuesSame(FALSE); if (Interpolation[i] != Interpolation[e]) Param->SetAreInterpolationValuesSame(FALSE); if (TranspType[i] != TranspType[e]) Param->SetSameTranspType(FALSE); } } } if (pList != NULL) CCFree(pList); delete [] BitmapCols; delete [] Width; delete [] Height; delete [] DisposalMethod; delete [] BitmapFormat; delete [] Delay; delete [] Interpolation; delete [] TranspType; return TRUE; } /************************************************************************************************* > BOOL BitmapSGallery::SetBmpInfo(BmpDlgPara* Param) Author: Ranbir_Rana (Xara Group Ltd) Created: 05/01/96 Inputs: Param - Allows the transfer of data to and from the bitmap poperties dialog. Outputs: - Returns: TRUE if Successful, FALSE otherwise. Purpose: Stores info, retrieved from the Bitmap Properties Dialog, in an OILBitmap. SeeAlso: - **************************************************************************************************/ BOOL BitmapSGallery::SetBmpInfo(BmpDlgParam* Param) { ERROR2IF(Param == NULL,FALSE,"Param is NULL"); // The user has entrered OK, so go through the list of selected bitmaps and set their Delay\Restore fields. UINT32 ListSize = 0; KernelBitmap** pList = NULL; Document* WorkDoc = Document::GetSelected(); if (!GetSelectedBitmaps(&pList, &ListSize)) return FALSE; if(Param->GetAreDelayValuesSame()) { UINT32 ListCounter = ListSize; while (ListCounter>0) { KernelBitmap* pKernelBitmap = pList[--ListCounter]; if (pKernelBitmap != NULL) { pKernelBitmap->SetDelay(Param->GetAnimDelay()); } } } if (Param->GetSameRestoreType()) { UINT32 ListCounter = ListSize; while (ListCounter>0) { KernelBitmap* pKernelBitmap = pList[--ListCounter]; if(pKernelBitmap != NULL) { OILBitmap* pOILBitmap = pKernelBitmap->GetActualBitmap(); if (pOILBitmap != NULL) { pOILBitmap->SetAnimationRestoreType(Param->GetRestoreType()); } } } } // Andy Hills, 09-10-00 // Record changes to the 'smooth when scaled up' tickbox if (Param->GetAreInterpolationValuesSame()) { UINT32 ListCounter = ListSize; while (ListCounter>0) { KernelBitmap* pKernelBitmap = pList[--ListCounter]; if(pKernelBitmap != NULL) { OILBitmap* pOILBitmap = pKernelBitmap->GetActualBitmap(); if (pOILBitmap != NULL) { // change the interpolation setting of each selected bitmap pOILBitmap->SetInterpolation(Param->GetInterpolation()); // invalidate all uses of this bitmap, so that the screen is updated correctly if (WorkDoc != NULL) { pOILBitmap->InvalidateAllReferences(WorkDoc); } } } } } if (pList != NULL) CCFree(pList); return TRUE; } /************************************************************************************************************ > BOOL BitmapSGallery::IsJPEG() Author: Ranbir_Rana (Xara Group Ltd) Created: 05/01/96 Inputs: pList - A ptr to a Kernel bitmap. ListSize - The number of bitmaps selected in the bitmap gallery. Param - Allows data to be passed to and from the bitmap properties dialog. pBytes - If it is a JPEG, the memory (bytes), is returned to the caller. Outputs: - Returns: True if the selected bitmap is a compressed JPEG, false otherwise Purpose: To determine whether an imported bitmap is a compressed JPEG. SeeAlso: - ***************************************************************************************************************/ BOOL BitmapSGallery::IsJPEG(KernelBitmap** pList,UINT32 ListSize, BmpDlgParam* Param, INT32* pBytes) { ERROR2IF(pList == NULL || Param == NULL || pBytes == NULL, FALSE, "NULL Parameters Passed"); BitmapSource* pSource = NULL; BaseBitmapFilter* pDummyFilter; KernelBitmap* pKernelBitmap = pList[ListSize]; if (pKernelBitmap == NULL) return FALSE; BOOL OriginalSourcePresent = pKernelBitmap->GetOriginalSource(&pSource, &pDummyFilter); if(OriginalSourcePresent) { if (pSource != NULL) { if (pSource->IsJPEG()) { Param->SetIsJPEG(TRUE); *pBytes += pSource->GetSize(); } } } else { Param->SetIsJPEG(FALSE); } return Param->GetIsJPEG(); } /****************************************************************************************** BOOL BitmapSGallery::AreDelayValuesSame () Author: Ranbir_Rana (Xara Group Ltd) Created: 05/01/96 Inputs: - Outputs: - Returns: TRUE if values are the same , FALSE otherwise. Purpose: To find if the Animation delay values of selected Bitmaps are the same. SeeAlso: - ********************************************************************************************/ /* BOOL BitmapSGallery::AreDelayValuesSame() { UINT32 ListSize = 0; KernelBitmap** pList = NULL; BOOL DelayValuesDiffer = FALSE; UINT32 i =0; UINT32 e=0; UINT32 Value =0; if (!GetSelectedBitmaps(&pList, &ListSize)) return FALSE; UINT32 TempListSize = ListSize; UINT32* Delay = new UINT32[ListSize]; if (!Delay) return FALSE; // Get each bitmaps delay value while (ListSize>0) { ListSize--; Value = pList[ListSize]->GetDelay(); Delay[i] = Value; i++; } // Compare the values. for(i=0; i UINT32 BitmapSGallery::GetBitmapAnimDelay() Author: Ranbir_Rana (Xara Group Ltd) Created: 05/01/96 Inputs: Outputs: - Returns: The Delay value stored in a Bitmap. Purpose: SeeAlso: - ********************************************************************************************/ /* UINT32 BitmapSGallery::GetBitmapDelay() { UINT32 ListSize = 0; KernelBitmap** pList = NULL; UINT32 i =0; if (!GetSelectedBitmaps(&pList, &ListSize)) InformError(); return pList[i]->GetActualBitmap()->GetBitmapAnimDelay(); } */