// 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. // // Copyright (c) 2004-2005 Novell, Inc. // // Authors: // Peter Bartok pbartok@novell.com // // COMPLETE using System.Collections; using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; namespace System.Windows.Forms { [DefaultProperty("Images")] [Designer("System.Windows.Forms.Design.ImageListDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")] [ToolboxItemFilter("System.Windows.Forms", ToolboxItemFilterType.Allow)] [TypeConverter("System.Windows.Forms.ImageListConverter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public sealed class ImageList : System.ComponentModel.Component { #region Local Variables private ColorDepth color_depth; private ImageCollection image_collection; private Size size; private Color transparency_color; private Delegate handler; private ImageListStreamer image_stream; #endregion // Local Variables #region Sub-classes [Editor("System.Windows.Forms.Design.ImageCollectionEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))] public sealed class ImageCollection : IList, ICollection, IEnumerable { #region ImageCollection Local Variables private ImageList owner; private ArrayList list; #endregion // ImageCollection Local Variables #region ImageCollection Private Constructors internal ImageCollection(ImageList owner) { this.owner=owner; this.list=new ArrayList(); } #endregion // ImageCollection Private Constructor #region ImageCollection Public Instance Properties [Browsable(false)] public int Count { get { return list.Count; } } public bool Empty { get { return list.Count==0; } } public bool IsReadOnly { get { return list.IsReadOnly; } } [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Image this[int index] { get { if (index<0 || index>=list.Count) { throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images"); } return (Image)list[index]; } set { if (index<0 || index>=list.Count) { throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images"); } if (value==null) { throw new ArgumentOutOfRangeException("value", value, "Image cannot be null"); } list[index]=value; // What happens if the bitmap had a previous 'MakeTransparent' done to it? ((Bitmap)list[index]).MakeTransparent(owner.transparency_color); } } #endregion // ImageCollection Public Instance Properties #region ImageCollection Private Instance Methods private int AddInternal(Image image) { int width; int height; PixelFormat format; width=owner.ImageSize.Width; height=owner.ImageSize.Height; switch(owner.color_depth) { case ColorDepth.Depth4Bit: format=PixelFormat.Format4bppIndexed; break; case ColorDepth.Depth8Bit: format=PixelFormat.Format8bppIndexed; break; case ColorDepth.Depth16Bit: format=PixelFormat.Format16bppRgb555; break; case ColorDepth.Depth24Bit: format=PixelFormat.Format24bppRgb; break; case ColorDepth.Depth32Bit: format=PixelFormat.Format32bppArgb; break; default: format=PixelFormat.Format32bppArgb; break; } // Check if we can add straight or if we have to resize if (image.Width!=width || image.Height!=height || image.PixelFormat!=format) { Graphics g; Bitmap reformatted_image; reformatted_image = new Bitmap(width, height, format); g=Graphics.FromImage(reformatted_image); g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel); g.Dispose(); return list.Add(reformatted_image); } else { return list.Add(image); } } internal void Dispose() { #if dontwantthis if (list!=null) { for (int i=0; i=list.Count) { throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images"); } list.RemoveAt(index); } #endregion // ImageCollection Public Instance Methods #region ImageCollection Interface Properties object IList.this[int index] { get { if (index<0 || index>=list.Count) { throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images"); } return this[index]; } set { if (!(value is Bitmap)) { throw new ArgumentException("Object of type Image required", "value"); } this[index]=(Image)value; } } bool IList.IsFixedSize { get { return false; } } bool IList.IsReadOnly { get { return list.IsReadOnly; } } bool ICollection.IsSynchronized { get { return list.IsSynchronized; } } object ICollection.SyncRoot { get { return list.SyncRoot; } } #endregion // ImageCollection Interface Properties #region ImageCollection Interface Methods int IList.Add(object value) { if (value == null) { throw new ArgumentNullException("value", "Cannot add null images"); } if (!(value is Bitmap)) { throw new ArgumentException("Object of type Image required", "value"); } return list.Add(value); } bool IList.Contains(object value) { if (!(value is Bitmap)) { throw new ArgumentException("Object of type Image required", "value"); } return this.Contains((Image) value); } int IList.IndexOf(object value) { if (!(value is Bitmap)) { throw new ArgumentException("Object of type Image required", "value"); } return this.IndexOf((Image) value); } void IList.Insert(int index, object value) { if (!(value is Bitmap)) { throw new ArgumentException("Object of type Image required", "value"); } list.Insert(index, value); } void IList.Remove(object value) { if (!(value is Bitmap)) { throw new ArgumentException("Object of type Image required", "value"); } list.Remove(value); } void ICollection.CopyTo(Array array, int index) { if (list.Count>0) { list.CopyTo(array, index); } } #endregion // ImageCollection Interface Methods } #endregion // Sub-classes #region Public Constructors public ImageList() { color_depth = ColorDepth.Depth8Bit; transparency_color = Color.Transparent; size = new Size(16, 16); image_collection = new ImageCollection(this); } public ImageList(System.ComponentModel.IContainer container) : this () { color_depth = ColorDepth.Depth8Bit; transparency_color = Color.Transparent; size = new Size(16, 16); container.Add (this); } #endregion // Public Constructors #region Public Instance Properties [DefaultValue(ColorDepth.Depth8Bit)] public ColorDepth ColorDepth { get { return this.color_depth; } set { this.color_depth=value; } } [MonoTODO("Determine if we support HBITMAP handles, this would involve XplatUI")] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Advanced)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public IntPtr Handle { get { if (RecreateHandle!=null) RecreateHandle(this, EventArgs.Empty); return IntPtr.Zero; } } [MonoTODO("Determine if we support HBITMAP handles, this would involve XplatUI")] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Advanced)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool HandleCreated { get { return false; } } [DefaultValue(null)] [MergableProperty(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ImageCollection Images { get { return this.image_collection; } } [Localizable(true)] public Size ImageSize { get { return this.size; } set { if (value.Width<1 || value.Width>256 || value.Height<1 || value.Height>256) { throw new ArgumentException("ImageSize width and height must be between 1 and 255", "value"); } this.size=value; } } [Browsable(false)] [DefaultValue(null)] [EditorBrowsable(EditorBrowsableState.Advanced)] public ImageListStreamer ImageStream { get { return image_stream; } set { image_stream = value; size = image_stream.ImageSize; color_depth = image_stream.ImageColorDepth; transparency_color = image_stream.BackColor; image_collection.Clear (); foreach (Image image in image_stream.Images) image_collection.Add (image); } } public Color TransparentColor { get { return this.transparency_color; } set { this.transparency_color=value; } } #endregion // Public Instance Properties #region Public Instance Methods public void Draw(Graphics g, Point pt, int index) { this.Draw(g, pt.X, pt.Y, index); } public void Draw(Graphics g, int x, int y, int index) { this.Draw(g, x, y, this.size.Width, this.size.Height, index); } public void Draw(Graphics g, int x, int y, int width, int height, int index) { Image i; if ((index < 0) || (index >= this.Images.Count)) { throw new ArgumentOutOfRangeException("index", index, "ImageList does not contain that many images"); } i = this.Images[index]; g.DrawImage(i, x, y, width, height); } public override string ToString() { return "ImageList Size "+this.size.Width.ToString()+"x"+this.size.Height.ToString()+", Depth "+this.color_depth.ToString()+", Transparency color "+this.transparency_color.ToString(); } #endregion // Public Instance Methods #region Protected Instance Methods protected override void Dispose(bool disposing) { if (image_collection!=null) { image_collection.Dispose(); } } #endregion // Protected Instance Methods #region Events [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Advanced)] public event EventHandler RecreateHandle; #endregion // Events } }