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