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 }