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