2 // System.Drawing.ImageAnimator.cs
5 // Dennis Hayes (dennish@Raytek.com)
6 // Sanjay Gupta (gsanjay@novell.com)
8 // (C) 2002 Ximian, Inc
9 // Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Drawing.Imaging;
32 using System.Threading;
33 using System.Collections;
35 namespace System.Drawing
37 //AnimateEventArgs class
38 class AnimateEventArgs : EventArgs
40 private int frameCount;
41 private int activeFrameCount = 0;
42 private Thread thread;
46 public AnimateEventArgs(Image img)
48 Guid[] dimensionList = img.FrameDimensionsList;
49 int length = dimensionList.Length;
50 for (int i=0; i<length; i++) {
51 if (dimensionList [i].Equals(FrameDimension.Time.Guid))
52 this.frameCount = img.GetFrameCount (FrameDimension.Time);
56 public int FrameCount {
62 public int ActiveFrameCount {
64 return activeFrameCount;
68 activeFrameCount = value;
72 public Thread RunThread{
84 /// Summary description for ImageAnimator.
88 public sealed class ImageAnimator
90 static Hashtable ht = new Hashtable ();
92 private ImageAnimator ()
95 // TODO: Add constructor logic here
99 public static void Animate (Image img, EventHandler onFrameChangeHandler)
102 throw new System.NullReferenceException ("Object reference not set to an instance of an object.");
104 if (!ht.ContainsKey (img)) {
105 AnimateEventArgs evtArgs = new AnimateEventArgs (img);
108 PropertyItem item = img.GetPropertyItem (0x5100); // FrameDelay in libgdiplus
109 // Time is in 1/100th of a second
110 delay = (item.Value [0] + item.Value [1] * 256) * 10;
115 WorkerThread WT = new WorkerThread (onFrameChangeHandler, evtArgs, delay);
116 ThreadStart TS = new ThreadStart(WT.LoopHandler);
117 Thread thread = new Thread(TS);
118 thread.IsBackground = true;
119 evtArgs.RunThread = thread;
120 ht.Add (img, evtArgs);
126 public static bool CanAnimate (Image img)
128 //An image can animate if it has multiple frame in
129 //time based FrameDimension else return false
130 //Doubt what if the image has multiple frame in page
131 //based FrameDimension
135 //Need to check whether i can do this without iterating
136 //within the FrameDimensionsList, ie just call GetFrameCount
137 //with parameter FrameDimension.Time
138 Guid[] dimensionList = img.FrameDimensionsList;
139 int length = dimensionList.Length;
141 for (int i=0; i<length; i++)
143 if (dimensionList [i].Equals(FrameDimension.Time.Guid))
145 frameCount = img.GetFrameCount (FrameDimension.Time);
154 public static void StopAnimate (Image img, EventHandler onFrameChangeHandler)
157 throw new System.NullReferenceException ("Object reference not set to an instance of an object.");
159 if (ht.ContainsKey (img)) {
160 AnimateEventArgs evtArgs = (AnimateEventArgs) ht [img];
161 evtArgs.RunThread.Abort ();
166 public static void UpdateFrames ()
168 foreach (Image img in ht.Keys) {
173 public static void UpdateFrames (Image img)
176 throw new System.NullReferenceException ("Object reference not set to an instance of an object.");
178 if (ht.ContainsKey (img)){
179 //Need a way to get the delay during animation
180 AnimateEventArgs evtArgs = (AnimateEventArgs) ht [img];
181 if (evtArgs.ActiveFrameCount < evtArgs.FrameCount-1){
182 evtArgs.ActiveFrameCount ++;
183 img.SelectActiveFrame (FrameDimension.Time, evtArgs.ActiveFrameCount);
186 evtArgs.ActiveFrameCount = 0;
194 EventHandler frameChangeHandler;
195 AnimateEventArgs animateEventArgs;
198 public WorkerThread (EventHandler frmChgHandler, AnimateEventArgs aniEvtArgs, int delay)
200 frameChangeHandler = frmChgHandler;
201 animateEventArgs = aniEvtArgs;
205 public void LoopHandler()
209 Thread.Sleep (delay);
210 frameChangeHandler (null, animateEventArgs);
212 } catch (ThreadAbortException) {
213 Thread.ResetAbort (); // we're going to finish anyway