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.core.controls.ownerdrawcontrol;
10 
11 public import dgui.core.controls.subclassedcontrol;
12 public import dgui.core.events.eventargs;
13 
14 enum OwnerDrawMode: ubyte
15 {
16 	normal = 0,
17 	fixed = 1,
18 	variable = 2,
19 }
20 
21 enum DrawItemState: uint
22 {
23 	default_  = ODS_DEFAULT,
24 	checked  = ODS_CHECKED,
25 	disabled = ODS_DISABLED,
26 	focused  = ODS_FOCUS,
27 	grayed   = ODS_GRAYED,
28 	selected = ODS_SELECTED,
29 }
30 
31 class MeasureItemEventArgs: EventArgs
32 {
33 	private int _width;
34 	private int _height;
35 	private int _index;
36 	private Canvas _canvas;
37 
38 
39 	public this(Canvas c, int width, int height, int index)
40 	{
41 		this._canvas = c;
42 		this._width = width;
43 		this._height = height;
44 		this._index = index;
45 	}
46 
47 	@property public Canvas canvas()
48 	{
49 		return this._canvas;
50 	}
51 
52 	@property public int width()
53 	{
54 		return this._width;
55 	}
56 
57 	@property public void width(int w)
58 	{
59 		this._width = w;
60 	}
61 
62 	@property public int height()
63 	{
64 		return this._height;
65 	}
66 
67 	@property public void height(int h)
68 	{
69 		this._height = h;
70 	}
71 
72 	@property public int index()
73 	{
74 		return this._index;
75 	}
76 }
77 
78 class DrawItemEventArgs: EventArgs
79 {
80 	private DrawItemState _state;
81 	private Color _foreColor;
82 	private Color _backColor;
83 	private Canvas _canvas;
84 	private Rect _itemRect;
85 	private int _index;
86 
87 	public this(Canvas c, DrawItemState state, Rect itemRect, Color foreColor, Color backColor, int index)
88 	{
89 		this._canvas = c;
90 		this._state = state;
91 		this._itemRect = itemRect;
92 		this._foreColor = foreColor;
93 		this._backColor = backColor;
94 		this._index = index;
95 	}
96 
97 	@property public Canvas canvas()
98 	{
99 		return this._canvas;
100 	}
101 
102 	@property public DrawItemState itemState()
103 	{
104 		return this._state;
105 	}
106 
107 	@property public Rect itemRect()
108 	{
109 		return this._itemRect;
110 	}
111 
112 	@property public Color foreColor()
113 	{
114 		return this._foreColor;
115 	}
116 
117 	@property public Color backColor()
118 	{
119 		return this._backColor;
120 	}
121 
122 	public void drawBackground()
123 	{
124 		scope SolidBrush brush = new SolidBrush(this._backColor);
125 		this._canvas.fillRectangle(brush, this._itemRect);
126 	}
127 
128 	public void drawFocusRect()
129 	{
130 		if(this._state & DrawItemState.focused)
131 		{
132 			DrawFocusRect(this._canvas.handle, &this._itemRect.rect);
133 		}
134 	}
135 
136 	@property public int index()
137 	{
138 		return this._index;
139 	}
140 }
141 
142 abstract class OwnerDrawControl: SubclassedControl
143 {
144 	public Event!(Control, MeasureItemEventArgs) measureItem;
145 	public Event!(Control, DrawItemEventArgs) drawItem;
146 
147 	protected OwnerDrawMode _drawMode = OwnerDrawMode.normal;
148 
149 	@property public OwnerDrawMode drawMode()
150 	{
151 		return this._drawMode;
152 	}
153 
154 	@property public void drawMode(OwnerDrawMode dm)
155 	{
156 		this._drawMode = dm;
157 	}
158 
159 	protected void onMeasureItem(MeasureItemEventArgs e)
160 	{
161 		this.measureItem(this, e);
162 	}
163 
164 	protected void onDrawItem(DrawItemEventArgs e)
165 	{
166 		this.drawItem(this, e);
167 	}
168 
169 	protected override void onReflectedMessage(ref Message m)
170 	{
171 		switch(m.msg)
172 		{
173 			case WM_MEASUREITEM:
174 			{
175 				MEASUREITEMSTRUCT* pMeasureItem = cast(MEASUREITEMSTRUCT*)m.lParam;
176 				HDC hdc = GetDC(this._handle);
177 				SetBkColor(hdc, this.backColor.colorref);
178 				SetTextColor(hdc, this.foreColor.colorref);
179 
180 				scope Canvas c = Canvas.fromHDC(hdc);
181 				scope MeasureItemEventArgs e = new MeasureItemEventArgs(c, pMeasureItem.itemWidth, pMeasureItem.itemHeight,
182 																		   pMeasureItem.itemID);
183 
184 				this.onMeasureItem(e);
185 
186 				if(e.width)
187 				{
188 					pMeasureItem.itemWidth = e.width;
189 				}
190 
191 				if(e.height)
192 				{
193 					pMeasureItem.itemHeight = e.height;
194 				}
195 
196 				ReleaseDC(this._handle, null);
197 			}
198 			break;
199 
200 			case WM_DRAWITEM:
201 			{
202 				DRAWITEMSTRUCT* pDrawItem = cast(DRAWITEMSTRUCT*)m.lParam;
203 				Rect r = Rect.fromRECT(&pDrawItem.rcItem);
204 
205 				Color fc, bc;
206 
207 				if(pDrawItem.itemState & ODS_SELECTED)
208 				{
209 					fc = SystemColors.colorHighlightText;
210 					bc = SystemColors.colorHighlight;
211 				}
212 				else
213 				{
214 					fc = this.foreColor;
215 					bc = this.backColor;
216 				}
217 
218 				scope Canvas c = Canvas.fromHDC(pDrawItem.hDC);
219 				scope DrawItemEventArgs e = new DrawItemEventArgs(c, cast(DrawItemState)pDrawItem.itemState,
220 																  r, fc, bc, pDrawItem.itemID);
221 
222 				this.onDrawItem(e);
223 			}
224 			break;
225 
226 			default:
227 				break;
228 		}
229 
230 		super.onReflectedMessage(m);
231 	}
232 }