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 }