1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2005 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
26 // If we ever need to support the Handle property, we should create a static ArrayList,
27 // and store the ImageList object in it, and return the index as handle
28 // That way, once we try to support P/Invokes, we can make the handle back to the object
33 using System.Collections;
34 using System.ComponentModel;
36 using System.Drawing.Imaging;
38 namespace System.Windows.Forms {
39 [DefaultProperty("Images")]
40 [Designer("System.Windows.Forms.Design.ImageListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
41 [ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow)]
42 [TypeConverter("System.Windows.Forms.ImageListConverter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
43 public sealed class ImageList : System.ComponentModel.Component {
44 #region Local Variables
45 private ColorDepth color_depth;
46 private ImageCollection image_collection;
48 private Color transparency_color;
49 private Delegate handler;
50 private ImageListStreamer image_stream;
51 private IntPtr handle;
52 #endregion // Local Variables
55 [Editor("System.Windows.Forms.Design.ImageCollectionEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
56 public sealed class ImageCollection : IList, ICollection, IEnumerable {
57 #region ImageCollection Local Variables
58 private ImageList owner;
59 private ArrayList list;
60 #endregion // ImageCollection Local Variables
62 #region ImageCollection Private Constructors
63 internal ImageCollection(ImageList owner) {
65 this.list=new ArrayList();
67 #endregion // ImageCollection Private Constructor
69 #region ImageCollection Public Instance Properties
83 public bool IsReadOnly {
85 return list.IsReadOnly;
90 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
91 public Image this[int index] {
93 if (index<0 || index>=list.Count) {
94 throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
96 return (Image)list[index];
100 if (index<0 || index>=list.Count) {
101 throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
105 throw new ArgumentOutOfRangeException("value", value, "Image cannot be null");
109 // What happens if the bitmap had a previous 'MakeTransparent' done to it?
110 ((Bitmap)list[index]).MakeTransparent(owner.transparency_color);
113 #endregion // ImageCollection Public Instance Properties
115 #region ImageCollection Private Instance Methods
116 private int AddInternal(Image image) {
121 width=owner.ImageSize.Width;
122 height=owner.ImageSize.Height;
123 switch(owner.color_depth) {
124 case ColorDepth.Depth4Bit: format=PixelFormat.Format4bppIndexed; break;
125 case ColorDepth.Depth8Bit: format=PixelFormat.Format8bppIndexed; break;
126 case ColorDepth.Depth16Bit: format=PixelFormat.Format16bppRgb555; break;
127 case ColorDepth.Depth24Bit: format=PixelFormat.Format24bppRgb; break;
128 case ColorDepth.Depth32Bit: format=PixelFormat.Format32bppArgb; break;
129 default: format=PixelFormat.Format32bppArgb; break;
132 // Check if we can add straight or if we have to resize
133 if (image.Width!=width || image.Height!=height || image.PixelFormat!=format) {
135 Bitmap reformatted_image;
137 reformatted_image = new Bitmap(width, height, format);
138 g=Graphics.FromImage(reformatted_image);
140 g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
143 return list.Add(reformatted_image);
145 return list.Add(image);
149 internal void Dispose() {
152 for (int i=0; i<list.Count; i++) {
153 ((Image)list[i]).Dispose();
158 #endregion // ImageCollection Private Instance Methods
160 #region ImageCollection Public Instance Methods
161 public int Add(Image value, Color transparentColor) {
163 throw new ArgumentNullException("value", "Cannot add null image");
166 ((Bitmap)value).MakeTransparent(owner.transparency_color);
167 return AddInternal(value);
171 public void Add(Icon value) {
174 image = value.ToBitmap();
176 if (value==null || image==null) {
177 throw new ArgumentNullException("value", "Cannot add null icon");
180 ((Bitmap)image).MakeTransparent(owner.transparency_color);
184 public void Add(Image value) {
186 throw new ArgumentNullException("value", "Cannot add null image");
188 ((Bitmap)value).MakeTransparent(owner.transparency_color);
192 public int AddStrip(Image value) {
200 throw new ArgumentNullException("value", "Cannot add null images");
203 if ((value.Width % owner.ImageSize.Width) != 0) {
204 throw new ArgumentException("Strip is not a multiple of the ImageList with", "value");
207 // MSDN: The number of images is inferred from the width. A strip is multiple images side-by-side
208 width=owner.ImageSize.Width;
209 height=owner.ImageSize.Height;
210 image_count=value.Width/width;
211 for (int i=0; i<image_count; i++) {
212 image = new Bitmap(value, width, height);
213 g = Graphics.FromImage(image);
215 g.DrawImage(value, new Rectangle(0, 0, width, height), i*width, 0, width, height, GraphicsUnit.Pixel);
222 // FIXME - is this right? MSDN says to return the index, but we might have multiple...
226 public void Clear() {
230 public bool Contains(Image image) {
231 return list.Contains(image);
234 public IEnumerator GetEnumerator() {
235 return list.GetEnumerator();
238 public int IndexOf(Image image) {
239 return list.IndexOf(image);
242 public void Remove(Image image) {
246 public void RemoveAt(int index) {
247 if (index<0 || index>=list.Count) {
248 throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
251 list.RemoveAt(index);
253 #endregion // ImageCollection Public Instance Methods
255 #region ImageCollection Interface Properties
256 object IList.this[int index] {
258 if (index<0 || index>=list.Count) {
259 throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
265 if (!(value is Bitmap)) {
266 throw new ArgumentException("Object of type Image required", "value");
269 this[index]=(Image)value;
273 bool IList.IsFixedSize {
279 bool IList.IsReadOnly {
281 return list.IsReadOnly;
285 bool ICollection.IsSynchronized {
287 return list.IsSynchronized;
291 object ICollection.SyncRoot {
293 return list.SyncRoot;
296 #endregion // ImageCollection Interface Properties
298 #region ImageCollection Interface Methods
299 int IList.Add(object value) {
301 throw new ArgumentNullException("value", "Cannot add null images");
304 if (!(value is Bitmap)) {
305 throw new ArgumentException("Object of type Image required", "value");
308 return list.Add(value);
311 bool IList.Contains(object value) {
312 if (!(value is Bitmap)) {
313 throw new ArgumentException("Object of type Image required", "value");
316 return this.Contains((Image) value);
319 int IList.IndexOf(object value) {
320 if (!(value is Bitmap)) {
321 throw new ArgumentException("Object of type Image required", "value");
324 return this.IndexOf((Image) value);
327 void IList.Insert(int index, object value) {
328 if (!(value is Bitmap)) {
329 throw new ArgumentException("Object of type Image required", "value");
331 list.Insert(index, value);
334 void IList.Remove(object value) {
335 if (!(value is Bitmap)) {
336 throw new ArgumentException("Object of type Image required", "value");
341 void ICollection.CopyTo(Array array, int index) {
343 list.CopyTo(array, index);
346 #endregion // ImageCollection Interface Methods
348 #endregion // Sub-classes
350 #region Public Constructors
352 color_depth = ColorDepth.Depth8Bit;
353 transparency_color = Color.Transparent;
354 size = new Size(16, 16);
355 image_collection = new ImageCollection(this);
356 handle = IntPtr.Zero;
359 public ImageList(System.ComponentModel.IContainer container) : this ()
361 color_depth = ColorDepth.Depth8Bit;
362 transparency_color = Color.Transparent;
363 size = new Size(16, 16);
364 container.Add (this);
366 #endregion // Public Constructors
368 #region Public Instance Properties
369 [DefaultValue(ColorDepth.Depth8Bit)]
370 public ColorDepth ColorDepth {
372 return this.color_depth;
376 this.color_depth=value;
381 [EditorBrowsable(EditorBrowsableState.Advanced)]
382 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
383 public IntPtr Handle {
385 if (RecreateHandle!=null) RecreateHandle(this, EventArgs.Empty);
386 handle = new IntPtr(1);
392 [EditorBrowsable(EditorBrowsableState.Advanced)]
393 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
394 public bool HandleCreated {
396 if (handle != IntPtr.Zero) {
404 [MergableProperty(false)]
405 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
406 public ImageCollection Images {
408 return this.image_collection;
413 public Size ImageSize {
419 if (value.Width<1 || value.Width>256 || value.Height<1 || value.Height>256) {
420 throw new ArgumentException("ImageSize width and height must be between 1 and 255", "value");
428 [EditorBrowsable(EditorBrowsableState.Advanced)]
429 public ImageListStreamer ImageStream {
435 image_stream = value;
437 size = image_stream.ImageSize;
438 color_depth = image_stream.ImageColorDepth;
439 transparency_color = image_stream.BackColor;
441 image_collection.Clear ();
443 foreach (Image image in image_stream.Images)
444 image_collection.Add (image);
448 public Color TransparentColor {
450 return this.transparency_color;
454 this.transparency_color=value;
457 #endregion // Public Instance Properties
459 #region Public Instance Methods
460 public void Draw(Graphics g, Point pt, int index) {
461 this.Draw(g, pt.X, pt.Y, index);
464 public void Draw(Graphics g, int x, int y, int index) {
465 this.Draw(g, x, y, this.size.Width, this.size.Height, index);
468 public void Draw(Graphics g, int x, int y, int width, int height, int index) {
471 if ((index < 0) || (index >= this.Images.Count)) {
472 throw new ArgumentOutOfRangeException("index", index, "ImageList does not contain that many images");
474 i = this.Images[index];
475 g.DrawImage(i, x, y, width, height);
478 public override string ToString() {
\r
479 return "ImageList Size "+this.size.Width.ToString()+"x"+this.size.Height.ToString()+", Depth "+this.color_depth.ToString()+", Transparency color "+this.transparency_color.ToString();
\r
481 #endregion // Public Instance Methods
483 #region Protected Instance Methods
484 protected override void Dispose(bool disposing) {
\r
485 if (image_collection!=null) {
\r
486 image_collection.Dispose();
\r
490 #endregion // Protected Instance Methods
494 [EditorBrowsable(EditorBrowsableState.Advanced)]
495 public event EventHandler RecreateHandle;