prevwdlg.cpp

Go to the documentation of this file.
00001 // $Id: prevwdlg.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 // A simple Dialog That does some Gavin Rendering into itself
00099 
00100 /*
00101 */
00102 
00103 #include "camtypes.h"
00104 #include "prevwdlg.h"
00105 
00106 #include "ccdc.h"       // specific #includes needed for kernel-rendered dialogues
00107 #include "dlgcol.h"     // DialogColourInfo
00108 //#include "fillval.h"
00109 #include "grnddib.h"
00110 
00111 //#include "prevwres.h"
00112 #include "impexpop.h"   // BitmapExportParam
00113 #include "nodebmp.h"    // NodeBitmap
00114 //#include "gifutil.h"  // GDM_BACKTOBACK
00115 #include "dlgview.h"    // DialogView
00116 
00117 //#include "rikdlg.h"       // _R(IDB_SLIDERBASE), _R(IDB_SLIDERSLIDER)
00118 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00119 #include "ctrlhelp.h"
00120 //#include "docvmsg.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00121 
00122 //#include "spread.h"       // GetFirstFrameLayer() - in camtypes.h [AUTOMATICALLY REMOVED]
00123 
00124 //#include "xshelpid.h" //For the help ID
00125 
00126 // This is not compulsory, but you may as well put it in so that the correct version
00127 // of your file can be registered in the .exe
00128 DECLARE_SOURCE("$Revision: 1282 $");
00129 
00130 // An implement to match the Declare in the .h file.
00131 // If you have many classes, it is recommended to place them all together, here at the start of the file
00132 CC_IMPLEMENT_DYNCREATE(AnimatedBitmapItem, ListItem)
00133 CC_IMPLEMENT_DYNCREATE(PreviewDialog, DialogOp)
00134 
00135 // This will get Camelot to display the filename and linenumber of any memory allocations
00136 // that are not released at program exit
00137 #define new CAM_DEBUG_NEW
00138 
00139 
00140 // Set the static vars of the render dialog
00141 const CDlgMode  PreviewDialog::Mode = MODELESS; 
00142 const UINT32        PreviewDialog::IDD = _R(IDD_PREVIEWDIALOG);
00143       BOOL      PreviewDialog::m_AnimationPropertiesChanged = FALSE;
00144               
00145 typedef struct
00146 {
00147     CGadgetID   Gadget;         // Gadget ID
00148     UINT32      BubbleID;       //Bubble help ID for this gadget
00149 } GadgetBubbleHelp;
00150 
00151 
00152 // If extra controls are added to the Preview dialog and
00153 // they require Bubble help, add them to this table.
00154 static GadgetBubbleHelp BubbleHelp[] = 
00155 {
00156 
00157     {   _R(IDC_PREVIEW_PLAY),        _R(IDS_PREVIEWBH_PLAY)      },
00158     {   _R(IDC_PREVIEW_STOP),        _R(IDS_PREVIEWBH_STOP)      },
00159     {   _R(IDC_PREVIEW_NEXTFRAME),   _R(IDS_PREVIEWBH_NEXTFRAME) },
00160     {   _R(IDC_PREVIEW_PREVFRAME),   _R(IDS_PREVIEWBH_PREVFRAME) }, 
00161     {   _R(IDC_PREVIEW_SLIDER),      _R(IDS_PREVIEWBH_SLIDER)    },
00162     {   0, 0                                         }  
00163 
00164 };
00165 
00166 BOOL PreviewDialog::viaBitmapGallery = FALSE;
00167 
00168 
00169 
00170 
00171 /********************************************************************************************
00172 
00173 >   AnimatedBitmapItem::AnimatedBitmapItem(KernelBitmap *pEntry, Layer * pLayer = NULL)
00174 
00175     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00176     Created:    11/4/97
00177     Inputs:     pEntry  - The bitmap to add to the list of frames
00178                 pLayer  - The layer that the bitmap is associated with (defaults to NULL)
00179     Purpose:    To add a bitmap to the list of frames in the animation sequence. If it has
00180                 an associated layer then add this at the same time.
00181 
00182 ********************************************************************************************/
00183 
00184 AnimatedBitmapItem::AnimatedBitmapItem(KernelBitmap * pEntry, Layer * pLayer)
00185 {
00186     m_pBitmap = pEntry;
00187     m_pLayer = pLayer;
00188 }
00189 
00190 /********************************************************************************************
00191 
00192 >   AnimatedBitmapItem::AnimatedBitmapItem()
00193 
00194     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00195     Created:    11/4/97
00196     Purpose:    Default contructor.
00197 
00198 ********************************************************************************************/
00199 
00200 AnimatedBitmapItem::AnimatedBitmapItem()
00201 {
00202     ERROR3("AnimatedBitmapItem::AnimatedBitmapItem - call the other constructor");
00203     m_pBitmap = NULL;
00204     m_pLayer = NULL;
00205 }
00206 
00207 /********************************************************************************************
00208 
00209 >   AnimatedBitmapItem::~AnimatedBitmapItem()
00210 
00211     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00212     Created:    11/4/97
00213     Purpose:    Default destructor
00214 
00215 ********************************************************************************************/
00216 
00217 AnimatedBitmapItem::~AnimatedBitmapItem()
00218 {
00219     // Do not attempt to delete the pointers that we have as these are references
00220     // rather than anything that we have allocated
00221 }
00222 
00223 
00224 
00225 /*******************************************************************************************
00226 ********************************************************************************************/
00227 // Initialise our statics
00228 
00229 PreviewDialog * PreviewDialog::m_pPreviewDialog = NULL;
00230 UINT32          PreviewDialog::m_Delay = 0; 
00231 
00232 
00233 /*******************************************************************************************
00234 
00235 >   PreviewDialog::PreviewDialog() : DialogOp(RenderDlg::IDD, RenderDlg::Mode) 
00236 
00237     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00238     Created:    11/4/97
00239     Purpose:    Constructs a Preview Dialog
00240 
00241 *******************************************************************************************/
00242 
00243 PreviewDialog::PreviewDialog() : DialogOp(PreviewDialog::IDD, PreviewDialog::Mode), m_Timer(this)
00244 {
00245     m_BitmapListSize            = 0;
00246     m_CurrentItem               = 0;
00247     m_pPreviewDialog            = this;
00248     m_pRender                   = NULL;
00249     m_PlayAnimation             = TRUE;
00250     m_DisplayNextFrame          = FALSE;
00251     m_DisplayPreviousFrame      = FALSE;
00252     m_SliderPosition            = m_BitmapListSize;
00253     m_DocumentAboutToDie        = FALSE;
00254     m_SetPreviewDlgToIdleState  = FALSE;
00255     m_GeneratedFrameLayers      = FALSE;
00256     m_DisposalMethod            = GDM_BACKTOBACK;
00257     m_CurrentDisposalMethod     = GDM_BACKTOBACK;
00258 
00259     m_AnimationRect.MakeEmpty();
00260 
00261     // Reset the loop counts
00262     m_CurrentLoopCount          = 0;    // The loop that we are currently on (default to start)
00263     m_RequiredLoopCount         = 0;    // The loop count that we must reach (default for ever)
00264     
00265     //viaBitmapGallery          = FALSE;        // THIS MUST ALREADY HAVE BEEN SET TO THE CORRECT
00266                                                 // VALUE !!!!!
00267     
00268     // Get the input focus for bubble help.
00269     GetApplication()->RegisterIdleProcessor(IDLEPRIORITY_HIGH, this);
00270 }       
00271 
00272 /*******************************************************************************************
00273 
00274 >   PreviewDialog::~PreviewDialog()
00275 
00276     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00277     Created:    11/4/97
00278     Purpose:    Destructor
00279 
00280 *******************************************************************************************/
00281 
00282 PreviewDialog::~PreviewDialog()
00283 {
00284     // clean out the render region, if allocated
00285     if (m_pRender)
00286     {
00287         // Delete the render region and its (dialog) view
00288         // Do it by hand as StopRender should have been called already
00289         delete m_pRender->GetRenderView();
00290         delete m_pRender;
00291 //      DestroyGRenderRegion(m_pRender);
00292         m_pRender = NULL;
00293     }
00294     
00295     // Clean out the list of bitmaps that we were animating
00296     m_BitmapList.DeleteAll();
00297 
00298     // kill the static link to this dialog box
00299     m_pPreviewDialog = NULL;
00300 
00301     // The dialog has been destroyed, remove the input focus.
00302     GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
00303 } 
00304 
00305 
00306 
00307 /*******************************************************************************************
00308 
00309 >   MsgResult PreviewDialog::Message(Msg* Message)
00310 
00311     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00312     Created:    11/4/97
00313     Purpose:    Handles all the Preview dialog's messages 
00314 
00315 *******************************************************************************************/
00316 
00317 MsgResult PreviewDialog::Message(Msg* Message)
00318 {
00319     MsgResult Result;
00320 
00321     BOOL EndDialog = FALSE;     // TRUE if we should quit the dialog
00322 
00323     // See if it is for us
00324     if (IS_OUR_DIALOG_MSG(Message))
00325     {
00326         // it is
00327         DialogMsg* Msg = (DialogMsg*)Message;
00328 
00329         // decide what to do
00330         switch (Msg->DlgMsg)
00331         {
00332             // Create message
00333             case DIM_CREATE :
00334                 // As it is a modal dialog box we are sent a message to say the dialog box
00335                 // is being created, so we have a chance to set the initial control values.
00336             //  if (Mode == MODAL)
00337             {
00338                     InitDialog();
00339                     SetUpCallBack();
00340                     
00341                     INT32 i = 0;
00342                     while (BubbleHelp[i].Gadget)                        
00343                     {
00344                         SetGadgetHelp(BubbleHelp[i].Gadget, BubbleHelp[i].BubbleID, BubbleHelp[i].BubbleID);
00345                         i++;
00346                     }
00347                 break;
00348             }
00349             //  break;
00350 
00351             // Close and destroy the dialog 
00352             case DIM_COMMIT :
00353             case DIM_CANCEL :
00354             {
00355                 EndDialog = TRUE;                       // Flag to close and end
00356                 break;
00357             }
00358             //case DIM_SLIDER_POS_SET:
00359             case DIM_SLIDER_POS_CHANGING:
00360             {
00361                 // Messages to all the controls, handled individually
00362                 if (Msg->GadgetID == _R(IDC_PREVIEW_SLIDER))
00363                 {
00364                     // While the animation is playing, if this button is selected,
00365                     // the play button is clicked out, the stop button is clicked in,
00366                     // and the next/previous frame in the animation is displayed. 
00367                     PreviewDlgStop();
00368                     // Kill any bubble help just in case the user has bubble help up
00369                     // over the slider
00370 PORTNOTE("other", "Remove Bubble help reference");
00371 #ifndef EXCLUDE_FROM_XARALX
00372                     ControlHelper::BubbleHelpDisable();
00373 #endif
00374                     SetSliderPosition();                                                
00375                                                 
00376                     // Force the gadget to be repainted, 
00377                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00378                     InvalidateGadget(_R(IDC_REDRAW_ME));
00379                 }
00380                 break;  //DIM_SLIDER_POS_CHANGING:
00381             }
00382 
00383             case DIM_LFT_BN_CLICKED :
00384             {
00385                 // See which button was pressed
00386                 if (FALSE) {}
00387                 else if (Msg->GadgetID == _R(IDC_PREVIEW_PLAY))
00388                 {
00389                     // Play the animation.
00390                     PreviewDlgPlay();
00391                     
00392                     // Force the gadget to be repainted, 
00393                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00394                     InvalidateGadget(_R(IDC_REDRAW_ME));
00395                 }
00396                 else if (Msg->GadgetID == _R(IDC_PREVIEW_STOP))
00397                 {
00398                     // Stop the animation.
00399                     PreviewDlgStop();
00400 
00401                     // Force the gadget to be repainted, 
00402                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00403                     InvalidateGadget(_R(IDC_REDRAW_ME));
00404                 }
00405                 else if (Msg->GadgetID == _R(IDC_PREVIEW_NEXTFRAME))
00406                 {
00407                     //  While the animation is playing, if this button is selected,
00408                     //  the play button is clicked out, the stop button is clicked in,
00409                     //  and the next frame in the animation is displayed. 
00410                     PreviewNextFrame();
00411                                             
00412                     // Force the gadget to be repainted, 
00413                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00414                     InvalidateGadget(_R(IDC_REDRAW_ME));
00415 
00416                     // Only show one frame at a time, therefore set this flag back to false. 
00417                     m_DisplayNextFrame = FALSE;
00418                 }
00419                 else if (Msg->GadgetID == _R(IDC_PREVIEW_PREVFRAME))
00420                 {
00421                     // While the animation is playing, if this button is selected,
00422                     // the play button is clicked out, the stop button is clicked in,
00423                     // and the previous frame in the animation is displayed. 
00424                     PreviewPreviousFrame();
00425                     
00426                     // Force the gadget to be repainted, 
00427                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00428                     InvalidateGadget(_R(IDC_REDRAW_ME));
00429 
00430                     // Only show one frame at a time, therefore, set this flag to false. 
00431                     m_DisplayPreviousFrame = FALSE;
00432                 }
00433                 else if (Msg->GadgetID == _R(IDC_PREVIEW_REFRESH))
00434                 {
00435                     // Has the refresh button been clicked, while the dlg is in an idle state.
00436                     if (m_SetPreviewDlgToIdleState)
00437                         SetDlgStateAfterDocChange();
00438                     else
00439                         SetDlgStateAfterRefresh();                              
00440                 }
00441                 /*
00442                 else if (Msg->GadgetID == _R(IDC_PREVIEW_STARTFRAME))
00443                 {
00444                     m_DisplayListOfBitmaps = TRUE;
00445 
00446                     // Find the first frame in our list.
00447                     m_pPreviewDialog->SelectFirstBitmap();
00448 
00449                     // Force the gadget to be repainted, 
00450                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00451                     m_pPreviewDialog->InvalidateGadget(_R(IDC_REDRAW_ME));
00452                     m_DisplayListOfBitmaps = FALSE;
00453 
00454                     break;
00455                 }*/
00456 
00457                 /*
00458                 else if (Msg->GadgetID == _R(IDC_PREVIEW_ENDFRAME))
00459                 {
00460                     m_DisplayListOfBitmaps = TRUE;
00461                     // Find the first frame in our list.
00462                     SelectLastBitmap();
00463 
00464                     // Force the gadget to be repainted, 
00465                     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00466                     m_pPreviewDialog->InvalidateGadget(_R(IDC_REDRAW_ME));
00467                     m_DisplayListOfBitmaps = FALSE;
00468                 }
00469                 {
00470                     BOOL Valid = FALSE;
00471                     BOOL State = GetLongGadgetValue(Msg->GadgetID, 0, 1, NULL, &Valid);
00472                     //if (State)
00473                     //  SetLongGadgetValue(Msg->GadgetID, !State);
00474                     break;
00475                 } */
00476             }
00477 
00478             case DIM_REDRAW :
00479             {
00480                 // This is where all the redrawing is done
00481                 // Which control in the window is sending the redraw message (if there are many
00482                 // grdraw controls you can tell which is which from the Gadget ID
00483                 if (Msg->GadgetID == _R(IDC_REDRAW_ME))
00484                 {
00485                     if(m_SetPreviewDlgToIdleState)
00486                         // Set the Preview dialog to an idle state.
00487                         SetPreviewDialogToIdleState((ReDrawInfoType*) Msg->DlgMsgParam);
00488                     else
00489                         // Render this control.
00490                         RenderControl((ReDrawInfoType*) Msg->DlgMsgParam);                                              
00491                 }
00492                 else
00493                 {
00494                     // give out an error in debug builds, ignore in retail builds
00495                     ERROR3("Got a redraw message for a control I don't know about");
00496                 }
00497                 break;
00498             }   
00499             default:
00500                 break;
00501         }
00502     }
00503     else if (MESSAGE_IS_A(Message, DocChangingMsg))
00504     {
00505         DocChangingMsg *Msg = (DocChangingMsg *) Message;
00506         switch (Msg->State)
00507         {
00508             case DocChangingMsg::ABOUTTODIE:
00509             /*{
00510                 if (Msg->pOldDoc == NULL)
00511                 {
00512                     //Stop playing the animation.
00513                     m_DocumentAboutToDie = TRUE;
00514 
00515                     // Since the document is about to die, no frame layers will exist.
00516                     m_GeneratedFrameLayers = FALSE;
00517 
00518                     // Reset the disposal method
00519                     m_DisposalMethod = GDM_BACKTOBACK;
00520                     m_CurrentDisposalMethod = GDM_BACKTOBACK;
00521                 
00522                     // End the dialog
00523                     // EndDialog = TRUE;                        // Flag to close and end
00524                 }
00525                 break;
00526             }*/
00527             case DocChangingMsg::SELCHANGED:
00528             case DocChangingMsg::BORN:
00529             /*{
00530                 // called when new is used,thereafter called when no docs. are around.
00531                 if (Msg->pNewDoc == NULL)
00532                 {
00533                     SetDialogToIdleState();
00534 
00535                     // End the dialog
00536                     //EndDialog = TRUE;                     // Flag to close and end
00537                 }
00538                 // There is an active doucment around.
00539                 else
00540                 {
00541                     SetDialogToIdleState();
00542                 }
00543                 break;
00544             }*/
00545                 EndDialog = TRUE;
00546             break;
00547 
00548             default:
00549                 break;
00550         }
00551     }
00552 
00553     // End dialog here
00554     if (EndDialog) 
00555     {
00556         Close();                // Hide the dialog box
00557         End();                  // Finish the operation
00558         return OK;
00559     }
00560 
00561     // Allow the base class access to the message, it will do the
00562     // DLG_EAT_IF_HUNGRY(Msg) for us
00563     // Must do this before the Close and End
00564     Result = DialogOp::Message(Message);
00565 
00566 
00567     // The message was for our dialog box so return that we have handled it, if necessary
00568     //return (DLG_EAT_IF_HUNGRY(Msg)); 
00569     return Result;
00570 }  
00571 
00572 /******************************************************************************************
00573 
00574 >   BOOL PreviewDialog::SetDialogToIdleState()
00575 
00576     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00577     Created:    22/7/97
00578     Returns:    TRUE if successful, else FALSE
00579     Purpose:    Ensures that the the dialog is set into an idle state showing a cross in
00580                 the preview section.
00581 
00582 ******************************************************************************************/
00583 
00584 BOOL PreviewDialog::SetDialogToIdleState()
00585 {
00586     // Stop playing the animation.
00587     m_DocumentAboutToDie = TRUE;
00588     m_PlayAnimation = FALSE;
00589     
00590     // Set the Preview dialog to an idle state.
00591     m_SetPreviewDlgToIdleState = TRUE;
00592 
00593     // Since the document has changed no frame layers will exist.
00594     // They will require generating.
00595     m_GeneratedFrameLayers = FALSE;
00596 
00597     // Reset the disposal methods
00598     m_DisposalMethod = GDM_BACKTOBACK;
00599     m_CurrentDisposalMethod = GDM_BACKTOBACK;
00600 
00601     // SetDlgState(TRUE);
00602 
00603     // Clean the list of bitmaps that we were animating.
00604     m_BitmapList.DeleteAll();
00605     m_BitmapListSize            = 0;
00606     m_CurrentItem               = 0;
00607     m_SliderPosition            = m_BitmapListSize;
00608     m_AnimationRect.MakeEmpty();
00609 
00610     // Reset the loop counts
00611     m_CurrentLoopCount          = 0;    // The loop that we are currently on (default to start)
00612     m_RequiredLoopCount         = 0;    // The loop count that we must reach (default for ever)
00613 
00614     // Force the gadget to be repainted, 
00615     InvalidateGadget(_R(IDC_REDRAW_ME));
00616 
00617     return TRUE;
00618 }
00619 
00620 /******************************************************************************************
00621 
00622 >   BOOL PreviewDialog::InitDialog()
00623 
00624     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00625     Created:    11/4/97
00626     Returns:    TRUE if successful, else FALSE
00627     Purpose:    Sets initial dialog values 
00628 
00629 ******************************************************************************************/
00630 
00631 BOOL PreviewDialog::InitDialog()
00632 {
00633     SetGadgetBitmaps(_R(IDC_PREVIEW_SLIDER), _R(IDB_SLIDERBASE), _R(IDB_SLIDERSLIDER));
00634     INT32 StepValue = 100;
00635     if (m_BitmapListSize > 0)
00636         StepValue = 100/m_BitmapListSize;
00637 
00638     // Set the range of the slider control plus the step value.  
00639     SetGadgetRange(_R(IDC_PREVIEW_SLIDER), 1, m_BitmapListSize, StepValue); 
00640     SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), m_BitmapListSize - m_CurrentItem);
00641 
00642     // Find the correct bitmap to display.                      
00643     UINT32 BitmapNum = (m_BitmapListSize - 1);
00644     SelectCurrentBitmap(BitmapNum);
00645     
00646     // Set up the bitmaps for the play controls
00647     // Uses the title defined in the rc file so do not specify any bitmaps
00648     SetGadgetBitmaps(_R(IDC_PREVIEW_PLAY), 0, 0);
00649     SetGadgetBitmaps(_R(IDC_PREVIEW_STOP), 0, 0);
00650     SetGadgetBitmaps(_R(IDC_PREVIEW_NEXTFRAME), 0, 0);
00651     SetGadgetBitmaps(_R(IDC_PREVIEW_PREVFRAME), 0, 0);
00652     SetGadgetBitmaps(_R(IDC_PREVIEW_STARTFRAME), 0, 0);
00653     SetGadgetBitmaps(_R(IDC_PREVIEW_ENDFRAME), 0, 0);
00654 
00655     // Reset the loop count that we are currently on
00656     m_CurrentLoopCount = 0;
00657 
00658     // Are we in single bitmap mode?
00659     if (m_BitmapListSize == 1)
00660     {
00661         // Single bitmap mode
00662 
00663         // Enable the play button = grab all frames and play
00664         if (viaBitmapGallery)
00665         {
00666             EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);//TRUE);
00667 
00668             // Set the title of the dialog to "Preview single bitmap"
00669             String_256 title(_R(IDS_PREVIEWTITLE_SINGLEBITMAP));
00670             SetTitlebarName(&title); 
00671 
00672             // change the name field from saying "Frame:" to "Image:"
00673             String_32 Name(_R(IDS_PREVIEW_FRAMENAMETYPESTR));
00674             SetStringGadgetValue(_R(IDC_PREVIEW_FRAMENAMETYPE), Name);
00675         }
00676         else
00677         {
00678             EnableGadget(_R(IDC_PREVIEW_PLAY), TRUE);
00679 
00680             // Set the title of the dialog to "Preview single frame"
00681             String_256 title(_R(IDS_PREVIEWTITLE_SINGLE));
00682             SetTitlebarName(&title); 
00683         }
00684 
00685         // disable all the other controls
00686         EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
00687         EnableGadget(_R(IDC_PREVIEW_NEXTFRAME), FALSE);
00688         EnableGadget(_R(IDC_PREVIEW_PREVFRAME), FALSE);
00689 
00690         // Disable the slider
00691         EnableGadget(_R(IDC_PREVIEW_SLIDER), FALSE);
00692 
00693         // Disable the refresh button
00694         EnableGadget (_R(IDC_PREVIEW_REFRESH), FALSE);
00695 
00696         m_PlayAnimation = FALSE;
00697     }
00698     else
00699     {
00700         // No, in multiple bitmap mode
00701 
00702         if (viaBitmapGallery)
00703         {
00704             // Set the title of the dialog to "Preview multiple images"
00705             String_256 title(_R(IDS_PREVIEWTITLE_MULTIPLEBITMAP));
00706             SetTitlebarName(&title);
00707 
00708             // change the name field from saying "Frame:" to "Image:"
00709             String_32 Name(_R(IDS_PREVIEW_FRAMENAMETYPESTR));
00710             SetStringGadgetValue(_R(IDC_PREVIEW_FRAMENAMETYPE), Name);
00711         }
00712         else
00713         {
00714             // Set the title of the dialog to "Preview all frames"
00715             String_256 title(_R(IDS_PREVIEWTITLE_MULTIPLE));
00716             SetTitlebarName(&title); 
00717         }
00718 
00719         // Disable the Play buttton. Enable the Stop buttton.
00720         EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);
00721         EnableGadget(_R(IDC_PREVIEW_STOP), TRUE);
00722 
00723         // Enable the slider
00724         EnableGadget(_R(IDC_PREVIEW_SLIDER), TRUE);
00725 
00726         // although I would like to do this here, viaBitmapGallery has not been set yet
00727         // so instead we do this within ToggleViaBitmapGallery ()
00728         
00729         if (viaBitmapGallery)
00730         {
00731             EnableGadget (_R(IDC_PREVIEW_REFRESH), FALSE);
00732             SetPlayAnimation (TRUE);
00733         }
00734     }
00735 
00736 /*  SetGadgetBitmaps(_R(IDC_PREVIEW_PLAY), _R(IDB_PREVIEW_PLAY), _R(IDB_PREVIEW_PLAY));
00737     SetGadgetBitmaps(_R(IDC_PREVIEW_STOP), _R(IDB_PREVIEW_STOP), _R(IDB_PREVIEW_STOP));
00738     SetGadgetBitmaps(_R(IDC_PREVIEW_NEXTFRAME), _R(IDB_PREVIEW_NEXT), _R(IDB_PREVIEW_NEXT));
00739     SetGadgetBitmaps(_R(IDC_PREVIEW_PREVFRAME), _R(IDB_PREVIEW_PREVIOUS), _R(IDB_PREVIEW_PREVIOUS));
00740     SetGadgetBitmaps(_R(IDC_PREVIEW_STARTFRAME), _R(IDB_PREVIEW_START), _R(IDB_PREVIEW_START));
00741     SetGadgetBitmaps(_R(IDC_PREVIEW_ENDFRAME), _R(IDB_PREVIEW_END), _R(IDB_PREVIEW_END)); */
00742 
00743     // Set up the frame/layer name control
00744     String_32 BlankName(TEXT(""));
00745     SetStringGadgetValue(_R(IDC_PREVIEW_FRAMENAME), BlankName);
00746 
00747     return TRUE;
00748 }
00749 
00750 void PreviewDialog::ToggleViaBitmapGallery (BOOL val)
00751 {
00752     viaBitmapGallery = val;//TRUE;
00753 
00754 /*  if (viaBitmapGallery)
00755     {
00756 //      EnableGadget (_R(IDC_PREVIEW_REFRESH), FALSE);
00757 //      m_Delay = 100;                              // lets make the frames tick slower ....
00758     }
00759     else
00760     {
00761         EnableGadget (_R(IDC_PREVIEW_REFRESH), TRUE);
00762     }*/
00763 }
00764 
00765 
00766 /******************************************************************************************
00767 
00768 >   BOOL PreviewDialog::ReInitDialog()
00769 
00770     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Ranbir code which was in OpGrabFrame::SetFullBitmapList
00771     Created:    17/6/97
00772     Returns:    TRUE if successful, else FALSE
00773     Purpose:    Will reset the initial dialog values. Should be used on an already open
00774                 dialog box.
00775 
00776 ******************************************************************************************/
00777 
00778 BOOL PreviewDialog::ReInitDialog()
00779 {
00780     if (GetDlgState())
00781     {
00782         SetDocumentAboutToDie(FALSE);
00783         SetDlgState(FALSE);
00784         // Set the correct state of the controls.
00785     }
00786 
00787     // Reset the disposal method
00788     m_DisposalMethod = GDM_BACKTOBACK;
00789     m_CurrentDisposalMethod = GDM_BACKTOBACK;
00790 
00791     // Reset the loop count that we are currently on
00792     m_CurrentLoopCount = 0;
00793 
00794     // Is there more than one bitmap in the animation?
00795     INT32   BitmapListSize = GetBitmapListSize();
00796     if (BitmapListSize == 1)
00797     {
00798         // Set the title of the dialog to "Preview single frame"
00799         String_256 title(_R(IDS_PREVIEWTITLE_SINGLE));
00800         SetTitlebarName(&title); 
00801 
00802         // Enable the play button = grab all frames and play
00803         EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);//TRUE);
00804 
00805         // Disable all the other controls
00806         EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
00807         EnableGadget(_R(IDC_PREVIEW_NEXTFRAME), FALSE);
00808         EnableGadget(_R(IDC_PREVIEW_PREVFRAME), FALSE);
00809 
00810         // Disable the slider
00811         EnableGadget(_R(IDC_PREVIEW_SLIDER), FALSE);
00812 
00813         // Disable the refresh button
00814         EnableGadget (_R(IDC_PREVIEW_REFRESH), FALSE);
00815 
00816         // A single frame layer has been generated.
00817         SetGeneratedFrameLayers(FALSE);
00818     }
00819     else
00820     {
00821         // Set the title of the dialog to "Preview all frames"
00822         String_256 title(_R(IDS_PREVIEWTITLE_MULTIPLE));
00823         SetTitlebarName(&title); 
00824 
00825         // Enable the slider
00826         EnableGadget(_R(IDC_PREVIEW_SLIDER), TRUE);
00827 
00828         if (viaBitmapGallery)
00829         {
00830             EnableGadget (_R(IDC_PREVIEW_REFRESH), FALSE);
00831             SetPlayAnimation (TRUE);
00832         }
00833 
00834         // Is the animation playing.
00835         if (GetPlayAnimation())
00836         {
00837             // Set the correct state of the controls.
00838             EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);
00839             EnableGadget(_R(IDC_PREVIEW_STOP), TRUE);
00840             EnableGadget(_R(IDC_PREVIEW_NEXTFRAME), TRUE);
00841             EnableGadget(_R(IDC_PREVIEW_PREVFRAME), TRUE);
00842 
00843             // A document change will stop the timer, therefore re-start it.
00844             RestartTimer();                 
00845         }
00846         else
00847         {
00848             // Set the correct state of the controls.
00849             EnableGadget(_R(IDC_PREVIEW_PLAY), TRUE);
00850             EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
00851             EnableGadget(_R(IDC_PREVIEW_NEXTFRAME), TRUE);
00852             EnableGadget(_R(IDC_PREVIEW_PREVFRAME), TRUE);
00853         }
00854 
00855         // Set the correct state of the dlg.
00856         // Ensure that the timer does not get stopped after we restarted it as it thinks
00857         // that either the animation properties have changed or the document is about to die
00858         SetDlgState(FALSE);
00859         SetDocumentAboutToDie(FALSE);
00860         SetGeneratedFrameLayers(TRUE);
00861         SetAnimationPropertiesChanged(FALSE);
00862     }
00863 
00864     // If there is only a single layer, set the slider to the end.
00865     m_SliderPosition = m_BitmapListSize;
00866     SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), m_BitmapListSize);
00867     
00868     // Since the dialog is modeless, the user can add extra layers,
00869     // therefore reset the step value of the slider.
00870     INT32 Step = 100/ m_BitmapListSize;
00871     SetGadgetRange(_R(IDC_PREVIEW_SLIDER), 1, m_BitmapListSize, Step);
00872     SetGadgetBitmaps(_R(IDC_PREVIEW_SLIDER), _R(IDB_SLIDERBASE), _R(IDB_SLIDERSLIDER));
00873 
00874     // Find the correct bitmap to display.                      
00875     //if (m_SliderPosition >= m_BitmapListSize)
00876     //  m_SliderPosition = 0;
00877     UINT32 BitmapNum = m_BitmapListSize - m_SliderPosition;
00878     SelectCurrentBitmap(BitmapNum);
00879 
00880     // Force the gadget to be repainted, 
00881     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00882     InvalidateGadget(_R(IDC_REDRAW_ME));
00883 
00884     // Set up the frame/layer name control
00885     String_32 BlankName(TEXT(""));
00886     SetStringGadgetValue(_R(IDC_PREVIEW_FRAMENAME), BlankName);
00887 
00888     return TRUE;
00889 }
00890 
00891 /********************************************************************************************
00892 
00893 >   BOOL PreviewDialog::SelectCurrentFrame(const UINT32 Position)
00894 
00895     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00896     Created:    28/7/97
00897     Inputs:     The frame to be selected (0 .. max frames - 1)
00898     Returns:    True if worked ok, False otherwise
00899     Purpose:    Tries to set the current frame to be displayed and ensure that associated
00900                 items are set e.g. the slider.
00901 
00902 ********************************************************************************************/
00903 
00904 BOOL PreviewDialog::SelectCurrentFrame(const UINT32 Position)
00905 {
00906     INT32 NewPosition = (INT32)Position;
00907     // check if the requested position is beyond the end of the list
00908     if (NewPosition >= m_BitmapListSize)
00909         NewPosition = 0;
00910     
00911     // Set the current selection to be correct
00912     SelectCurrentBitmap(NewPosition);
00913 
00914     // Set the slider position REM slider works backwards.
00915     m_SliderPosition = m_BitmapListSize - NewPosition;
00916     SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), m_SliderPosition);
00917 
00918     // Force the main display gadget to be repainted, 
00919     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00920     InvalidateGadget(_R(IDC_REDRAW_ME));
00921 
00922     return TRUE;
00923 }
00924 
00925 /********************************************************************************************
00926 
00927 >   BOOL PreviewDialog::StopPreviewing()
00928 
00929     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00930     Created:    20/6/97
00931     Returns:    True if worked ok, False otherwise
00932     Purpose:    Puts the dialog into a stopped state ready to grab the frames or frame.
00933 
00934 ********************************************************************************************/
00935 
00936 BOOL PreviewDialog::StopPreviewing()
00937 {
00938     // Stop the animation.
00939     PreviewDlgStop();
00940 
00941     // Force the gadget to be repainted, 
00942     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
00943     InvalidateGadget(_R(IDC_REDRAW_ME));
00944 
00945     // Reset the loop count that we are currently on
00946     m_CurrentLoopCount = 0;
00947 
00948     return TRUE;
00949 }
00950 
00951 /********************************************************************************************
00952 
00953 >   void PreviewDialog::RenderControl(ReDrawInfoType* pExtraInfo)
00954 
00955     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00956     Created:    11/4/97
00957     Inputs:     pExtraInfo - The structure that has the extra data we need to start rendering
00958     Purpose:    Renders the current bitmap into the control. This actually consists of:-
00959                     Render slabbed in border
00960                     Render items before present bitmap in list to set up background
00961                     Render current bitmap
00962 
00963 ********************************************************************************************/
00964 
00965 void PreviewDialog::RenderControl(ReDrawInfoType* pExtraInfo)
00966 {
00967     if (pExtraInfo == NULL)
00968         return;
00969     
00970     // Go get a render region
00971     DocRect VirtualSize(0, 0, pExtraInfo->dx, pExtraInfo->dy);
00972     DocRect WholeRedrawSize = VirtualSize;
00973     
00974     // If we haven't already created our render region then go and create it
00975     BOOL StartedOk = TRUE;
00976     if (m_pRender == NULL)
00977     {
00978         // This will call start render for us
00979         m_pRender = CreateGRenderRegion(&VirtualSize, pExtraInfo);
00980     }
00981     else
00982     {
00983         // and delete the render region and its (dialog) view
00984         View * pDialogView = m_pRender->GetRenderView();
00985         
00986         if (pDialogView)
00987         {
00988             // Try and create the bitmap etc
00989             StartedOk = m_pRender->AttachDevice(pDialogView, pExtraInfo->pDC, NULL);
00990 
00991             // Try and start the render region
00992             StartedOk = StartedOk && m_pRender->StartRender();
00993         }
00994         else
00995             StartedOk = FALSE;
00996     }
00997 
00998     // if we have a render region then go and use it
00999     if (m_pRender != NULL && StartedOk)
01000     {
01001         // Code stolen from ColourEditDlg::RenderControl
01002         DialogColourInfo RedrawColours;             // Get a supplier for default dlg colours
01003         INT32 PixelSize = 72000 / pExtraInfo->Dpi;  // Size of output pixel in millipoints
01004 
01005         GridLockRect(&VirtualSize, PixelSize);
01006 
01007         // Render the attributes and then a rectangle
01008         m_pRender->SaveContext();
01009 
01010         // Get the current bitmap and try and display it
01011         KernelBitmap * pBitmapToUse = GetCurrentBitmap();
01012         if (pBitmapToUse)
01013         {
01014             // Using this method we don't get flicker on the backdrop as we draw the background rectangle
01015             // followed by the white new background
01016             // Draw single pixel black line left and top and single pixel background colour 1 pixel in
01017             m_pRender->SetLineWidth(0);
01018             m_pRender->SetFillColour(RedrawColours.DialogBack());
01019             m_pRender->SetLineColour(COLOUR_BLACK); //RedrawColours.ButtonShadow());
01020             m_pRender->DrawLine(DocCoord(VirtualSize.lo.x, VirtualSize.hi.y - PixelSize),
01021                                 DocCoord(VirtualSize.hi.x, VirtualSize.hi.y - PixelSize));
01022             m_pRender->DrawLine(DocCoord(VirtualSize.lo.x, VirtualSize.hi.y),
01023                                 DocCoord(VirtualSize.lo.x, VirtualSize.lo.y));
01024             m_pRender->SetLineColour(RedrawColours.DialogBack());
01025             m_pRender->DrawLine(DocCoord(VirtualSize.lo.x + PixelSize, VirtualSize.hi.y - 2 * PixelSize),
01026                                 DocCoord(VirtualSize.hi.x - PixelSize, VirtualSize.hi.y - 2 * PixelSize));
01027             m_pRender->DrawLine(DocCoord(VirtualSize.lo.x + PixelSize, VirtualSize.lo.y),
01028                                 DocCoord(VirtualSize.lo.x + PixelSize, VirtualSize.hi.y - 2 * PixelSize));
01029 
01030             // Draw single pixel hightligh line right and bottom and single pixel background colour 1 pixel in
01031             m_pRender->SetLineColour(RedrawColours.ButtonHighlight());
01032             m_pRender->DrawLine(DocCoord(VirtualSize.hi.x - PixelSize, VirtualSize.hi.y - PixelSize),
01033                                 DocCoord(VirtualSize.hi.x - PixelSize, VirtualSize.lo.y));
01034             m_pRender->DrawLine(DocCoord(VirtualSize.hi.x - PixelSize, VirtualSize.lo.y),
01035                                 DocCoord(VirtualSize.lo.x + PixelSize, VirtualSize.lo.y));
01036 
01037             m_pRender->SetLineColour(RedrawColours.DialogBack());
01038             m_pRender->DrawLine(DocCoord(VirtualSize.hi.x - 2 * PixelSize, VirtualSize.hi.y - 2 * PixelSize),
01039                                 DocCoord(VirtualSize.hi.x - 2 * PixelSize, VirtualSize.lo.y + 1 * PixelSize));
01040             m_pRender->DrawLine(DocCoord(VirtualSize.hi.x - 2 * PixelSize, VirtualSize.lo.y + 1 * PixelSize),
01041                                 DocCoord(VirtualSize.lo.x + 2 * PixelSize, VirtualSize.lo.y + 1 * PixelSize));
01042 
01043             // And deflate the rect by 2 pixels
01044             VirtualSize.Inflate(-PixelSize * 2);
01045 
01046             // Ensure that we cannot redraw into the border that we have just redrawn
01047 //          m_pRender->SetClipRect(VirtualSize);
01048 
01049             // Code stolen from BfxDlg::RenderBitmap
01050             m_pRender->SetLineColour(COLOUR_TRANS);
01051 
01052             // If we are playing then assume we need the quickest redraw and we will
01053             // be overlaying the correct frames.
01054 /*          if (m_PlayAnimation)
01055             {
01056                 // Check the GIFDisposalMethod for the previous bitmap. If necessary redraw the background.
01057                 if (m_DisposalMethod == GDM_BACKTOBACK)
01058                 {
01059                     // Draw a rectangle to fill in the background - Fill with Dialogue Background colour
01060                     //m_pRender->SetFillColour(RedrawColours.DialogBack()); // COLOUR_WHITE); //
01061                     m_pRender->SetFillColour(COLOUR_WHITE); 
01062                     m_pRender->DrawRect(&VirtualSize);
01063                 }
01064                 // This is REDRAW code and so noting the redraw method is very bad.
01065                 // Should be done in the code which moves between frames.
01067                 //m_DisposalMethod = pBitmapToUse->GetAnimationRestoreType();
01068 
01069                 // redraw the specified bitmap into the render region
01070                 RedrawBitmap(pBitmapToUse, &VirtualSize);
01071             }
01072             else */
01073             {
01074                 // Try just redrawing everything we need to
01075 
01076                 // Not playing so we must redraw everything that is required to make up
01077                 // this frame. If the previous frame is restore background then we just
01078                 // need to redraw this frame. If the previous frame is anything else then
01079                 // we need to move back through the frames until we find the start or a
01080                 // frame with restore background and then draw from this point.
01081                 // If we encounter a bitmap which is restore previous and it is not this
01082                 // one then we need do nothing.
01083 
01084                 // Draw a rectangle to fill in the background
01085                 m_pRender->SetFillColour(COLOUR_WHITE); 
01086                 m_pRender->DrawRect(&VirtualSize);
01087 
01088 //              INT32 ThisIndex = m_CurrentItem;
01089                 INT32 StartIndex = m_CurrentItem;
01090                 BOOL StartFrameFound = FALSE;
01091                 // First, search out the first frame to redraw
01092                 while (!StartFrameFound && StartIndex > 0)
01093                 {
01094                     // Move to the previous item in the list
01095                     StartIndex--;
01096                     KernelBitmap * pBitmap = GetBitmapItem(StartIndex);
01097                     // Check the GIFDisposalMethod for the previous bitmap.
01098                     if (pBitmap == NULL)
01099                     {
01100                         // No previous frame so stop the search now
01101                         StartFrameFound = TRUE;
01102                         StartIndex++;
01103                     }
01104                     else if (pBitmap->GetAnimationRestoreType() == GDM_BACKTOBACK)
01105                     {
01106                         // Its a restore background so we have found our first frame
01107                         // to redraw, its StartIndex + 1
01108                         StartFrameFound = TRUE;
01109                         StartIndex++;
01110                     }
01111                 }
01112 
01113                 // I'm not sure why they were originally doing this, BUT I've taken it out
01114                 // because it was causing problems with my new stuff ....
01115 
01116                 // Now redraw all the bitmaps from the start frame onwards
01117                 // up to the frame before the current one
01118         /*      for (INT32 i = StartIndex; i < ThisIndex; i++)
01119                 {
01120                     KernelBitmap * pBitmap = GetBitmapItem(i);
01121                     if (pBitmap && pBitmap->GetAnimationRestoreType() != GDM_PREVIOUS)
01122                     {
01123                         RedrawBitmap(pBitmap, &VirtualSize);
01124                     }
01125                 }*/
01126 
01127                 // Lastly, redraw the present bitmap into the render region
01128                 RedrawBitmap(pBitmapToUse, &VirtualSize);
01129             }
01130         }
01131         else
01132         {
01133             // draw a cross to show we do not have a bitmap
01134             RedrawCross(&VirtualSize, &RedrawColours, PixelSize);
01135         }
01136 
01137         // Now that we have drawn everything, reset the cliprect back to the whole
01138         // size, otherwise it seems to stop redrawing the border.
01139         m_pRender->SetClipRect(WholeRedrawSize);
01140 
01141         m_pRender->RestoreContext();
01142 
01143         // Get rid of the render region, now done in the destructor
01144         //DestroyGRenderRegion(m_pRender);
01145         
01146         // Blit to the screen
01147         m_pRender->StopRender();
01148     }
01149 }
01150 
01151 /*******************************************************************************************
01152 
01153 >   BOOL PreviewDialog::RedrawBitmap(KernelBitmap * pBitmapToUse, DocRect * pVirtualSize)
01154 
01155     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01156     Created:    17/6/97
01157     Inputs:     pBitmap             the bitmap to redraw
01158                 pVirtualSize        the size of the area to redraw into
01159     Purpose:    Redraws the specified bitmap into the render region.
01160 
01161 *******************************************************************************************/
01162 
01163 BOOL PreviewDialog::RedrawBitmap(KernelBitmap * pBitmapToUse, DocRect * pVirtualSize)
01164 {
01165     // If we haven't got a render region or bitmap then give up now
01166     // No errors as we are in redraw code
01167     if (m_pRender == NULL || pBitmapToUse == NULL || pVirtualSize == NULL)
01168         return FALSE;
01169 
01170     // Ensure that we cannot redraw into the border that we have just redrawn
01171     m_pRender->SetClipRect(*pVirtualSize);
01172 
01173     NodeBitmap NB;
01174     NodeBitmap * pNodeBitmap = &NB;
01175 
01176     if (!((pNodeBitmap == NULL) || (!pNodeBitmap->SetUpPath(12,12))))
01177     {
01178         // Get a new bitmap object for this node.
01179         pNodeBitmap->GetBitmapRef()->SetBitmap(pBitmapToUse);
01180         ENSURE(pNodeBitmap->GetBitmap()->ActualBitmap != NULL, "No bitmap object found!");
01181 
01182         DocRect BitmapSize(*pVirtualSize);
01183 
01184         MILLIPOINT Width = pBitmapToUse->GetRecommendedWidth();
01185         MILLIPOINT Height = pBitmapToUse->GetRecommendedHeight();
01186         if (Width < 1) Width = 1;
01187         if (Height < 1) Height = 1;
01188 
01189         UINT32 LeftOffset = pBitmapToUse->GetLeftOffset();
01190         UINT32 TopOffset = pBitmapToUse->GetTopOffset();
01191         UINT32 HDpi = pBitmapToUse->GetHorizontalDPI();
01192         UINT32 VDpi = pBitmapToUse->GetVerticalDPI();
01193         MILLIPOINT LeftOffsetMP = ((LeftOffset * 72000)/HDpi);
01194         MILLIPOINT TopOffsetMP = ((TopOffset * 72000)/VDpi);
01195 
01196         // Plot bitmap 1:1 with no scaling
01197         // Try to centralise the image inside the available width
01198         // Otherwise
01199         // Plot the bitmap from the top left of the redraw area using
01200         // the offsets stored in the bitmap
01201         MILLIPOINT FullWidth = m_AnimationRect.Width();
01202         if (FullWidth < pVirtualSize->Width())
01203         {
01204             MILLIPOINT diff = pVirtualSize->Width() - FullWidth;
01205             BitmapSize.lo.x = pVirtualSize->lo.x + diff/2 + LeftOffsetMP;
01206             BitmapSize.hi.x = BitmapSize.lo.x + Width;
01207         }
01208         else
01209         {
01210             BitmapSize.lo.x = pVirtualSize->lo.x + LeftOffsetMP;
01211             BitmapSize.hi.x = BitmapSize.lo.x + Width;
01212         }
01213 
01214         // Try to centralise the image inside the available height
01215         MILLIPOINT FullHeight = m_AnimationRect.Height();
01216         if (FullHeight < pVirtualSize->Height())
01217         {
01218             MILLIPOINT diff = pVirtualSize->Height() - FullHeight;
01219             BitmapSize.hi.y = pVirtualSize->hi.y - diff/2 - TopOffsetMP;
01220             BitmapSize.lo.y = BitmapSize.hi.y - Height;
01221         }
01222         else
01223         {
01224             BitmapSize.hi.y = pVirtualSize->hi.y - TopOffsetMP;
01225             BitmapSize.lo.y = BitmapSize.hi.y - Height;
01226         }
01227 
01228         // If the bitmap is bigger than the size we have available then
01229         // the nodebitmap will render into the slabbed in region on the right
01230         // hand side. So set the clipping rectangle to be the size we have
01231         // available to us i.e. the inside of the slabbed in area.
01232         // Remember, NodeBitmaps has the bitmap applied to fill the entire shape
01233         // and so the NodeBitmap must be the size of the bitmap to fill 1:1.
01234         //m_pRender->SetClipRect(*pVirtualSize);
01235         // Done in the caller now
01236 
01237         // And set this in our bitmap node
01238         pNodeBitmap->CreateShape(BitmapSize);
01239             
01240         pNodeBitmap->Render(m_pRender);
01241     }
01242 
01243     return TRUE;
01244 }
01245 
01246 
01247 /*******************************************************************************************
01248 
01249 >   BOOL PreviewDialog::RedrawCross(DocRect * pVirtualSize, DialogColourInfo * pRedrawColours,
01250                                     INT32 PixelSize)
01251 
01252     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01253     Created:    17/6/97
01254     Inputs:     pVirtualSize        the size of the area to redraw into
01255                 pRedrawColours      a default dialog colour supplier object
01256                 PixelSize           the size of a pixel on the redraw area
01257     Purpose:    Redraws the specified bitmap into the render region.
01258 
01259 *******************************************************************************************/
01260 
01261 BOOL PreviewDialog::RedrawCross(DocRect * pVirtualSize, DialogColourInfo * pRedrawColours,
01262                                 INT32 PixelSize)
01263 {
01264     // If we haven't got a render region then give up now
01265     // No errors as we are in redraw code
01266     if (m_pRender == NULL || pVirtualSize == NULL || pRedrawColours == NULL)
01267         return FALSE;
01268 
01269     // Draw a backgound making sure we blat anything previously there with the dialog
01270     // background colour
01271     m_pRender->SetLineWidth(0);
01272     m_pRender->SetFillColour(pRedrawColours->DialogBack());
01273     m_pRender->SetLineColour(COLOUR_BLACK); //RedrawColours.ButtonShadow());
01274     m_pRender->DrawRect(pVirtualSize);
01275     m_pRender->DrawLine(DocCoord(pVirtualSize->lo.x, pVirtualSize->hi.y), pVirtualSize->hi);
01276 
01277     m_pRender->SetLineWidth(0);
01278     m_pRender->SetLineColour(pRedrawColours->ButtonHighlight());
01279     m_pRender->DrawLine(DocCoord(pVirtualSize->hi.x - PixelSize, pVirtualSize->hi.y - PixelSize),
01280                         DocCoord(pVirtualSize->hi.x - PixelSize, pVirtualSize->lo.y));
01281     m_pRender->DrawLine(DocCoord(pVirtualSize->hi.x - PixelSize, pVirtualSize->lo.y + PixelSize),
01282                         DocCoord(pVirtualSize->lo.x + PixelSize, pVirtualSize->lo.y + PixelSize));
01283 
01284     // Draw the no bitmap present cross i.e. vertical
01285     // And Deflate the rect by 1 pixels so we draw to the outer lines
01286     DocRect InnerSize(*pVirtualSize);
01287     InnerSize.Inflate(-PixelSize);
01288     INT32 Width = InnerSize.Width();
01289     INT32 Height = InnerSize.Height();
01290     m_pRender->SetLineWidth(0);
01291     m_pRender->SetLineColour(COLOUR_BLACK); //RedrawColours.ButtonShadow());
01292     m_pRender->DrawLine(DocCoord(InnerSize.lo.x + Width/2, InnerSize.lo.y),
01293                         DocCoord(InnerSize.lo.x + Width/2, InnerSize.hi.y));
01294     m_pRender->DrawLine(DocCoord(InnerSize.lo.x, InnerSize.lo.y + Height/2),
01295                         DocCoord(InnerSize.hi.x, InnerSize.lo.y + Height/2));
01296 
01297     return TRUE;
01298 }
01299 
01300 /********************************************************************************************
01301 
01302 >   inline INT32 PreviewDialog::HalfGridLock(INT32 Position, INT32 GridSize)
01303 
01304     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Jason code in coldlog.cpp
01305     Created:    28/7/97
01306     Inputs:     Position - The X/Y position, in millipoints
01307                 GridSize - the size of the grid to lock to, in millipoints
01308     Returns:    Position, locked (by rounding) to a grid of the given size, and offset by
01309                 half a grid.
01310     Purpose:    Grid-locks a given plotting poisition to lie over a grid (usually the
01311                 output device-pixel grid). The result is shifted by half the grid size to
01312                 grid-lock to the _center_ of a pixel rather than the edges.
01313     Note:       stolen from ColourEditDlg rendering routines
01314 
01315 ********************************************************************************************/
01316 
01317 inline INT32 PreviewDialog::HalfGridLock(INT32 Position, INT32 GridSize)
01318 {
01319     // By truncating down to the nearest grid point, and adding half the grid value,
01320     // we achieve rounding to the nearest offset-grid position. 
01321 
01322     // NOTE:
01323     // The original algorithm incorrectly rounded negative numbers towards
01324     // zero. Negative numbers should be rounded towards negative infinity.
01325     // The algorithm has been corrected by always rounding a positive number
01326     // and restoring the original sign of the number after rounding.
01327 
01328     BOOL bNegative = FALSE;             // Assume the number is positive
01329 
01330     if (Position < 0)                   // If the number if not positive
01331     {                                   // note the fact and make positive
01332         bNegative   = TRUE;
01333         Position    = -Position;
01334     }
01335 
01336     Position -= Position % GridSize;
01337     Position += GridSize / 2;
01338 
01339     if (bNegative)                      // If the number was negative
01340         Position = -Position;           // restore the sign
01341 
01342     return (Position);
01343 }
01344 
01345 
01346 
01347 /********************************************************************************************
01348 
01349 >   void PreviewDialog::GridLockRect(DocRect *TheRect, INT32 GridSize)
01350 
01351     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Jason code in coldlog.cpp
01352     Created:    28/7/97
01353     Inputs:     TheRect - A MILLIPOINT DocRect to be grid-locked
01354                 GridSize - the size of the grid to lock to, in millipoints
01355     Outputs:    TheRect is updated as appropriate
01356     Purpose:    GridLocks all 4 coordinates of the rectangle using HalfGridLock
01357     Note:       stolen from ColourEditDlg rendering routines
01358 
01359 ********************************************************************************************/
01360 
01361 void PreviewDialog::GridLockRect(DocRect *TheRect, INT32 GridSize)
01362 {
01363     TheRect->lo.x = HalfGridLock(TheRect->lo.x, GridSize);
01364     TheRect->lo.y = HalfGridLock(TheRect->lo.y, GridSize);
01365     TheRect->hi.x = HalfGridLock(TheRect->hi.x, GridSize);
01366     TheRect->hi.y = HalfGridLock(TheRect->hi.y, GridSize);
01367 }
01368 
01369 /*******************************************************************************************
01370 
01371 >   Layer * PreviewDialog::GetCurrentLayer()
01372 
01373     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01374     Created:    20/6/97
01375     Purpose:    Returns the current layer
01376 
01377 *******************************************************************************************/
01378 
01379 Layer * PreviewDialog::GetCurrentLayer()
01380 {
01381     // If beyond the end of the list then wrap around to the start
01382     if (m_CurrentItem >= m_BitmapListSize)
01383         m_CurrentItem = 0;
01384 
01385     // get the item associated with this index
01386     return GetLayerItem(m_CurrentItem); 
01387 }
01388 
01389 /*******************************************************************************************
01390 
01391 >   Layer * PreviewDialog::GetLayerItem(INT32 Index)
01392 
01393     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01394     Created:    20/6/97
01395     Inputs:     Index   the index of the layer in the list to get
01396     Purpose:    Returns the specified layer
01397 
01398 *******************************************************************************************/
01399 
01400 Layer * PreviewDialog::GetLayerItem(INT32 Index)
01401 {
01402     // If beyond the end of the list or the start then return nothing found
01403     if (Index >= m_BitmapListSize || Index < 0)
01404         return NULL;
01405 
01406     // Search through the list for the nth item
01407     AnimatedBitmapItem * pCurrentItem = (AnimatedBitmapItem *)m_BitmapList.GetHead();
01408     INT32 Count = 0;
01409     while (pCurrentItem)
01410     {
01411         if (Count == Index)
01412         {
01413             return pCurrentItem->GetLayer();
01414         }
01415 
01416         Count ++;
01417 
01418         // Get the next item in the list
01419         pCurrentItem = (AnimatedBitmapItem *)m_BitmapList.GetNext(pCurrentItem);
01420     }
01421 
01422     // Nothing found
01423     return NULL;
01424 }
01425 
01426 /*******************************************************************************************
01427 
01428 >   KernelBitmap * PreviewDialog::GetBitmap(INT32 Index)
01429 
01430     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01431     Created:    17/6/97
01432     Inputs:     Index   the index of the bitmap in the list to get
01433     Purpose:    Returns the specified bitmap
01434 
01435 *******************************************************************************************/
01436 
01437 KernelBitmap * PreviewDialog::GetBitmapItem(INT32 Index)
01438 {
01439     // If beyond the end of the list or the start then return nothing found
01440     if (Index >= m_BitmapListSize || Index < 0)
01441         return NULL;
01442 
01443     // Search through the list for the nth item
01444     AnimatedBitmapItem * pCurrentItem = (AnimatedBitmapItem *)m_BitmapList.GetHead();
01445     INT32 Count = 0;
01446     while (pCurrentItem)
01447     {
01448         if (Count == Index)
01449         {
01450             return pCurrentItem->GetBitmap();
01451         }
01452 
01453         Count ++;
01454 
01455         // Get the next item in the list
01456         pCurrentItem = (AnimatedBitmapItem *)m_BitmapList.GetNext(pCurrentItem);
01457     }
01458 
01459     // Nothing found
01460     return NULL;
01461 }
01462 
01463 /*******************************************************************************************
01464 
01465 >   KernelBitmap * PreviewDialog::GetCurrentBitmap(BOOL GetDetails = TRUE)
01466 
01467     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01468     Created:    11/4/97
01469     Purpose:    Returns the current bitmap which we should be using
01470 
01471 *******************************************************************************************/
01472 
01473 KernelBitmap * PreviewDialog::GetCurrentBitmap(BOOL GetDetails)
01474 {
01475     KernelBitmap * pBitmapToUse = NULL;
01476 
01477     // If beyond the end of the list then wrap around to the start
01478     if (m_CurrentItem >= m_BitmapListSize)
01479         m_CurrentItem = 0;
01480 
01481     // Search through the list for the nth item
01482     AnimatedBitmapItem * pCurrentItem = (AnimatedBitmapItem *)m_BitmapList.GetHead();
01483     INT32 Count = 0;
01484     while (pCurrentItem)
01485     {
01486         if (Count == m_CurrentItem)
01487         {
01488             pBitmapToUse = pCurrentItem->GetBitmap();
01489             break;
01490         }
01491 
01492         Count ++;
01493 
01494         // Get the next item in the list
01495         pCurrentItem = (AnimatedBitmapItem *)m_BitmapList.GetNext(pCurrentItem);
01496     }
01497 
01498     // Note the disposal method for this bitmap for the next time around
01499     if (pBitmapToUse && GetDetails)
01500     {
01501         m_CurrentDisposalMethod = pBitmapToUse->GetAnimationRestoreType();
01502 
01503         // Set up the frame/layer name control to be the bitmap name
01504         String_256 Name = pBitmapToUse->GetName();
01505         SetStringGadgetValue(_R(IDC_PREVIEW_FRAMENAME), Name);
01506     }
01507 
01508     return pBitmapToUse;
01509 }
01510 
01511 
01512 /*******************************************************************************************
01513 
01514 >   void PreviewDialog::IncrementCurrentBitmap()
01515 
01516     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01517     Created:    11/4/97
01518     Purpose:    Moves the current item to be the next bitmap in the list. 
01519                 If we reach the end of the list, it then becomes the first item in the list.
01520 
01521 *********************************************************************************************/
01522 
01523 void PreviewDialog::IncrementCurrentBitmap()
01524 {
01525     // Local flag to test whether to increment the slider position.
01526 //  BOOL SliderPositionReset = FALSE;
01527 
01528     // Increment the Bitmap if the user has clicked either Play or NextFrame.
01529     if (m_PlayAnimation || m_DisplayNextFrame )
01530     {
01531         m_CurrentItem++;
01532 
01533         // Moving forward so note the current disposal method as the new one
01534         m_DisposalMethod = m_CurrentDisposalMethod;
01535 
01536         // Only activate the slider if we have more than 1 bitmap.
01537         if(m_BitmapListSize > 1)
01538         {
01539             // Decrement the slider.
01540             m_SliderPosition--;
01541 
01542             // If the slider is set to the end, place it back at the start.
01543             if (m_SliderPosition <= 0)
01544                 m_SliderPosition = m_BitmapListSize;    
01545         }   
01546 
01547         // Set the slider to the correct position.
01548         SetSliderPosition(m_SliderPosition);
01549     }
01550 
01551     // If beyond the end of the list then wrap around to the start.
01552     if (m_CurrentItem >= m_BitmapListSize)
01553     {
01554         // We have looped again so update our loop count
01555         // Only do though if we haven't got a loop forever state
01556         if (m_RequiredLoopCount <= 0)
01557             m_CurrentItem = 0;
01558         else
01559         {
01560             m_CurrentLoopCount++;
01561             if (m_CurrentLoopCount >= m_RequiredLoopCount)
01562             {
01563                 // We have looped enough so stop the animation
01564                 // Stops the animation and sets the play/stop buttons to the play state
01565                 PreviewDlgStop();
01566             }
01567             else
01568             {
01569                 // Need to loop again so reset to the start of the loop
01570                 m_CurrentItem = 0;
01571             }
01572         }
01573     }
01574 
01575     TRACEUSER( "JustinF", _T("\t-- current frame is %ld\n"), (INT32) m_CurrentItem);        
01576 }
01577 
01578 /*******************************************************************************************
01579 
01580 >   void PreviewDialog::SelectFirstBitmap()
01581 
01582     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01583     Created:    14/05/97
01584     Purpose:    Selects the first bitmap in our list.
01585 
01586 *******************************************************************************************/
01587 
01588 void PreviewDialog::SelectFirstBitmap()
01589 {
01590     // select the first bitmap from our list.
01591     m_CurrentItem = 0;
01592 }
01593 
01594 /***********************************************************************************************
01595 
01596 >   void PreviewDialog::SelectLastBitmap()
01597 
01598     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01599     Created:    14/05/97
01600     Purpose:    Selects the last bitmap in our list.
01601 
01602 ***********************************************************************************************/
01603 
01604 void PreviewDialog::SelectLastBitmap()
01605 {
01606     // select the last bitmap from our list.
01607     m_CurrentItem = (m_BitmapListSize -1);
01608 }
01609 
01610 /***********************************************************************************************
01611 
01612 >   void PreviewDialog::SelectCurrentBitmap(UINT32 Position)
01613 
01614     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01615     Created:    14/05/97
01616     Inputs:     Position - THe position on the slider.
01617     Outputs:    None
01618     Purpose:    Moves the current item to where the slider has been positioned. 
01619                 
01620 *************************************************************************************************/
01621 void PreviewDialog::SelectCurrentBitmap(UINT32 Position)
01622 {
01623     m_CurrentItem = Position;
01624 }
01625 
01626 /***********************************************************************************************
01627 
01628 >   void PreviewDialog::DecrementCurrentBitmap()
01629 
01630     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01631     Created:    14/05/97
01632     Purpose:    Moves the current item to be the previous bitmap in the list.
01633                 If we reach the start of the list, it then becomes the last item in the list.
01634 
01635 *************************************************************************************************/
01636 
01637 void PreviewDialog::DecrementCurrentBitmap()
01638 {
01639     //  Local flag to test whether to increment the slider position.
01640 //  BOOL SliderPositionReset = FALSE;
01641 
01642     //  Decrement the bitmap if the user has eitther clicked Play or Previous frame.
01643     if(m_PlayAnimation || m_DisplayPreviousFrame)
01644     {
01645         m_CurrentItem--;
01646         
01647         // Moving backwards so do what?????
01648         m_DisposalMethod = GDM_BACKTOBACK;
01649 
01650         // Activate the slider if we have more than 1 bitmap.
01651         if(m_BitmapListSize > 1)
01652         {
01653             // Increment the slider.
01654             m_SliderPosition++;
01655 
01656             //  If the slider is at the start, then set it to the end.  
01657             if(m_SliderPosition >= m_BitmapListSize + 1)
01658                 m_SliderPosition = 1;       
01659         }
01660 
01661         // Set the slider to the correct position.
01662         SetSliderPosition(m_SliderPosition);
01663     }
01664 
01665     // If we reach the start of the list then wrap around to the end.
01666     if (m_CurrentItem < 0)
01667         m_CurrentItem = (m_BitmapListSize-1);
01668 }
01669 
01670 /*******************************************************************************************
01671 
01672 >   void SetSliderPosition(INT32 Position)
01673 
01674     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01675     Created:    14/05/97
01676     Inputs:     The position at which the slider is to be set.
01677     Purpose:    Set the slider to its correct position.
01678 
01679 ******************************************************************************************/
01680 void PreviewDialog::SetSliderPosition(INT32 Position)
01681 {
01682     if (Position == 0)
01683         Position = m_BitmapListSize;
01684         
01685     SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), Position);
01686 }
01687 
01688 /*************************************************************************************************************
01689 
01690 >   BOOL PreviewDialog::SetRegeneratedBitmapInList(GIFAnimationExportParam* pParam, UINT32 BitmapNumber)
01691 
01692     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01693     Created:    14/05/97
01694     Inputs:     pParam - GIF Export Options
01695                 BitmapNumber - A reference to the bitmap which will be replaced with our regenerated bitmap.
01696     Otutputs    -
01697     REturns     TRUE if successful, else FALSE.
01698     Purpose:    If we need to regenerate a SINGLE bitmap while the Preview dialog is open, 
01699                 this function allows us to update our Bitmap list.              
01700 
01701 ***************************************************************************************************************/
01702 
01703 BOOL PreviewDialog::SetRegeneratedBitmapInList(GIFAnimationExportParam* pParam)
01704 {
01705     if (pParam == NULL)
01706         ERROR2RAW("PreviewDialog::SetRegeneratedBitmapInList bad params");
01707 
01708     // For the regenerated bitmap, retrieve it's position in the list. 
01709     UINT32 BitmapNumber = pParam->GetRegeneratedBitmapPosition();
01710 
01711 #ifdef _DEBUG
01712     UINT32 BitmapCount = pParam->GetBitmapCount();
01713     ERROR3IF(BitmapCount != 1, "BitmapCount specifid an illegal value");
01714 #endif
01715 
01716     // Ensure that a reference to this bitmap will exist.
01717     DWORD Count = m_BitmapList.GetCount();
01718 
01719     if (BitmapNumber > Count - 1)
01720         return FALSE;
01721 
01722     //  Find the first bitmap in the list.
01723     AnimatedBitmapItem* pList = (AnimatedBitmapItem*) m_BitmapList.GetHead();
01724 
01725     if (!pList) 
01726         return FALSE;
01727 
01728     // Loop counter.
01729     UINT32 Num = 0;
01730  
01731     // Find the bitmap corresponding to BitmapNumber.
01732     while (Num != BitmapNumber)
01733     {
01734         pList = (AnimatedBitmapItem*) m_BitmapList.GetNext(pList);
01735         Num++;
01736     }
01737 
01738     // Find the previous bitmap in the list.
01739     BOOL ListHead = FALSE;
01740     AnimatedBitmapItem * pPrev = (AnimatedBitmapItem*) m_BitmapList.GetPrev(pList);
01741 
01742     if (!pPrev)
01743     {
01744         //This must be the head of the list.
01745         ListHead = TRUE;
01746     }
01747 
01748     // Remove the bitmap corresponding to BitmapNumber from the list.
01749         m_BitmapList.RemoveItem(pList);
01750 
01751     // Retrieve the regenerated bitmap from GIFAnimationExportParam.
01752     KernelBitmap* pRegeneratedBitmap = pParam->GetBitmap(0);
01753     Layer * pLayer = pParam->GetLayer(0);
01754 
01755     if (pRegeneratedBitmap)
01756     {
01757         AnimatedBitmapItem * pNewItem = new AnimatedBitmapItem(pRegeneratedBitmap, pLayer);
01758         if (pNewItem)
01759         {
01760             // Add this bitmap to our list.
01761             if(ListHead)
01762                 m_BitmapList.AddHead(pNewItem);
01763             else
01764                 m_BitmapList.InsertAfter(pPrev, pNewItem);
01765         }   
01766     }
01767 
01768     return TRUE;
01769 }
01770 
01771 /*******************************************************************************************
01772 
01773 >   BOOL PreviewDialog::SetBitmapList(BitmapExportParam* pParam, BOOL SetSlider = TRUE)
01774 
01775     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
01776     Created:    14/05/97
01777     Inputs:     pParam      - GIF Export options
01778                 SetSlider   - True if want the slider position to be set (Default)
01779     Outputs     -
01780     Returns     TRUE if successful, else FALSE.
01781     Purpose:    If we need to regenerate our bitmaps while the Preview dialog is open,
01782                 this function allows us to update our list.             
01783 
01784 *******************************************************************************************/
01785 
01786 BOOL PreviewDialog::SetBitmapList(BitmapExportParam* pParam, BOOL SetSlider)
01787 {
01788     if (pParam == NULL)
01789             ERROR2RAW("PreviewDialog::SetBitmapList bad params");
01790 
01791     // Clean the list of bitmaps that we were animating.
01792     m_BitmapList.DeleteAll();
01793 
01794     // Store the bitmaps which have been passed to us.
01795     m_BitmapListSize = pParam->GetBitmapCount();
01796 
01797     if (m_BitmapListSize == 0)
01798         ERROR2RAW("PreviewDialog::SetBitmapList no bitmaps to preview");
01799     
01800     KernelBitmap* pTheBitmap = NULL;
01801     Layer * pLayer = NULL;
01802     MILLIPOINT MaxWidth = 0;
01803     MILLIPOINT MaxHeight = 0;
01804     for (INT32 i = 0; i < m_BitmapListSize; i++)
01805     {
01806         pTheBitmap = pParam->GetBitmap(i);
01807         pLayer = pParam->GetLayer(i);
01808 
01809         if (pTheBitmap)
01810         {
01811             AnimatedBitmapItem * pNewItem = new AnimatedBitmapItem(pTheBitmap, pLayer);
01812             if (pNewItem)
01813             {
01814                 // Add this item to our list.
01815                 m_BitmapList.AddTail(pNewItem);
01816 
01817                 MILLIPOINT Width = pTheBitmap->GetRecommendedWidth();
01818                 MILLIPOINT Height = pTheBitmap->GetRecommendedHeight();
01819                 if (Width > MaxWidth)
01820                     MaxWidth = Width;
01821                 if (Height > MaxHeight)
01822                     MaxHeight = Height;
01823             }
01824         }
01825     }
01826 
01827 PORTNOTE("other", "Removed GIFAnimationExportParam")
01828 #ifndef EXCLUDE_FROM_XARALX
01829     // Work out the bounding box of the animation and the loop count
01830     if (pParam->IS_KIND_OF(GIFAnimationExportParam))
01831     {
01832         GIFAnimationExportParam * pGIFParam = (GIFAnimationExportParam*)pParam;
01833         // Get the bounding rect that we have been passed in
01834         m_AnimationRect = pGIFParam->GetBoundingRect();
01835 
01836         // Get the loop count that we have been passed in
01837         m_RequiredLoopCount = pGIFParam->GetAnimLoop();
01838     }
01839     else
01840 #endif
01841     {
01842         // Look through all the bitmaps to find the biggest size
01843         // But we have already done this above, so use it
01844         m_AnimationRect = DocRect(0, 0, MaxWidth, MaxHeight);
01845 
01846         // Set the loop count to its default of loop forever
01847         m_RequiredLoopCount = 0;
01848     }
01849 
01850     // reset the current loop count to zero
01851     m_CurrentLoopCount = 0;
01852 
01853     // Reset the disposal methods
01854     m_DisposalMethod = GDM_BACKTOBACK;
01855     m_CurrentDisposalMethod = GDM_BACKTOBACK;
01856 
01857     if (SetSlider)
01858     {
01859         // Set the range of the slider control plus the step value.  
01860         INT32 StepValue = 100/ m_BitmapListSize;
01861         SetGadgetRange(_R(IDC_PREVIEW_SLIDER), 1, m_BitmapListSize, StepValue);
01862     }
01863 
01864     return TRUE;
01865 }
01866 
01867 /*******************************************************************************************
01868 
01869 >   UINT32 PreviewDialog::GetDelayForCurrentBitmap()
01870 
01871     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01872     Created:    14/4/97
01873     Returns:    Delay in centiseconds.
01874     Purpose:    Returns the delay in centiseconds for the current bitmap.
01875 
01876 *******************************************************************************************/
01877 
01878 UINT32 PreviewDialog::GetDelayForCurrentBitmap()
01879 {
01880     if (!viaBitmapGallery)
01881     {
01882         UINT32 Delay = 0;
01883         KernelBitmap * pBitmap = GetCurrentBitmap(FALSE);
01884         if (pBitmap)
01885         {
01886             // Ask the bitmap for its stored delay
01887             Delay = pBitmap->GetDelay();
01888             // If the delay specified is zero then use the default
01889             if (Delay == 0)
01890                 Delay = 10;
01891         }
01892 
01893         return Delay;
01894     }
01895     else
01896     {
01897         return (100);       // we wan't a longer delay ....
01898     }
01899 }
01900 
01901 
01902 /*******************************************************************************************
01903 
01904 >   OpState PreviewDialog::GetState(String_256*, OpDescriptor*)
01905 
01906     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01907     Created:    11/4/97
01908     Purpose:    Returns the OpState of the Preview dialogue operation
01909 
01910 *******************************************************************************************/
01911 
01912 OpState PreviewDialog::GetState(String_256*, OpDescriptor*)
01913 {
01914     return OpState(FALSE, FALSE);
01915 }
01916          
01917 
01918 /*******************************************************************************************
01919 
01920 >   BOOL PreviewDialog::Init()
01921 
01922     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01923     Created:    11/4/97
01924     Returns:    FALSE if it fails (due to lack of memory)
01925     Purpose:    Creates an OpDescriptor for a Preview Dialog
01926 
01927 *******************************************************************************************/
01928 
01929 BOOL PreviewDialog::Init()  
01930 {  
01931     return RegisterOpDescriptor(0,                              // Tool ID
01932                                 _R(IDS_PREVIEWDIALOG),              // String resource ID
01933                                 CC_RUNTIME_CLASS(PreviewDialog),// Runtime class
01934                                 OPTOKEN_PREVIEWDIALOG,          // Token string
01935                                 PreviewDialog::GetState,        // GetState function
01936                                 _R(IDH_Command_Preview_All_Frames), // Help ID
01937                                 0,                              // Bubble ID
01938                                 0,                              // Resource ID
01939                                 0,                              // Control ID
01940                                 SYSTEMBAR_ILLEGAL,              // Bar ID
01941                                 FALSE,                          // Recieve system messages
01942                                 FALSE,                          // Smart duplicate operation
01943                                 TRUE,                           // Clean operation
01944                                 0,                              // No vertical counterpart
01945                                 0);                             // String for one copy only
01946 }   
01947          
01948 
01949 /*******************************************************************************************
01950 
01951 >   virtual void PreviewDialog::DoWithParam(OpDescriptor* pOpDesc,OpParam* pParam)
01952 
01953     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01954     Created:    11/4/97
01955     Inputs:     pOpDesc     The OpDescriptor being invoked
01956                 pParam      The parameters being passed in
01957     Purpose:    Creates and shows a Preview dialog
01958 
01959 *******************************************************************************************/
01960 
01961 void PreviewDialog::DoWithParam(OpDescriptor* pOpDesc,OpParam* pParam)
01962 {
01963     TRACEUSER( "Neville", _T("PreviewDialog::DoWithParam\n"));
01964 
01965     // Check out the parameter that we should be being passed
01966     if (pParam == NULL)
01967     {
01968         ERROR2RAW("OpMenuExport::DoWithParam bad params");
01969         FailAndExecute();
01970         End();
01971         return;
01972     }
01973     
01974     BitmapExportParam* pExportParam = (BitmapExportParam*) pParam;
01975     ERROR3IF(!pExportParam->IS_KIND_OF(BitmapExportParam), "OpParam passed is not a BitmapExportParam");
01976 
01977     if (pExportParam->GetBitmapCount() == 0)
01978     {
01979         ERROR2RAW("OpMenuExport::DoWithParam no bitmaps to preview");
01980         FailAndExecute();
01981         End();
01982         return;
01983     }               
01984 
01985     // Take a copy of the list of bitmaps passed in
01986     // Don't set the slider position as we haven't constructed the dialog yet!
01987     SetBitmapList(pExportParam, FALSE);
01988 
01989     // Has more than one frame layer been generated.
01990     if(m_BitmapListSize > 1)
01991         m_GeneratedFrameLayers = TRUE;
01992 
01993     // Force the dialog box to be created.
01994     // If it is non-modal it must be opened if the create works ok.
01995     // If it is modal then don't call the open
01996     if (Create())
01997     {
01998         // If dialog is not Modal do this now
01999         // Otherwise set up happens in the message handler
02000         if (Mode == MODELESS)
02001         {
02002             // Try to resize the dialog box so that the current animation fits
02003             ResizeDialogToFitAnimation();
02004 
02005             // Set the initial control values 
02006             InitDialog();
02007 
02008             // If modeless then call open Open()
02009             Open();
02010         
02011             // Set up the call back so we get timer events
02012             SetUpCallBack();
02013         }
02014     }
02015     else
02016     {
02017         TRACE( _T("Failed to create Render Demo Dialog\n"));
02018         // Could not create the dialog box so call inform error 
02019         InformError();                      // Show user the error
02020         End();                              // End the operation 
02021     }
02022 
02023     return;
02024 }
02025 
02026 /*******************************************************************************************
02027 
02028 >   BOOL PreviewDialog::ResizeDialogToFitAnimation()
02029 
02030     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02031     Created:    11/6/97
02032     Returns:    True if worked ok, False otherwise
02033     Purpose:    Tries to resize the dialog to fit the animation in the preview control
02034 
02035 *******************************************************************************************/
02036 
02037 BOOL PreviewDialog::ResizeDialogToFitAnimation()
02038 {
02039     // Clean out the render region, if allocated, otherwise redraws may be funny
02040     // after the resize
02041     if (m_pRender)
02042     {
02043         // Delete the render region and its (dialog) view
02044         DestroyGRenderRegion(m_pRender);
02045         m_pRender = NULL;
02046     }
02047     
02048     // Get the handle of the dialog box. This is really an CWindowID.
02049 //  CWindowID hWnd = GetReadWriteWindowID();
02050 
02051     RECT RedrawRect;
02052     if (!GetGadgetPosition(_R(IDC_REDRAW_ME), &RedrawRect))
02053         return FALSE;
02054 
02055     // Work out the required size for the redraw icon
02056     // REMEMBER m_AnimationRect is in MILLIPOINTS 
02057     // Read from the dpi of the screen from the OS via the dialog manager
02058     INT32 ScreenDpi = GetScreenDpi();
02059     if (ScreenDpi <= 0)
02060         ScreenDpi = 96;
02061 
02062     // Work out the size of an output pixel in millipoints
02063     const INT32 PixelSize = 72000 / ScreenDpi;
02064     // And inflate the rect by 6 pixels to take account of the slab in
02065     ERROR3IF(m_AnimationRect.IsEmpty(),"m_AnimationRect not set up!");
02066     DocRect RequiredSize = m_AnimationRect;
02067     RequiredSize.Inflate(PixelSize * 6);
02068 
02069     INT32 Width = RequiredSize.Width() / PixelSize; 
02070     INT32 Height = RequiredSize.Height() / PixelSize; 
02071     
02072     // Read from the size of the screen from the OS via the dialog manager
02073     INT32 MaxWidth = 800;
02074     INT32 MaxHeight = 600;
02075     GetScreenSize(&MaxWidth, &MaxHeight);
02076 
02077     // Work out the size of redraw icon that is required
02078     INT32 CurrentWidth = RedrawRect.right - RedrawRect.left;
02079     INT32 NewWidth = CurrentWidth;
02080     if (Width > NewWidth)
02081         NewWidth = Width;
02082     if (NewWidth > MaxWidth)
02083         NewWidth = MaxWidth;
02084     INT32 DiffWidth = NewWidth - CurrentWidth;
02085 
02086     INT32 CurrentHeight = RedrawRect.bottom - RedrawRect.top;
02087     INT32 NewHeight = CurrentHeight;
02088     if (Height > NewHeight)
02089         NewHeight = Height;
02090     if (NewHeight > MaxHeight)
02091         NewHeight = MaxHeight;
02092     INT32 DiffHeight = NewHeight - CurrentHeight;
02093 
02094     // No changes required
02095     if (DiffHeight == 0 && DiffWidth == 0)
02096         return TRUE;
02097 
02098     // *************************************************
02099     // Make the redraw icon the required size
02100     RedrawRect.right  = RedrawRect.right + DiffWidth;
02101     RedrawRect.bottom = RedrawRect.bottom + DiffHeight;
02102     SetGadgetPosition(_R(IDC_REDRAW_ME), RedrawRect);
02103     
02104     // *************************************************
02105     RECT Rect;
02106     if (GetGadgetPosition(_R(IDC_3DFRAME), &Rect))
02107     {
02108         Rect.right  = Rect.right + DiffWidth;
02109         Rect.bottom = Rect.bottom + DiffHeight;
02110         SetGadgetPosition(_R(IDC_3DFRAME), Rect);
02111     }
02112 
02113     // *************************************************
02114     // Get the size and position of the dialog box itself
02115     if (GetWindowPosition(&Rect))
02116     {
02117         Rect.right  = Rect.right + DiffWidth;
02118         Rect.bottom = Rect.bottom + DiffHeight;
02119         SetWindowPosition(Rect);
02120     }
02121 
02122     // Force a redraw of the items that we have changed
02123     // causes a DIM_REDRAW\_R(IDC_REDRAW_ME) message to be sent.
02124     InvalidateGadget(_R(IDC_3DFRAME));
02125     InvalidateGadget(_R(IDC_REDRAW_ME));
02126 
02127     return TRUE;
02128 }
02129 
02130 /*******************************************************************************************
02131 
02132 >   BOOL PreviewDialog::SetUpCallBack()
02133 
02134     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02135     Created:    14/4/97
02136     Returns:    True if worked ok, False otherwise
02137     Purpose:    Sets up the call back for this dialog box so that we get timer events and
02138                 so can animate the bitmap on display.
02139 
02140 *******************************************************************************************/
02141 
02142 BOOL PreviewDialog::SetUpCallBack()
02143 {
02144     // set the delay for the first bitmap that we are going to display
02145     m_Delay = GetDelayForCurrentBitmap();
02146     return m_Timer.Start(m_Delay * 10, TRUE);
02147 }
02148 
02149 
02150 
02151 /*******************************************************************************************
02152 >   static BOOL PreviewDialog::TimerProc(HiResTimer* pThisTimer, INT32 nElapsed, void* pvData)
02153 
02154     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
02155     Created:    11/4/97
02156     Inputs:     (see HiResTimer::Callback)
02157     Purpose:    This callback function is called when the new frame in the GIF should be
02158                 displayed.  It resets the timer to generate an event for the subsequent
02159                 frame.
02160 *******************************************************************************************/
02161 
02162 void PreviewDialog::OnTimer()
02163 {
02164     if (m_pPreviewDialog != NULL)
02165     {
02166         // Stop the animation if the properties are changed or the document is closd.
02167         if(m_AnimationPropertiesChanged || m_DocumentAboutToDie)
02168         {
02169             // Stop any pending timer events.
02170             if (m_Timer.IsRunning())
02171                 m_Timer.Stop();
02172             return;
02173         }
02174     
02175         // Move to the next bitmap in the list
02176         IncrementCurrentBitmap();
02177 
02178         // Force the gadget to be repainted
02179         InvalidateGadget(_R(IDC_REDRAW_ME));
02180         PaintGadgetNow(_R(IDC_REDRAW_ME));
02181 
02182         // Get the delay until we need to show the next frame
02183         m_Delay = GetDelayForCurrentBitmap();
02184 
02185         // Reset the timer.
02186         m_Timer.Start(m_Delay * 10, FALSE);
02187     }
02188 
02189     return;
02190 }
02191 
02192 
02193 /********************************************************************************************
02194 
02195 >   virtual BOOL PreviewDialog::OnIdleEvent(void)
02196 
02197     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> 
02198     Created:    21/05/97
02199     Inputs:     -
02200     Returns:    TRUE if it does not want low-priority idle handlers to be called this time
02201                 FALSE if it's OK to call low-priority idles.
02202     Purpose:    Used to detect when the mouse has stopped moving 
02203                 Therefore allows us to implement bubble help for the Preview Dialog.
02204 
02205 ********************************************************************************************/
02206 
02207 BOOL PreviewDialog::OnIdleEvent(void)
02208 {
02209     UpdateBubbleHelp();
02210         return FALSE;
02211 };
02212 
02213 /********************************************************************************************
02214 
02215 >   void PreviewDialog::UpDateBubbleHelp(void)
02216 
02217     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason code)
02218     Created:    21/05/97
02219     Inputs:     -
02220     Purpose:    Called for Idle events to provide bubble help for the Preview Dialog.
02221 
02222 ********************************************************************************************/
02223 void PreviewDialog::UpdateBubbleHelp(void)
02224 {
02225 PORTNOTE("other", "Disabled PreviewDialog bubble help")
02226 #ifndef EXCLUDE_FROM_XARALX
02227     PreviewDialog *pPrvDlg = m_pPreviewDialog;
02228     if (pPrvDlg == NULL)
02229         return;
02230 
02231     static CWindowID TheWindow = NULL;
02232     
02233     if (TheWindow == NULL)
02234         TheWindow = (CWindowID)pPrvDlg->WindowID;
02235 
02236     if (TheWindow == NULL)
02237         return;
02238 
02239     static MonotonicTime LastUpdate;
02240     static UINT32 MousePos = NULL;
02241 
02242     if (LastUpdate.Elapsed(100))
02243     {
02244         // Remember when we last checked
02245         LastUpdate.Sample();
02246 
02247         // Default to the mouse being "nowhere special" again
02248         TheWindow = (CWindowID)pPrvDlg->WindowID;
02249         MousePos = NULL;
02250 
02251         POINT MouseScreenPos;
02252         if (::GetCursorPos(&MouseScreenPos))
02253         {
02254             // Only continue processing if the window under the pointer is the Preview Dialog
02255             
02256             CWindowID WindowUnder = ::WindowFromPoint(MouseScreenPos);
02257 
02258             if (WindowUnder != NULL &&
02259                 (WindowUnder == TheWindow || ::GetParent(WindowUnder) == TheWindow))
02260             {
02261                 POINT TempPos;
02262                 TempPos.x = MouseScreenPos.x;
02263                 TempPos.y = MouseScreenPos.y;
02264 
02265                 // Convert to client coords in the main window
02266                 ::ScreenToClient(TheWindow, &TempPos);
02267 
02268                 CPoint Pos(TempPos);
02269                 CWindowID WindowUnderPointer = ::ChildWindowFromPoint(TheWindow, Pos);
02270                 if (WindowUnderPointer != NULL)// && IsWindowVisible(WindowUnderPointer))
02271                 {
02272                     // Make sure that hidden windows do not provide status help!
02273                     INT32 WindowStyle = ::GetWindowLong(WindowUnderPointer, GWL_STYLE);
02274                     if ((WindowStyle & WS_VISIBLE) != 0)
02275                     {
02276                         CWindowID hGadget;
02277                         INT32 i = 0;
02278                         while (BubbleHelp[i].Gadget != NULL && MousePos == NULL)
02279                         {
02280                             hGadget = GetDlgItem(TheWindow, BubbleHelp[i].Gadget);
02281                             if (WindowUnderPointer == hGadget)
02282                             {
02283                                 MousePos = (UINT32)BubbleHelp[i].Gadget;
02284                                 TheWindow = hGadget;
02285                             }
02286                             i++;
02287                         }
02288                     }
02289                 }
02290             }
02291         }
02292     }
02293     // Tell the bubble help system what help we want.
02294     if (MousePos != NULL)
02295     {
02296         // Set up our callback handler to show the bubble help. 
02297         ControlHelper::DoBubbleHelpOn(TheWindow, MousePos, PreviewDialog::HelpCallbackHandler, NULL);
02298     }
02299 #endif
02300 }
02301 
02302 /********************************************************************************************
02303 
02304 >   TCHAR* PreviewDialog::HelpCallbackHandler(CWindowID Window, UINT32 Item, void *UserData)
02305 
02306     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> (Based onn Jason code)
02307     Created:    21/05/97
02308     Inputs:     Window   - The window to get help for
02309                 Item     - The control to get help for
02310                 UserData - User-supplied data (not used)
02311     Returns:    The bubble help string to use, or NULL if no help is available.
02312     Purpose:    Help callback handler to provide bubble help for the POreview Diaolg.
02313     
02314 ********************************************************************************************/
02315 
02316 TCHAR *PreviewDialog::HelpCallbackHandler(CWindowID Window, UINT32 Item, void *UserData)
02317 {
02318     static String_256 HelpStringStore;
02319     BOOL ReturnVal = FALSE;
02320 
02321     PreviewDialog* pPreviewDlg = m_pPreviewDialog;
02322     if (pPreviewDlg == NULL)
02323         return(NULL);
02324 
02325     if (Item == _R(IDC_PREVIEW_PLAY))
02326     {
02327         HelpStringStore = String_256(_R(IDS_PREVIEWBH_PLAY));
02328         ReturnVal = TRUE;
02329     }
02330     else if (Item == _R(IDC_PREVIEW_STOP))
02331     {
02332         HelpStringStore = String_256(_R(IDS_PREVIEWBH_STOP));
02333         ReturnVal = TRUE;
02334     }
02335     else if (Item == _R(IDC_PREVIEW_NEXTFRAME))
02336     {
02337         HelpStringStore = String_256(_R(IDS_PREVIEWBH_NEXTFRAME));
02338         ReturnVal = TRUE;
02339     }
02340     else if (Item == _R(IDC_PREVIEW_PREVFRAME))
02341     {
02342         HelpStringStore = String_256(_R(IDS_PREVIEWBH_PREVFRAME));
02343         ReturnVal = TRUE;
02344     }
02345     else if (Item == _R(IDC_PREVIEW_SLIDER))
02346     {
02347         HelpStringStore = String_256(_R(IDS_PREVIEWBH_SLIDER));
02348         ReturnVal = TRUE;
02349     }
02350 
02351     if (ReturnVal)
02352         return((TCHAR *) HelpStringStore);
02353 
02354     return(NULL);
02355     
02356 }
02357 
02358 
02359 /********************************************************************************************
02360 
02361 >   BOOL PreviewDialog::GetStatusLineText(String_256 *Result)
02362 
02363     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> (Based on Jason code)
02364     Created:    21/05/97
02365     Inputs:     *Result - The String to recieve the status line text.
02366     Outputs     The Status Line string to use, or NULL if not available.
02367     Returns     TRUE if successful, else false. 
02368         
02369 ********************************************************************************************/
02370 
02371 BOOL PreviewDialog::GetStatusLineText(String_256 *Result)
02372 {
02373 PORTNOTE("other", "Disabled bitmap preview dialog live status text")
02374 #ifndef EXCLUDE_FROM_XARALX
02375     ERROR3IF(Result == NULL, "Illegal NULL param");
02376         
02377     PreviewDialog* pPreviewDlg = m_pPreviewDialog;
02378 
02379     if (pPreviewDlg == NULL)
02380         return(FALSE);
02381 
02382     // Find the main editor window
02383     CWindowID TheWindow = (CWindowID)pPreviewDlg->WindowID;
02384     if (TheWindow == NULL)
02385         return(FALSE);
02386 
02387     // Get the cursor position in screen coords
02388     POINT TempPos;
02389     if (!::GetCursorPos(&TempPos))
02390         return(FALSE);
02391 
02392     // Convert to client coords in the main window
02393     ScreenToClient(TheWindow, &TempPos);
02394 
02395     // See if this is over the main window or any child, get it's CWindowID
02396     CPoint Pos(TempPos);    
02397     CWindowID WindowUnderPointer = ::ChildWindowFromPoint(TheWindow, Pos);
02398     if (WindowUnderPointer == NULL)
02399         return(FALSE);
02400 
02401     // Make sure that hidden windows do not provide status help!
02402     INT32 WindowStyle = ::GetWindowLong(WindowUnderPointer, GWL_STYLE);
02403     if ((WindowStyle & WS_VISIBLE) == 0)
02404         return(FALSE);
02405 
02406     // If the pointer is over main window background, return standard help
02407     if (WindowUnderPointer == TheWindow)
02408         return(GetStatusLineText(pPreviewDlg, 0, Result));
02409 
02410     // Otherwise, see if we can find help for the specific gadget
02411     CWindowID hGadget;
02412     INT32 i = 0;
02413     while (BubbleHelp[i].Gadget != NULL)
02414     {
02415         hGadget = GetDlgItem(TheWindow, BubbleHelp[i].Gadget);
02416         if (WindowUnderPointer == hGadget && GetStatusLineText(pPreviewDlg, BubbleHelp[i].Gadget, Result))
02417             return(TRUE);
02418         i++;
02419     }
02420     return FALSE;
02421 #else
02422     return TRUE;
02423 #endif
02424 }
02425 
02426 /************************************************************************************************
02427 
02428 >   static BOOL PreviewDialog::GetStatusLineText(PreviewDialog *pPrvDlg, UINT32 GadgetID,
02429                                                     String_256 *Result)
02430 
02431     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02432     Created:    21/05/97
02433     Inputs:     pPrvDlg - Points to the current Preview Dialog.
02434                 GadgetID - indicates the gadget for which you want status bar help.
02435     Outputs:    If return value is TRUE, Result is updated with an appropriate help string.
02436     Returns:    -
02437     
02438 **************************************************************************************************/
02439 
02440 BOOL PreviewDialog::GetStatusLineText(PreviewDialog *pPrvDlg, UINT32 GadgetID,String_256 *Result)
02441 {
02442     if (GadgetID == _R(IDC_PREVIEW_PLAY))
02443     {
02444         *Result = String_256(_R(IDS_PREVIEWST_PLAY));
02445     }
02446     else if (GadgetID == _R(IDC_PREVIEW_STOP))
02447     {
02448         *Result = String_256(_R(IDS_PREVIEWST_STOP));
02449     }
02450     else if (GadgetID == _R(IDC_PREVIEW_NEXTFRAME))
02451     {
02452         *Result = String_256(_R(IDS_PREVIEW_NEXTFRAME));
02453     }
02454     else if (GadgetID == _R(IDC_PREVIEW_PREVFRAME))
02455     {
02456         *Result = String_256(_R(IDS_PREVIEW_PREVFRAME));
02457     }
02458     return TRUE;
02459 }
02460 
02461 /***********************************************************************************************
02462 
02463 >   BOOL PreviewDialog::DoRegenerateSingleFrame()
02464 
02465     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02466     Created:    21/05/97
02467     Inputs:     -
02468     Returns:    True if worked ok, False otherwise
02469     Purpose:    While previewing an animation, if the Reset button is clicked we need to regrab 
02470                 all the frames. This function invokes the correct Op.
02471 
02472 *************************************************************************************************/
02473 BOOL PreviewDialog::DoRegenerateFrames()
02474 {
02475     // When in stop mode, we should try and regrab the frame being displayed
02476     // When in play mode, we should grab the entire animation
02477     // If we were in stand by mode then grab the active frame.
02478 
02479 PORTNOTE("other", "Disabled BrowserPreviewOptions")
02480 #ifndef EXCLUDE_FROM_XARALX
02481     // Return false if the document is empty.
02482     String_256 ShadeReason;
02483     OpState State = OpGrabAllFrames::GetState(&ShadeReason, NULL);
02484     if (State.Greyed)
02485     {
02486         if(!m_SetPreviewDlgToIdleState)
02487             //Set the dlg to an idle state.
02488             m_SetPreviewDlgToIdleState = TRUE;
02489 
02490         // Force the gadget to be repainted.
02491         m_pPreviewDialog->InvalidateGadget(_R(IDC_REDRAW_ME));
02492         return FALSE;           
02493     }
02494 #endif
02495     
02496     // Temp flags to remember whether the animation was playing/How may layers existed
02497     // before all the frames were regenerated.
02498     BOOL AnimationPlaying = FALSE;
02499     //UINT32 PreRefreshNumberOfLayers = m_BitmapListSize;
02500     BOOL IdleState = m_SetPreviewDlgToIdleState;
02501     
02502     // If we are not in an idle state already then ensure that we are playing we are stopped
02503     if (!m_SetPreviewDlgToIdleState)
02504     {
02505         // Stop the animation.
02506         if (m_PlayAnimation)
02507         {
02508             StopPreviewing();
02509 
02510             AnimationPlaying = TRUE;
02511         }
02512     }
02513 
02514     // Set the dlg idle flag back to false.
02515     m_SetPreviewDlgToIdleState = FALSE;
02516     
02517     // Are we in single bitmap mode?
02518     BOOL SingleBitmapMode = (m_BitmapListSize == 1);
02519 
02520     // If we were playing or idle then grab all frames
02521     //if (AnimationPlaying || IdleState)
02522     // If we are in an idle state or we are in multiple bitmap mode then
02523     // refresh = grab all frames
02524     if (IdleState || !SingleBitmapMode)
02525     {
02526         // If we were playing or idle then ensure that we restart in play mode
02527         if (AnimationPlaying || IdleState)
02528             m_PlayAnimation = TRUE;
02529         else
02530             m_PlayAnimation = FALSE;
02531 
02532         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABALLFRAMES); 
02533         if (pOpDesc != NULL)
02534             pOpDesc->Invoke();
02535         else
02536         {
02537             ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor");
02538         }
02539     }
02540     else
02541     {
02542         // We were showing a single frame so try and refresh this layer
02543         // and show it again.
02544         Layer * pLayerToRefresh = NULL;
02545         KernelBitmap * pBitmap = GetCurrentBitmap();
02546         if (pBitmap != NULL)
02547         {
02548             // Search through the layers for this bitmap and then try and regenerate it
02549             // If we don't find it then regnerate the active layer
02550             Spread * pSpread = Document::GetSelectedSpread();
02551             if (pSpread)
02552             {
02553                 Layer * pLayer = pSpread->FindFirstFrameLayer();
02554                 BOOL Found = FALSE;
02555                 while (pLayer != NULL && !Found)
02556                 {
02557                     KernelBitmap * pLayerBitmap = pLayer->GetGeneratedBitmap();
02558                     if (pLayerBitmap == pBitmap)
02559                     {
02560                         pLayerToRefresh = pLayer;
02561                         Found = TRUE;
02562                     }
02563                     
02564                     pLayer = pLayer->FindNextFrameLayer();
02565                 }
02566             }
02567         }
02568 
02569         // Ensure that we restart in stop mode
02570         m_PlayAnimation = FALSE;
02571 
02572         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABFRAME); 
02573         // Pass in pLayerToRefresh as a possible layer to refresh
02574         if (pOpDesc != NULL)
02575         {
02576             OpParam Param;
02577             Param.Param1 = (void *)pLayerToRefresh;
02578             pOpDesc->Invoke(&Param);
02579         }
02580         else
02581         {
02582             ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor");
02583         }
02584     }
02585 
02586     // The ops should call us back to set everything up.
02587 
02588     // We will just ensure that these are set correctly
02589     // Set the flags to the correct state.
02590     m_DocumentAboutToDie        =   FALSE;
02591     m_SetPreviewDlgToIdleState  =   FALSE;
02592 
02593     // Reset the loop counts
02594     m_CurrentLoopCount          = 0;    // The loop that we are currently on (default to start)
02595     m_RequiredLoopCount         = 0;    // The loop count that we must reach (default for ever)
02596 
02597     // Through a document change, the timer may not be ticking.
02598     // If it has been stopped, then re-start.
02599     RestartTimer();
02600 
02601     return TRUE;
02602 }
02603 
02604 /****************************************************************************************************
02605 
02606 >   BOOL PreviewDialog::SetPreviewDialogToIdleState();
02607 
02608     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> (From Neville code)
02609     Created:    28/05/97
02610     Inputs:     -
02611     Returns:    True if worked ok, False otherwise
02612     Purpose:    If the preview animation dialog is open, and the user does any of the following:-
02613                 Changes the current doc.
02614                 Closes the current doc.
02615                 Opens a new doc.
02616                 Then we stop playing the current animation, and set the dialog to a grey background
02617                 with a cross in the centre.
02618             
02619 *****************************************************************************************************/
02620 
02621 void PreviewDialog::SetPreviewDialogToIdleState(ReDrawInfoType* pExtraInfo)
02622 {
02623     if (pExtraInfo == NULL)
02624         return;
02625 
02626     // Go get a render region
02627     DocRect VirtualSize(0, 0, pExtraInfo->dx, pExtraInfo->dy);
02628     BOOL StartedOk = FALSE;
02629 
02630     // we should have a render region, but to be on the safe side.
02631     if (m_pRender == NULL)
02632     {   
02633         // This will call start render for us
02634         m_pRender = CreateGRenderRegion(&VirtualSize, pExtraInfo);
02635     }
02636     else
02637     {
02638         // and delete the render region and its (dialog) view
02639         View * pDialogView = m_pRender->GetRenderView();
02640     
02641         if (pDialogView)
02642         {
02643             // Try and create the bitmap etc
02644             StartedOk = m_pRender->AttachDevice(pDialogView, pExtraInfo->pDC, NULL);
02645 
02646             // Try and start the render region
02647             StartedOk = StartedOk && m_pRender->StartRender();
02648         }
02649         else
02650             StartedOk = FALSE;
02651     }
02652 
02653     // if we have a render region then go and use it
02654     if (m_pRender != NULL && StartedOk)
02655     {
02656         // Code stolen from ColourEditDlg::RenderControl
02657         DialogColourInfo RedrawColours;             // Get a supplier for default dlg colours
02658         INT32 PixelSize = 72000 / pExtraInfo->Dpi;  // Size of output pixel in millipoints
02659 
02660         // Render the attributes and then a rectangle
02661         m_pRender->SaveContext();
02662             
02663         // Draw a cross to signify we are in a halted or idle state
02664         RedrawCross(&VirtualSize, &RedrawColours, PixelSize);
02665 
02666         m_pRender->RestoreContext();
02667 
02668         // Blit to the screen
02669         m_pRender->StopRender();
02670     }
02671 
02672     // Set the correct state of the dlg controls.
02673     EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);
02674     EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
02675     EnableGadget(_R(IDC_PREVIEW_NEXTFRAME), FALSE);
02676     EnableGadget(_R(IDC_PREVIEW_PREVFRAME), FALSE);
02677 
02678     // Clean the list of bitmaps that we were animating.
02679     m_BitmapList.DeleteAll();
02680     m_BitmapListSize            = 0;
02681     m_CurrentItem               = 0;
02682     m_SliderPosition            = m_BitmapListSize;
02683     m_AnimationRect.MakeEmpty();
02684 
02685     // Set the slider back to a good state
02686     SetGadgetRange(_R(IDC_PREVIEW_SLIDER), 1, 1, 100);  
02687     SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), 1 );
02688 
02689     // Disable the slider
02690     EnableGadget(_R(IDC_PREVIEW_SLIDER), FALSE);
02691 }
02692 
02693 /*************************************************************************************************************
02694 
02695 >   BOOL PreviewDialog::SetBitmapToListTail(GIFAnimationExportParam* pParam)
02696 
02697     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02698     Created:    28/05/97
02699     Inputs:     pParam - GIF Export Options
02700     Outputs -
02701     Returns     TRUE if successful, else FALSE.
02702     Purpose:    If we need to (re)generate asingle bitmap while the Preview dialog is open, 
02703                 this function allows us to add the Bitmap to the Tail of the list.              
02704 
02705 ***************************************************************************************************************/
02706 
02707 BOOL PreviewDialog::SetBitmapToListTail(GIFAnimationExportParam* pParam)
02708 {
02709     if (pParam == NULL)
02710         ERROR2RAW("PreviewDialog::SetRegeneratedBitmapInList bad params");
02711 
02712 #ifdef _DEBUG
02713     // Ensure we only have a single bitmap in our list.
02714     UINT32 BitmapCount = pParam->GetBitmapCount();
02715     ERROR3IF(BitmapCount != 1, "BitmapCount specifid an illegal value");
02716 #endif
02717 
02718     // Increment the value of list size.
02719     m_BitmapListSize++; 
02720 
02721     // Retrieve the generated bitmap from GIFAnimationExportParam.
02722     KernelBitmap* pRegeneratedBitmap = pParam->GetBitmap(0);
02723     Layer * pLayer = pParam->GetLayer(0);
02724 
02725     if (pRegeneratedBitmap)
02726     {
02727         AnimatedBitmapItem * pNewItem = new AnimatedBitmapItem(pRegeneratedBitmap, pLayer);
02728         if (pNewItem)
02729         {
02730             // Add this bitmap to the tail of our list.
02731             m_BitmapList.AddTail(pNewItem);
02732         }
02733     }
02734 
02735     return TRUE;
02736 }
02737 
02738 /*************************************************************************************************************
02739 
02740 >   BOOL PreviewDialog::SetDlgStateAfterDocChange()
02741 
02742     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02743     Created:    28/05/97
02744     Inputs:     -
02745     Outputs:    -
02746     Returns:    TRUE if successful, else FALSE.
02747     Purpose:    If the Preview dialog is open before and after a doument change, then play the animation and
02748                 set the correct state of the controls.
02749 
02750 ***************************************************************************************************************/
02751 BOOL PreviewDialog::SetDlgStateAfterDocChange()
02752 {
02753     // The document has changed, the refresh button has been clicked,
02754     // regenerate all the frames, set the controls to the correct state.
02755     // and play the animation.
02756 
02757     // All the setting up of the new state of the dialog will happen when the op
02758     // realises that the dialog is already open and calls ReInitDialog().
02759     if(!DoRegenerateFrames())
02760         return FALSE;
02761 
02762     return TRUE;
02763 }
02764 
02765 /*************************************************************************************************************
02766 
02767 >   BOOL PreviewDialog::SetDlgStateAfterRefresh()
02768 
02769     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02770     Created:    28/05/97
02771     Inputs:     -
02772     Outputs:    -
02773     Returns:    TRUE if successful, else FALSE.
02774     Purpose:    When the preview dlg is open, if the refresh button is clicked, this function 
02775                 refreshes the current state of the dialog. 
02776 
02777 ***************************************************************************************************************/
02778 BOOL PreviewDialog::SetDlgStateAfterRefresh()
02779 {
02780     // Refresh the current state of the dialog:-
02781     // When in stop mode, we should try and regrab the frame being displayed
02782     // When in play mode, we should grab the entire animation
02783     // If we were in stand by mode then grab the active frame.
02784 
02785     // All the setting up of the new state of the dialog will happen when the op
02786     // realises that the dialog is already open and calls ReInitDialog().
02787     if(!DoRegenerateFrames())
02788         return FALSE;
02789 
02790     return TRUE;
02791 }
02792 
02793 /*************************************************************************************************************
02794 
02795 >   void PreviewDialog::PreviewDlgPlay()
02796 
02797     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02798     Created:    28/05/97
02799     Inputs:     -
02800     Outputs:    -
02801     Returns:    -
02802     Purpose:    After the play button has been clicked, this functions plays the animation and 
02803                 sets the correct state of the controls.
02804                 
02805 ***************************************************************************************************************/
02806 void PreviewDialog::PreviewDlgPlay()
02807 {
02808     // We should ensure that all the frames are up to date. The simplest way of doing this is
02809     // by calling the GrabAllFrames op. This should ensure that the frames are up to date
02810     // and force play to on. It should also rest the dialog to the way it should be.
02811     // Ensure that when we come back we are in play mode.
02812     m_PlayAnimation = TRUE;
02813 
02814     if (!viaBitmapGallery)
02815     {
02816         // we need to do this - so that we can call the followinf invoke ....
02817         //DialogBarOp::SetSystemStateChanged();
02818 
02819         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_FRAME_GRABALLFRAMES); 
02820         if (pOpDesc != NULL)
02821             pOpDesc->Invoke();
02822         else
02823         {
02824             ERROR3("Couldn't find OPTOKEN_FRAME_GRABALLFRAMES op descriptor");
02825         }
02826     }
02827     else
02828     {
02829         //Disable the Play button.
02830         EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);
02831 
02832         //Enable the Stop button.
02833         EnableGadget(_R(IDC_PREVIEW_STOP), TRUE);
02834 
02835         // Set the correct state of the flags.
02836         m_DocumentAboutToDie = FALSE;
02837         m_GeneratedFrameLayers = TRUE;
02838 
02839         // After a document change/refresh, the bitmap list size may have changed.
02840         INT32 StepValue = 100/ m_BitmapListSize;
02841         SetGadgetRange(_R(IDC_PREVIEW_SLIDER), 1, m_BitmapListSize, StepValue); 
02842         SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), m_BitmapListSize - m_CurrentItem);
02843 
02844         // Through a document change, the timer may not be ticking.
02845         // If it has been stopped, then re-start.
02846         RestartTimer();
02847     }
02848     
02849     // The old way of doing it, jsut play the animation
02850 /*  // Play the Animation.
02851     m_PlayAnimation = TRUE;
02852 
02853     //Disable the Play button.
02854     EnableGadget(_R(IDC_PREVIEW_PLAY), FALSE);
02855 
02856     //Enable the Stop button.
02857     EnableGadget(_R(IDC_PREVIEW_STOP), TRUE);
02858 
02859     // Set the correct state of the flags.
02860     m_DocumentAboutToDie = FALSE;
02861     m_GeneratedFrameLayers = TRUE;
02862 
02863     // After a document change/refresh, the bitmap list size may have changed.
02864     INT32 StepValue = 100/ m_BitmapListSize;
02865     SetGadgetRange(_R(IDC_PREVIEW_SLIDER), 1, m_BitmapListSize, StepValue); 
02866     SetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), m_BitmapListSize - m_CurrentItem);
02867 
02868     // Through a document change, the timer may not be ticking.
02869     // If it has been stopped, then re-start.
02870     RestartTimer(); */
02871 }
02872 
02873 /*************************************************************************************************************
02874 
02875 >   void PreviewDialog::PreviewDlgStop()
02876 
02877     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02878     Created:    28/05/97
02879     Inputs:     -
02880     Outputs:    -
02881     Returns:    -
02882     Purpose:    After the Stop button has been cllicked, this functions Stops the animation and 
02883                 sets the correct state of the controls.
02884                 
02885 ***************************************************************************************************************/
02886 void PreviewDialog::PreviewDlgStop()
02887 {
02888     // Only display the last bitmap when this button is clicked.
02889     m_PlayAnimation = FALSE;
02890 
02891     //Enable the Play button. 
02892     EnableGadget(_R(IDC_PREVIEW_PLAY), TRUE);
02893 
02894     // Disable the Stop button.
02895     EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
02896 }
02897 
02898 /*************************************************************************************************************
02899 
02900 >   void PreviewDialog::PreviewNextFrame()
02901 
02902     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02903     Created:    28/05/97
02904     Inputs:     -
02905     Outputs:    -
02906     Returns:    -
02907     Purpose:    After the preview next frame button is clicked, if the animation was playing this 
02908                 function stops tha animation, and selects the next frame.   
02909                                 
02910 ***************************************************************************************************************/
02911 void PreviewDialog::PreviewNextFrame()
02912 {
02913     // If the animation is playing, set the correct state of the controls.
02914     if (m_PlayAnimation)
02915     {
02916         EnableGadget(_R(IDC_PREVIEW_PLAY), TRUE);
02917         EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
02918     }
02919 
02920     // Stop the animation.
02921     m_PlayAnimation = FALSE;
02922     m_DisplayNextFrame = TRUE;
02923 
02924     // Find the correct bitmap to display.                      
02925     BOOL Valid;
02926     m_SliderPosition = GetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), 0, m_BitmapListSize, 0, &Valid);
02927     UINT32 BitmapNum = m_BitmapListSize - m_SliderPosition;
02928     SelectCurrentBitmap(BitmapNum);
02929 
02930     // Move to the next bitmap in the list.
02931     IncrementCurrentBitmap();
02932 }
02933 
02934 /*************************************************************************************************************
02935 
02936 >   void PreviewDialog::PreviewPreviousFrame()
02937 
02938     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02939     Created:    28/05/97
02940     Inputs:     -
02941     Outputs:    -
02942     Returns:    -
02943     Purpose:    After the Preview previous frame button is cllicked, if the animation was playing this 
02944                 function stops tha animation, and selects the previous frame.   
02945                                 
02946 ***************************************************************************************************************/
02947 void PreviewDialog::PreviewPreviousFrame()
02948 {
02949     if (m_PlayAnimation)
02950     {
02951         EnableGadget(_R(IDC_PREVIEW_PLAY), TRUE);
02952         EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
02953     }
02954 
02955     m_PlayAnimation = FALSE;
02956     m_DisplayPreviousFrame = TRUE;
02957 
02958     // Find the correct bitmap to display.                      
02959     BOOL Valid;
02960     m_SliderPosition = GetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), 0, m_BitmapListSize, 0, &Valid);
02961     UINT32 BitmapNum = m_BitmapListSize - m_SliderPosition;
02962     SelectCurrentBitmap(BitmapNum);
02963                             
02964     // Move to the previous bitmap in the list.
02965     DecrementCurrentBitmap();
02966 }
02967 
02968 /*************************************************************************************************************
02969 
02970 >   void PreviewDialog::SetSliderPosition()
02971 
02972     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
02973     Created:    28/05/97
02974     Inputs:     -
02975     Outputs:    -
02976     Returns:    -
02977     Purpose:    This functiion deals with clicks on the Preview dialog slider control.
02978                                 
02979 ***************************************************************************************************************/
02980 void PreviewDialog::SetSliderPosition()
02981 {
02982     // Set the correct state of the controls.
02983     if (m_PlayAnimation && m_BitmapListSize > 1)
02984     {
02985         EnableGadget(_R(IDC_PREVIEW_PLAY), TRUE);
02986         EnableGadget(_R(IDC_PREVIEW_STOP), FALSE);
02987     }
02988 
02989     // Stop the animation. 
02990     m_PlayAnimation = FALSE;    
02991                         
02992     // Get the new Slider position.
02993     BOOL Valid;
02994     m_SliderPosition = GetLongGadgetValue(_R(IDC_PREVIEW_SLIDER), 0, m_BitmapListSize, 0, &Valid);
02995 
02996     // Find the correct bitmap to display.                      
02997     UINT32 BitmapNum = m_BitmapListSize - m_SliderPosition;
02998     SelectCurrentBitmap(BitmapNum);
02999 
03000     // Set the new slider position.
03001     SetSliderPosition(m_SliderPosition);
03002 }
03003 
03004 /*************************************************************************************************************
03005 
03006 >   void PreviewDialog::RestartTimer()
03007 
03008     Author:     Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com>
03009     Created:    28/05/97
03010     Inputs:     -
03011     Outputs:    -
03012     Returns:    -
03013     Purpose:    If for some reason the timer was stopped, this function will re-start it.
03014                                 
03015 ***************************************************************************************************************/
03016 void PreviewDialog::RestartTimer()
03017 {
03018     // Has the timer been stopped.
03019     if (!m_Timer.IsRunning())
03020     {
03021         // Re-start the timer.
03022         SetUpCallBack();
03023     }
03024 }

Generated on Sat Nov 10 03:46:35 2007 for Camelot by  doxygen 1.4.4