1 /** DGui project file.
2 
3 Copyright: Trogu Antonio Davide 2011-2013
4 
5 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 
7 Authors: Trogu Antonio Davide
8 */
9 module dgui.imagelist;
10 
11 import dgui.core.interfaces.idisposable;
12 import dgui.core.collection;
13 import dgui.core.charset;
14 import dgui.core.winapi;
15 import dgui.core.handle;
16 import dgui.canvas;
17 
18 enum ColorDepth: uint
19 {
20 	depth4bit = ILC_COLOR4,
21 	depth8bit = ILC_COLOR8,
22 	depth16bit = ILC_COLOR16,
23 	depth24bit = ILC_COLOR24,
24 	depth32bit = ILC_COLOR32,
25 }
26 
27 /*
28  * Dynamic Binding (Uses The Latest Version Available)
29  */
30 
31 private alias extern(Windows) HIMAGELIST function(int, int, uint, int, int) ImageList_CreateProc;
32 private alias extern(Windows) HIMAGELIST function(HIMAGELIST) ImageList_DestroyProc;
33 private alias extern(Windows) BOOL function(HIMAGELIST, int) ImageList_RemoveProc;
34 private alias extern(Windows) int function(HIMAGELIST, HICON) ImageList_AddIconProc;
35 private alias extern(Windows) int function(HIMAGELIST, int, HDC, int, int, UINT) ImageList_DrawProc;
36 private alias extern(Windows) int function(HIMAGELIST, COLORREF) ImageList_SetBkColorProc;
37 
38 class ImageList: Handle!(HIMAGELIST), IDisposable
39 {
40 	private static ImageList_CreateProc imageList_Create;
41 	private static ImageList_RemoveProc imageList_Remove;
42 	private static ImageList_AddIconProc imageList_AddIcon;
43 	private static ImageList_DestroyProc imageList_Destroy;
44 	private static ImageList_DrawProc imageList_Draw;
45 	private static ImageList_SetBkColorProc imageList_SetBkColor;
46 
47 	private ColorDepth _depth = ColorDepth.depth32bit;
48 	private Size _size;
49 	private Collection!(Icon) _images;
50 
51 	public this()
52 	{
53 		if(!imageList_Create)
54 		{
55 			HMODULE hModule = getModuleHandle("comctl32.dll");
56 
57 			/*
58 			  * Static Library Issue: Use Dynamic Binding so Visual Styles are enabled (if supported)
59 			  */
60 
61 			imageList_Create = cast(ImageList_CreateProc)GetProcAddress(hModule, "ImageList_Create");
62 			imageList_Remove = cast(ImageList_RemoveProc)GetProcAddress(hModule, "ImageList_Remove");
63 			imageList_AddIcon = cast(ImageList_AddIconProc)GetProcAddress(hModule, "ImageList_AddIcon");
64 			imageList_Destroy = cast(ImageList_DestroyProc)GetProcAddress(hModule, "ImageList_Destroy");
65 			imageList_Draw = cast(ImageList_DrawProc)GetProcAddress(hModule, "ImageList_Draw");
66 			imageList_SetBkColor = cast(ImageList_SetBkColorProc)GetProcAddress(hModule, "ImageList_SetBkColor");
67 		}
68 	}
69 
70 	public ~this()
71 	{
72 		if(this.created)
73 		{
74 			this.dispose();
75 		}
76 	}
77 
78 	public void dispose()
79 	{
80 		foreach(Icon i; this._images)
81 		{
82 			i.dispose(); //Dispose Icons before delete the ImageList.
83 		}
84 
85 		imageList_Destroy(this._handle);
86 	}
87 
88 	@property public override HIMAGELIST handle()
89 	{
90 		if(!this.created)
91 		{
92 			if(this._size == nullSize)
93 			{
94 				this._size.width = 16;
95 				this._size.height = 16;
96 			}
97 
98 			this._handle = imageList_Create(this._size.width, this._size.height, this._depth | ILC_MASK, 0, 0);
99 			imageList_SetBkColor(this._handle, CLR_NONE);
100 		}
101 
102 		return super.handle;
103 	}
104 
105 	public final void drawIcon(int i, Canvas dest, Point pos)
106 	{
107 		imageList_Draw(this._handle, i, dest.handle, pos.x, pos.y, ILD_NORMAL);
108 	}
109 
110 	public final int addImage(Icon ico)
111 	{
112 		if(!this._images)
113 		{
114 			this._images = new Collection!(Icon)();
115 		}
116 
117 		this._images.add(ico);
118 
119 		if(!this.created)
120 		{
121 			if(this._size == nullSize)
122 			{
123 				this._size.width = 16;
124 				this._size.height = 16;
125 			}
126 
127 			this._handle = imageList_Create(this._size.width, this._size.height, this._depth | ILC_MASK, 0, 0);
128 			imageList_SetBkColor(this._handle, CLR_NONE);
129 		}
130 
131 		return imageList_AddIcon(this._handle, ico.handle);
132 	}
133 
134 	public final void removeImage(int index)
135 	{
136 		if(this._images)
137 		{
138 			this._images.removeAt(index);
139 		}
140 
141 		if(this.created)
142 		{
143 			imageList_Remove(this._handle, index);
144 		}
145 	}
146 
147 	public final void clear()
148 	{
149 		imageList_Remove(this._handle, -1);
150 	}
151 
152 	@property public final Icon[] images()
153 	{
154 		if(this._images)
155 		{
156 			return this._images.get();
157 		}
158 
159 		return null;
160 	}
161 
162 	@property public final Size size()
163 	{
164 		return this._size;
165 	}
166 
167 	@property public final void size(Size sz)
168 	{
169 		this._size = sz;
170 	}
171 
172 	@property public final ColorDepth colorDepth()
173 	{
174 		return this._depth;
175 	}
176 
177 	@property public final void colorDepth(ColorDepth depth)
178 	{
179 		this._depth = depth;
180 	}
181 }