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.listbox;
10 
11 import std.utf : toUTFz;
12 public import dguihub.core.controls.ownerdrawcontrol;
13 import dguihub.core.utils;
14 
15 class ListBox : OwnerDrawControl {
16    private static class StringItem {
17       private string _str;
18 
19       public this(string s) {
20          this._str = s;
21       }
22 
23       public override string toString() {
24          return this._str;
25       }
26    }
27 
28    public Event!(Control, EventArgs) itemChanged;
29 
30    private Collection!(Object) _items;
31    private Object _selectedItem;
32    private int _selectedIndex;
33 
34    public final int addItem(string s) {
35       return this.addItem(new StringItem(s));
36    }
37 
38    public final int addItem(Object obj) {
39       if (!this._items) {
40          this._items = new Collection!(Object)();
41       }
42 
43       this._items.add(obj);
44 
45       if (this.created) {
46          return this.createItem(obj);
47       }
48 
49       return this._items.length - 1;
50    }
51 
52    public final void removeItem(int idx) {
53       if (this.created) {
54          this.sendMessage(LB_DELETESTRING, idx, 0);
55       }
56 
57       this._items.removeAt(idx);
58    }
59 
60    @property public final int selectedIndex() {
61       if (this.created) {
62          return this.sendMessage(LB_GETCURSEL, 0, 0);
63       }
64 
65       return this._selectedIndex;
66    }
67 
68    @property public final void selectedIndex(int i) {
69       this._selectedIndex = i;
70 
71       if (this.created) {
72          this.sendMessage(LB_SETCURSEL, i, 0);
73       }
74    }
75 
76    @property public final Object selectedItem() {
77       int idx = this.selectedIndex;
78 
79       if (this._items) {
80          return this._items[idx];
81       }
82 
83       return null;
84    }
85 
86    @property public final string selectedString() {
87       Object obj = this.selectedItem;
88       return (obj ? obj.toString() : null);
89    }
90 
91    @property public final Object[] items() {
92       if (this._items) {
93          return this._items.get();
94       }
95 
96       return null;
97    }
98 
99    private int createItem(Object obj) {
100       return this.sendMessage(LB_ADDSTRING, 0, cast(LPARAM)toUTFz!(wchar*)(obj.toString()));
101    }
102 
103    protected void onItemChanged(EventArgs e) {
104       this.itemChanged(this, e);
105    }
106 
107    protected override void createControlParams(ref CreateControlParams ccp) {
108       /* LBN_SELCHANGE: This notification code is sent only by a list box that has the LBS_NOTIFY style (by MSDN) */
109       this.setStyle(LBS_NOINTEGRALHEIGHT | LBS_NOTIFY, true);
110       this.setExStyle(WS_EX_CLIENTEDGE, true);
111 
112       ccp.superclassName = WC_LISTBOX;
113       ccp.className = WC_DLISTBOX;
114       ccp.defaultBackColor = SystemColors.colorWindow;
115 
116       switch (this._drawMode) {
117       case OwnerDrawMode.fixed:
118          this.setStyle(LBS_OWNERDRAWFIXED, true);
119          break;
120 
121       case OwnerDrawMode.variable:
122          this.setStyle(LBS_OWNERDRAWVARIABLE, true);
123          break;
124 
125       default:
126          break;
127       }
128 
129       super.createControlParams(ccp);
130    }
131 
132    protected override void onReflectedMessage(ref Message m) {
133       if (m.msg == WM_COMMAND && HIWORD(m.wParam) == LBN_SELCHANGE) {
134          this._selectedIndex = this.sendMessage(LB_GETCURSEL, 0, 0);
135          this.onItemChanged(EventArgs.empty);
136       }
137 
138       super.onReflectedMessage(m);
139    }
140 
141    protected override void onHandleCreated(EventArgs e) {
142       if (this._items) {
143          foreach (Object obj; this._items) {
144             this.createItem(obj);
145          }
146       }
147 
148       super.onHandleCreated(e);
149    }
150 }