refactoring
[mono.git] / mcs / class / System.Drawing / System.Drawing / ImageAnimator.cs
index b5710902f186a6be134d4f52000c229ffe1a77f4..201e39e53de5be758608e831fcdb49a27bd9bd1e 100644 (file)
@@ -7,16 +7,91 @@
 //
 // (C) 2002 Ximian, Inc
 //
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
 using System;
 using System.Drawing.Imaging;
+using System.Threading;
+using System.Collections;
 
 namespace System.Drawing
 {
+       //AnimateEventArgs class
+       class AnimateEventArgs : EventArgs \r
+       {  \r
+               private int frameCount;\r
+               private int activeFrameCount = 0;\r
+               private Thread thread;\r
+      \r
+               //Constructor.\r
+               //\r
+               public AnimateEventArgs(Image img)\r
+               {\r
+                       Guid[] dimensionList = img.FrameDimensionsList;
+                       int length = dimensionList.Length;
+                       for (int i=0; i<length; i++) {
+                               if (dimensionList [i].Equals(FrameDimension.Time.Guid))\r
+                                       this.frameCount = img.GetFrameCount (FrameDimension.Time);
+                       }                       \r
+               }\r
+      \r
+               public int FrameCount {     \r
+                       get { \r
+                               return frameCount;\r
+                       }      \r
+               }\r
+      \r
+               public int ActiveFrameCount {\r
+                       get {\r
+                               return activeFrameCount;\r
+                       }\r
+\r
+                       set {\r
+                               activeFrameCount = value;\r
+                       }\r
+               }\r
+\r
+               public Thread RunThread{\r
+                       get {\r
+                               return thread;\r
+                       }\r
+\r
+                       set {\r
+                               thread = value;\r
+                       }\r
+               }\r
+       }\r
+
        /// <summary>
        /// Summary description for ImageAnimator.
        /// </summary>
+       /// 
+       [MonoTODO]
        public sealed class ImageAnimator
        {
+               static Hashtable ht = new Hashtable (); 
+               
                private ImageAnimator ()
                {
                        //
@@ -24,10 +99,22 @@ namespace System.Drawing
                        //
                }
 
-               [MonoTODO ("Implement")]
                public static void Animate (Image img, EventHandler onFrameChangeHandler)
                {
-                       throw new NotImplementedException (); 
+                       if (img == null)
+                               throw new System.NullReferenceException ("Object reference not set to an instance of an object.");
+                       
+                       if (!ht.ContainsKey (img)) {
+                               AnimateEventArgs evtArgs = new AnimateEventArgs (img);
+                               WorkerThread WT = new WorkerThread(onFrameChangeHandler, evtArgs);
+                               ThreadStart TS = new ThreadStart(WT.LoopHandler);       
+                               Thread thread = new Thread(TS);
+                               thread.IsBackground = true;
+                               evtArgs.RunThread = thread;
+                               ht.Add (img, evtArgs);
+                               
+                               thread.Start();                         
+                       }
                }
 
                public static bool CanAnimate (Image img)
@@ -44,33 +131,88 @@ namespace System.Drawing
                        //with parameter FrameDimension.Time
                        Guid[] dimensionList = img.FrameDimensionsList;
                        int length = dimensionList.Length;
-                       for (int i=0; i<length; i++){
-                               if (dimensionList [i].Equals(FrameDimension.Time.Guid)){
-                                       int frameCount = img.GetFrameCount (FrameDimension.Time);
+                       int frameCount;
+                       for (int i=0; i<length; i++) \r
+                       {
+                               if (dimensionList [i].Equals(FrameDimension.Time.Guid)) \r
+                               {
+                                       frameCount = img.GetFrameCount (FrameDimension.Time);
                                        if (frameCount > 1)
                                                return true;
                                }
                        }                       
 
-                       return false; 
+                       return false;           \r
                }
 
-               [MonoTODO ("Implement")]
                public static void StopAnimate (Image img, EventHandler onFrameChangeHandler)
                {
-                       throw new NotImplementedException (); 
+                       if (img == null)
+                               throw new System.NullReferenceException ("Object reference not set to an instance of an object.");                      
+
+                       if (ht.ContainsKey (img)) {
+                               AnimateEventArgs evtArgs = (AnimateEventArgs) ht [img];
+                               evtArgs.RunThread.Abort ();
+                               ht.Remove (img);
+                       }                               
                }
 
-               [MonoTODO ("Implement")]
                public static void UpdateFrames ()
                {
-                       throw new NotImplementedException (); 
+                       foreach (Image img in ht.Keys) {
+                               UpdateFrames (img);
+                       }
                }
                
-               [MonoTODO ("Implement")]
                public static void UpdateFrames (Image img)
                {
-                       throw new NotImplementedException (); 
-               }       
+                       if (img == null)
+                               throw new System.NullReferenceException ("Object reference not set to an instance of an object.");
+
+                       if (ht.ContainsKey (img)){
+                               //Need a way to get the delay during animation
+                               AnimateEventArgs evtArgs = (AnimateEventArgs) ht [img];
+                               if (evtArgs.ActiveFrameCount < evtArgs.FrameCount-1){
+                                       evtArgs.ActiveFrameCount ++;
+                                       img.SelectActiveFrame (FrameDimension.Time, evtArgs.ActiveFrameCount);
+                               } \r
+                               else
+                                       evtArgs.ActiveFrameCount = 0;
+                               ht [img] = evtArgs;
+                       }                       
+               }
        }
+
+       class WorkerThread
+       {
+               private EventHandler frameChangeHandler;
+               private AnimateEventArgs animateEventArgs;
+                               
+               public WorkerThread(EventHandler frmChgHandler, AnimateEventArgs aniEvtArgs)
+               {
+                       frameChangeHandler = frmChgHandler;
+                       animateEventArgs = aniEvtArgs;
+               }
+    
+               public void LoopHandler()
+               {
+                       try
+                       {
+                               while (true) {
+                                       //Need a way to get the delay during animation
+                                       Thread.Sleep (100);
+                                       frameChangeHandler (null, animateEventArgs);\r
+                               }                               
+                       }
+                       catch(ThreadAbortException)
+                       { 
+                               //lets not bother ourselves with tae
+                               //it will be thrown anyway
+                       }
+                       catch(Exception er)
+                       {
+                               throw er;
+                       }
+               }
+       }\r
 }