ImageList.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  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.
  19. //
  20. // Copyright (c) 2004 Novell, Inc.
  21. //
  22. // Authors:
  23. // Peter Bartok [email protected]
  24. //
  25. //
  26. // $Revision: 1.2 $
  27. // $Modtime: $
  28. // $Log: ImageList.cs,v $
  29. // Revision 1.2 2004/08/09 23:12:13 pbartok
  30. // - Fixed several bugs Ravindra pointed out
  31. //
  32. // Revision 1.1 2004/07/15 20:05:28 pbartok
  33. // - Implemented ImageList and ImageList.ImageCollection classes
  34. // - Added ColorDepth enumeration
  35. // - Updated SWF VS.Net project
  36. //
  37. //
  38. // COMPLETE
  39. using System.Collections;
  40. using System.ComponentModel;
  41. using System.Drawing;
  42. using System.Drawing.Imaging;
  43. namespace System.Windows.Forms {
  44. public sealed class ImageList : System.ComponentModel.Component {
  45. #region Local Variables
  46. private ColorDepth color_depth;
  47. private ImageCollection image_collection;
  48. private Size size;
  49. private Color transparency_color;
  50. private Delegate handler;
  51. private ImageListStreamer image_stream;
  52. #endregion // Local Variables
  53. #region Sub-classes
  54. public sealed class ImageCollection : IList, ICollection, IEnumerable {
  55. #region ImageCollection Local Variables
  56. private ImageList owner;
  57. private ArrayList list;
  58. #endregion // ImageCollection Local Variables
  59. #region ImageCollection Private Constructors
  60. internal ImageCollection(ImageList owner) {
  61. this.owner=owner;
  62. }
  63. #endregion // ImageCollection Private Constructor
  64. #region ImageCollection Public Instance Properties
  65. public int Count {
  66. get {
  67. return list.Count;
  68. }
  69. }
  70. public bool Empty {
  71. get {
  72. return list.Count==0;
  73. }
  74. }
  75. public bool IsReadOnly {
  76. get {
  77. return list.IsReadOnly;
  78. }
  79. }
  80. public Image this[int index] {
  81. get {
  82. if (index<0 || index>=list.Count) {
  83. throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
  84. }
  85. return (Image)list[index];
  86. }
  87. set {
  88. if (index<0 || index>=list.Count) {
  89. throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
  90. }
  91. if (value==null) {
  92. throw new ArgumentOutOfRangeException("value", value, "Image cannot be null");
  93. }
  94. list[index]=value;
  95. // What happens if the bitmap had a previous 'MakeTransparent' done to it?
  96. ((Bitmap)list[index]).MakeTransparent(owner.transparency_color);
  97. }
  98. }
  99. #endregion // ImageCollection Public Instance Properties
  100. #region ImageCollection Private Instance Methods
  101. private int AddInternal(Image image) {
  102. int width;
  103. int height;
  104. PixelFormat format;
  105. width=owner.ImageSize.Width;
  106. height=owner.ImageSize.Height;
  107. switch(owner.color_depth) {
  108. case ColorDepth.Depth4Bit: format=PixelFormat.Format4bppIndexed; break;
  109. case ColorDepth.Depth8Bit: format=PixelFormat.Format8bppIndexed; break;
  110. case ColorDepth.Depth16Bit: format=PixelFormat.Format16bppRgb555; break;
  111. case ColorDepth.Depth24Bit: format=PixelFormat.Format24bppRgb; break;
  112. case ColorDepth.Depth32Bit: format=PixelFormat.Format32bppRgb; break;
  113. default: format=PixelFormat.Format32bppRgb; break;
  114. }
  115. // Check if we can add straight or if we have to resize
  116. if (image.Width!=width || image.Height!=height || image.PixelFormat!=format) {
  117. Graphics g;
  118. Bitmap reformatted_image;
  119. reformatted_image = new Bitmap(width, height, format);
  120. g=Graphics.FromImage(reformatted_image);
  121. g.DrawImage(image, new Rectangle(0, 0, width, height), 0, 0, width, height, GraphicsUnit.Pixel);
  122. g.Dispose();
  123. return list.Add(reformatted_image);
  124. } else {
  125. return list.Add(image);
  126. }
  127. }
  128. internal void Dispose() {
  129. if (list!=null) {
  130. for (int i=0; i<list.Count; i++) {
  131. ((Image)list[i]).Dispose();
  132. }
  133. }
  134. }
  135. #endregion // ImageCollection Private Instance Methods
  136. #region ImageCollection Public Instance Methods
  137. public int Add(Image value, Color transparentColor) {
  138. if (value==null) {
  139. throw new ArgumentNullException("value", "Cannot add null image");
  140. }
  141. ((Bitmap)value).MakeTransparent(owner.transparency_color);
  142. return AddInternal(value);
  143. }
  144. public void Add(Icon value) {
  145. Image image;
  146. image = value.ToBitmap();
  147. if (value==null || image==null) {
  148. throw new ArgumentNullException("value", "Cannot add null icon");
  149. }
  150. ((Bitmap)image).MakeTransparent(owner.transparency_color);
  151. AddInternal(image);
  152. }
  153. public void Add(Image value) {
  154. if (value==null) {
  155. throw new ArgumentNullException("value", "Cannot add null image");
  156. }
  157. ((Bitmap)value).MakeTransparent(owner.transparency_color);
  158. AddInternal(value);
  159. }
  160. public int AddStrip(Image value) {
  161. int image_count;
  162. int width;
  163. int height;
  164. Bitmap image;
  165. Graphics g;
  166. if (value==null) {
  167. throw new ArgumentNullException("value", "Cannot add null images");
  168. }
  169. if ((value.Width % owner.ImageSize.Width) != 0) {
  170. throw new ArgumentException("Strip is not a multiple of the ImageList with", "value");
  171. }
  172. // MSDN: The number of images is inferred from the width. A strip is multiple images side-by-side
  173. width=owner.ImageSize.Width;
  174. height=owner.ImageSize.Height;
  175. image_count=value.Width/width;
  176. for (int i=0; i<image_count; i++) {
  177. image = new Bitmap(value, width, height);
  178. g = Graphics.FromImage(image);
  179. g.DrawImage(value, new Rectangle(0, 0, width, height), i*width, 0, width, height, GraphicsUnit.Pixel);
  180. AddInternal(image);
  181. g.Dispose();
  182. image.Dispose();
  183. }
  184. // FIXME - is this right? MSDN says to return the index, but we might have multiple...
  185. return image_count;
  186. }
  187. public void Clear() {
  188. list.Clear();
  189. }
  190. public bool Contains(Image image) {
  191. return list.Contains(image);
  192. }
  193. public IEnumerator GetEnumerator() {
  194. return list.GetEnumerator();
  195. }
  196. public int IndexOf(Image image) {
  197. return list.IndexOf(image);
  198. }
  199. public void Remove(Image image) {
  200. list.Remove(image);
  201. }
  202. public void RemoveAt(int index) {
  203. if (index<0 || index>=list.Count) {
  204. throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
  205. }
  206. list.RemoveAt(index);
  207. }
  208. #endregion // ImageCollection Public Instance Methods
  209. #region ImageCollection Interface Properties
  210. object IList.this[int index] {
  211. get {
  212. if (index<0 || index>=list.Count) {
  213. throw new ArgumentOutOfRangeException("index", index, "ImageCollection does not have that many images");
  214. }
  215. return this[index];
  216. }
  217. set {
  218. if (!(value is Bitmap)) {
  219. throw new ArgumentException("Object of type Image required", "value");
  220. }
  221. this[index]=(Image)value;
  222. }
  223. }
  224. bool IList.IsFixedSize {
  225. get {
  226. return false;
  227. }
  228. }
  229. bool IList.IsReadOnly {
  230. get {
  231. return list.IsReadOnly;
  232. }
  233. }
  234. bool ICollection.IsSynchronized {
  235. get {
  236. return list.IsSynchronized;
  237. }
  238. }
  239. object ICollection.SyncRoot {
  240. get {
  241. return list.SyncRoot;
  242. }
  243. }
  244. #endregion // ImageCollection Interface Properties
  245. #region ImageCollection Interface Methods
  246. int IList.Add(object value) {
  247. if (value == null) {
  248. throw new ArgumentNullException("value", "Cannot add null images");
  249. }
  250. if (!(value is Bitmap)) {
  251. throw new ArgumentException("Object of type Image required", "value");
  252. }
  253. return list.Add(value);
  254. }
  255. bool IList.Contains(object value) {
  256. if (!(value is Bitmap)) {
  257. throw new ArgumentException("Object of type Image required", "value");
  258. }
  259. return this.Contains((Image) value);
  260. }
  261. int IList.IndexOf(object value) {
  262. if (!(value is Bitmap)) {
  263. throw new ArgumentException("Object of type Image required", "value");
  264. }
  265. return this.IndexOf((Image) value);
  266. }
  267. void IList.Insert(int index, object value) {
  268. if (!(value is Bitmap)) {
  269. throw new ArgumentException("Object of type Image required", "value");
  270. }
  271. list.Insert(index, value);
  272. }
  273. void IList.Remove(object value) {
  274. if (!(value is Bitmap)) {
  275. throw new ArgumentException("Object of type Image required", "value");
  276. }
  277. list.Remove(value);
  278. }
  279. void ICollection.CopyTo(Array array, int index) {
  280. if (list.Count>0) {
  281. list.CopyTo(array, index);
  282. }
  283. }
  284. #endregion // ImageCollection Interface Methods
  285. }
  286. #endregion // Sub-classes
  287. #region Public Constructors
  288. public ImageList() {
  289. color_depth = ColorDepth.Depth8Bit;
  290. transparency_color = Color.Transparent;
  291. size = new Size(16, 16);
  292. image_collection = new ImageCollection(this);
  293. }
  294. #endregion // Public Constructors
  295. #region Public Instance Properties
  296. public ColorDepth ColorDepth {
  297. get {
  298. return this.color_depth;
  299. }
  300. set {
  301. this.color_depth=value;
  302. }
  303. }
  304. [MonoTODO("Determine if we support HBITMAP handles, this would involve XplatUI")]
  305. public IntPtr Handle {
  306. get {
  307. return IntPtr.Zero;
  308. }
  309. }
  310. [MonoTODO("Determine if we support HBITMAP handles, this would involve XplatUI")]
  311. public bool HandleCreated {
  312. get {
  313. return false;
  314. }
  315. }
  316. public ImageCollection Images {
  317. get {
  318. return this.image_collection;
  319. }
  320. }
  321. public Size ImageSize {
  322. get {
  323. return this.size;
  324. }
  325. set {
  326. if (value.Width<1 || value.Width>256 || value.Height<1 || value.Height>256) {
  327. throw new ArgumentException("ImageSize width and height must be between 1 and 255", "value");
  328. }
  329. this.size=value;
  330. }
  331. }
  332. public ImageListStreamer ImageStream {
  333. get {
  334. return image_stream;
  335. }
  336. set {
  337. image_stream = value;
  338. }
  339. }
  340. public Color TransparentColor {
  341. get {
  342. return this.transparency_color;
  343. }
  344. set {
  345. this.transparency_color=value;
  346. }
  347. }
  348. #endregion // Public Instance Properties
  349. #region Public Instance Methods
  350. public void Draw(Graphics g, Point pt, int index) {
  351. this.Draw(g, pt.X, pt.Y, this.size.Width, this.size.Height, index);
  352. }
  353. public void Draw(Graphics g, int x, int y, int width, int height, int index) {
  354. }
  355. public override string ToString() {
  356. return "ImageList Size "+this.size.Width.ToString()+"x"+this.size.Height.ToString()+", Depth "+this.color_depth.ToString()+", Transparency color "+this.transparency_color.ToString();
  357. }
  358. #endregion // Public Instance Methods
  359. #region Protected Instance Methods
  360. protected override void Dispose(bool disposing) {
  361. if (image_collection!=null) {
  362. image_collection.Dispose();
  363. }
  364. }
  365. #endregion // Protected Instance Methods
  366. }
  367. }