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