Mercurial > projects > dynamin
annotate dynamin/gui/windows_theme.d @ 55:c138461bf845
Add focusing and other changes that are related
like descendantAdded/Removed events, Window.activated event, and updating List.
Window.state was also added, even though focusing does not depend on it.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Sat, 08 Aug 2009 15:42:27 -0500 |
parents | d82c7e5b037b |
children | 60832e1eef04 |
rev | line source |
---|---|
0 | 1 // Written in the D programming language |
2 // www.digitalmars.com/d/ | |
3 | |
4 /* | |
5 * The contents of this file are subject to the Mozilla Public License Version | |
6 * 1.1 (the "License"); you may not use this file except in compliance with | |
7 * the License. You may obtain a copy of the License at | |
8 * http://www.mozilla.org/MPL/ | |
9 * | |
10 * Software distributed under the License is distributed on an "AS IS" basis, | |
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
12 * for the specific language governing rights and limitations under the | |
13 * License. | |
14 * | |
15 * The Original Code is the Dynamin library. | |
16 * | |
17 * The Initial Developer of the Original Code is Jordan Miner. | |
18 * Portions created by the Initial Developer are Copyright (C) 2007-2009 | |
19 * the Initial Developer. All Rights Reserved. | |
20 * | |
21 * Contributor(s): | |
22 * Jordan Miner <jminer7@gmail.com> | |
23 * | |
24 */ | |
25 | |
26 module dynamin.gui.windows_theme; | |
27 | |
28 import dynamin.core.string; | |
29 import dynamin.all_painting; | |
30 import dynamin.all_gui; | |
31 import tango.io.Stdout; | |
32 import Utf = tango.text.convert.Utf; | |
33 version(Windows) import dynamin.c.windows; | |
34 version(Windows) import dynamin.c.windows_tmschema; | |
35 import dynamin.gui_backend; | |
36 | |
37 version(Windows) { | |
38 } else { | |
39 enum { | |
40 COLOR_SCROLLBAR = 0, | |
41 COLOR_BACKGROUND = 1, | |
42 COLOR_ACTIVECAPTION = 2, | |
43 COLOR_INACTIVECAPTION = 3, | |
44 COLOR_MENU = 4, | |
45 COLOR_WINDOW = 5, | |
46 COLOR_WINDOWFRAME = 6, | |
47 COLOR_MENUTEXT = 7, | |
48 COLOR_WINDOWTEXT = 8, | |
49 COLOR_CAPTIONTEXT = 9, | |
50 COLOR_ACTIVEBORDER = 10, | |
51 COLOR_INACTIVEBORDER = 11, | |
52 COLOR_APPWORKSPACE = 12, | |
53 COLOR_HIGHLIGHT = 13, | |
54 COLOR_HIGHLIGHTTEXT = 14, | |
55 COLOR_BTNFACE = 15, | |
56 COLOR_BTNSHADOW = 16, | |
57 COLOR_GRAYTEXT = 17, | |
58 COLOR_BTNTEXT = 18, | |
59 COLOR_INACTIVECAPTIONTEXT = 19, | |
60 COLOR_BTNHIGHLIGHT = 20, | |
61 | |
62 COLOR_3DDKSHADOW = 21, | |
63 COLOR_3DLIGHT = 22, | |
64 COLOR_INFOTEXT = 23, | |
65 COLOR_INFOBK = 24, | |
66 | |
67 COLOR_HOTLIGHT = 26, | |
68 COLOR_GRADIENTACTIVECAPTION = 27, | |
69 COLOR_GRADIENTINACTIVECAPTION = 28, | |
70 COLOR_MENUHILIGHT = 29, | |
71 COLOR_MENUBAR = 30, | |
72 | |
73 COLOR_DESKTOP = COLOR_BACKGROUND, | |
74 COLOR_3DFACE = COLOR_BTNFACE, | |
75 COLOR_3DSHADOW = COLOR_BTNSHADOW, | |
76 COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT, | |
77 COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT, | |
78 COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT | |
79 } | |
80 } | |
81 | |
82 /** | |
83 * This file/module, even though it starts with 'windows_', is not part | |
84 * of the windows backend. It is a theme that should run on any system, | |
85 * but can only show visual styles under Windows because the | |
86 * Windows API is needed. | |
87 */ | |
88 | |
89 static this() { | |
90 Theme.add(new WindowsTheme()); | |
91 } | |
92 | |
93 /** | |
94 * This theme should work with any backend, but can only paint the Windows | |
95 * classic look if not on Windows XP, Vista, or newer. | |
96 */ | |
97 class WindowsTheme : Theme { | |
98 version(Windows) { | |
99 static string defaultFont() { // TODO: rename | |
100 NONCLIENTMETRICS ncMetrics; | |
101 ncMetrics.cbSize = NONCLIENTMETRICS.sizeof; | |
102 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, | |
103 NONCLIENTMETRICS.sizeof, &ncMetrics, 0); | |
104 // TODO: need to strip the nulls off the name | |
105 return Utf.toString(ncMetrics.lfMessageFont.lfFaceName); | |
106 } | |
107 } | |
108 version(Windows) { | |
109 static void printSysColors() { | |
110 int[string] colors = [ | |
111 "COLOR_SCROLLBAR"[] : COLOR_SCROLLBAR, | |
112 "COLOR_BACKGROUND" : COLOR_BACKGROUND, | |
113 "COLOR_ACTIVECAPTION" : COLOR_ACTIVECAPTION, | |
114 "COLOR_INACTIVECAPTION" : COLOR_INACTIVECAPTION, | |
115 "COLOR_MENU" : COLOR_MENU, | |
116 "COLOR_WINDOW" : COLOR_WINDOW, | |
117 "COLOR_WINDOWFRAME" : COLOR_WINDOWFRAME, | |
118 "COLOR_MENUTEXT" : COLOR_MENUTEXT, | |
119 "COLOR_WINDOWTEXT" : COLOR_WINDOWTEXT, | |
120 "COLOR_CAPTIONTEXT" : COLOR_CAPTIONTEXT, | |
121 "COLOR_ACTIVEBORDER" : COLOR_ACTIVEBORDER, | |
122 "COLOR_INACTIVEBORDER" : COLOR_INACTIVEBORDER, | |
123 "COLOR_APPWORKSPACE" : COLOR_APPWORKSPACE, | |
124 "COLOR_HIGHLIGHT" : COLOR_HIGHLIGHT, | |
125 "COLOR_HIGHLIGHTTEXT" : COLOR_HIGHLIGHTTEXT, | |
126 "COLOR_BTNFACE" : COLOR_BTNFACE, | |
127 "COLOR_BTNSHADOW" : COLOR_BTNSHADOW, | |
128 "COLOR_GRAYTEXT" : COLOR_GRAYTEXT, | |
129 "COLOR_BTNTEXT" : COLOR_BTNTEXT, | |
130 "COLOR_INACTIVECAPTIONTEXT" : COLOR_INACTIVECAPTIONTEXT, | |
131 "COLOR_BTNHIGHLIGHT" : COLOR_BTNHIGHLIGHT, | |
132 "COLOR_3DDKSHADOW" : COLOR_3DDKSHADOW, | |
133 "COLOR_3DLIGHT" : COLOR_3DLIGHT, | |
134 "COLOR_INFOTEXT" : COLOR_INFOTEXT, | |
135 "COLOR_INFOBK" : COLOR_INFOBK, | |
136 "COLOR_HOTLIGHT" : COLOR_HOTLIGHT, | |
137 "COLOR_GRADIENTACTIVECAPTION" : COLOR_GRADIENTACTIVECAPTION, | |
138 "COLOR_GRADIENTINACTIVECAPTION" : COLOR_GRADIENTINACTIVECAPTION, | |
139 "COLOR_MENUHILIGHT" : COLOR_MENUHILIGHT, | |
140 "COLOR_MENUBAR" : COLOR_MENUBAR, | |
141 | |
142 "COLOR_DESKTOP" : COLOR_DESKTOP, | |
143 "COLOR_3DFACE" : COLOR_3DFACE, | |
144 "COLOR_3DSHADOW" : COLOR_3DSHADOW, | |
145 "COLOR_3DHIGHLIGHT" : COLOR_3DHIGHLIGHT, | |
146 "COLOR_3DHILIGHT" : COLOR_3DHILIGHT, | |
147 "COLOR_BTNHILIGHT" : COLOR_BTNHILIGHT | |
148 ]; | |
149 foreach(key, value; colors) | |
150 Stdout.format("{,-27} : {}", key, getColor(value).toUtf8).newline; | |
151 | |
152 } | |
153 } | |
154 static Color getColor(int index) { | |
155 version(Windows) { | |
156 uint sysColor = GetSysColor(index); | |
157 return Color(GetRValue(sysColor), GetGValue(sysColor), GetBValue(sysColor)); | |
158 } else { | |
159 return Color.Black; // TODO: temp to get X backend to compile | |
160 | |
161 uint sysColor = 0; | |
162 switch(sysColor) { | |
163 default: | |
164 assert(0, "error: default case hit"); | |
165 } | |
166 } | |
167 } | |
168 | |
169 //{{{ utility functions | |
170 int findUxState(Button c, int disabled, int normal, int hot, int pressed) { | |
171 if(c.state == ButtonState.Normal) | |
172 return normal; | |
173 else if(c.state == ButtonState.Hot) | |
174 return hot; | |
175 else if(c.state == ButtonState.Pressed) | |
176 return pressed; | |
177 } | |
178 | |
179 /// draws a classic check, which is 7 wide and 7 high | |
180 void drawCheck(Graphics g, real x, real y) { | |
181 g.source = getColor(COLOR_WINDOWTEXT); | |
182 auto checkYs = [2, 3, 4, 3, 2, 1, 0]; | |
183 foreach(i, cy; checkYs) { | |
184 g.moveTo(x + i + 0.5, y + cy); | |
185 g.lineTo(x + i + 0.5, y + cy + 3); | |
186 g.stroke(); | |
187 } | |
188 } | |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
189 /// draws a dotted focus rectangle |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
190 void drawFocus(Graphics g, int colorIndex, real x, real y, real w, real h) { |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
191 g.lineWidth = 1; |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
192 g.source = getColor(colorIndex); |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
193 g.setDash([1, 1], 0.5); |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
194 g.rectangle(x, y, w, h); |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
195 g.stroke(); |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
196 } |
0 | 197 //}}} |
198 | |
199 string name() { | |
200 return "Windows"; | |
201 } | |
202 | |
203 void Window_paint(Window c, Graphics g) { | |
204 g.source = getColor(COLOR_3DFACE); | |
205 g.paint(); | |
206 } | |
207 //{{{ Button | |
208 Size Button_bestSize(Button c) { | |
209 // default button size is 17 points tall | |
210 return Size(75, 23); | |
211 } | |
212 | |
213 void Button_paint(Button c, Graphics g) { | |
214 version(Windows) { | |
215 if(Ux.isThemeActive()) { | |
216 auto uxState = findUxState(c, PBS_DISABLED, PBS_NORMAL, PBS_HOT, PBS_PRESSED); | |
217 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "BUTTON", BP_PUSHBUTTON, uxState); | |
218 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
52
diff
changeset
|
219 if(c.focused && c.showFocus) |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
220 drawFocus(g, COLOR_WINDOWTEXT, 3.5, 3.5, c.width-7, c.height-7); |
0 | 221 g.source = getColor(COLOR_WINDOWTEXT); |
222 c.paintFore(g); | |
223 return; | |
224 } | |
225 } | |
226 g.source = getColor(COLOR_3DFACE); | |
227 g.paint(); | |
228 if(c.state == ButtonState.Pressed) { | |
229 draw3dRectangle(g, 0, 0, c.width, c.height, | |
230 getColor(COLOR_3DDKSHADOW), getColor(COLOR_3DHIGHLIGHT)); | |
231 draw3dRectangle(g, 1, 1, c.width-2, c.height-2, | |
232 getColor(COLOR_3DSHADOW), getColor(COLOR_3DLIGHT)); | |
233 } else { | |
234 draw3dRectangle(g, 0, 0, c.width, c.height, | |
235 getColor(COLOR_3DHIGHLIGHT), getColor(COLOR_3DDKSHADOW)); | |
236 draw3dRectangle(g, 1, 1, c.width-2, c.height-2, | |
237 getColor(COLOR_3DLIGHT), getColor(COLOR_3DSHADOW)); | |
238 } | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
52
diff
changeset
|
239 if(c.focused && c.showFocus) |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
240 drawFocus(g, COLOR_WINDOWTEXT, 3.5, 3.5, c.width-7, c.height-7); |
0 | 241 g.source = getColor(COLOR_WINDOWTEXT); |
242 c.paintFore(g); | |
243 } | |
244 //}}} | |
245 | |
246 //{{{ CheckBox | |
247 void CheckBox_paint(CheckBox c, Graphics g) { | |
248 version(Windows) { | |
249 if(Ux.isThemeActive()) { | |
250 int uxState; | |
251 if(c.checked) { | |
252 uxState = findUxState(c, CBS_CHECKEDDISABLED, CBS_CHECKEDNORMAL, CBS_CHECKEDHOT, CBS_CHECKEDPRESSED); | |
253 } else { | |
254 uxState = findUxState(c, CBS_UNCHECKEDDISABLED, CBS_UNCHECKEDNORMAL, CBS_UNCHECKEDHOT, CBS_UNCHECKEDPRESSED); | |
255 } | |
256 Ux.drawBackground(g, Rect(0, 0, 13, c.height), "BUTTON", BP_CHECKBOX, uxState); | |
257 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
52
diff
changeset
|
258 if(c.focused && c.showFocus) |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
259 drawFocus(g, COLOR_WINDOWTEXT, |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
260 15.5, 0.5, c.width-16, c.height-1); |
0 | 261 g.source = getColor(COLOR_WINDOWTEXT); |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
262 g.translate(16, 0); |
0 | 263 c.paintFore(g); |
264 return; | |
265 } | |
266 } | |
267 | |
268 if(c.state == ButtonState.Pressed) | |
269 g.source = getColor(COLOR_3DFACE); | |
270 else | |
271 g.source = getColor(COLOR_WINDOW); | |
272 | |
273 g.rectangle(0, 0, 13, 13); | |
274 g.fill(); | |
275 draw3dRectangle(g, 0, 0, 13, 13, | |
276 getColor(COLOR_3DSHADOW), getColor(COLOR_3DHIGHLIGHT)); | |
277 draw3dRectangle(g, 1, 1, 11, 11, | |
278 getColor(COLOR_3DDKSHADOW), getColor(COLOR_3DLIGHT)); | |
279 | |
280 if(c.checked) | |
281 drawCheck(g, 3, 3); | |
282 // drawCheck(g, 0, 0, 13, 13); | |
283 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
52
diff
changeset
|
284 if(c.focused && c.showFocus) |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
285 drawFocus(g, COLOR_WINDOWTEXT, 15.5, 0.5, c.width-16, c.height-1); |
0 | 286 g.source = getColor(COLOR_WINDOWTEXT); |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
287 g.translate(16, 0); |
0 | 288 c.paintFore(g); |
289 } | |
290 //}}} | |
291 | |
292 //{{{ RadioButton | |
293 void RadioButton_paint(CheckBox c, Graphics g) { | |
294 version(Windows) { | |
295 if(Ux.isThemeActive()) { | |
296 int uxState; | |
297 if(c.checked) { | |
298 uxState = findUxState(c, RBS_CHECKEDDISABLED, RBS_CHECKEDNORMAL, RBS_CHECKEDHOT, RBS_CHECKEDPRESSED); | |
299 } else { | |
300 uxState = findUxState(c, RBS_UNCHECKEDDISABLED, RBS_UNCHECKEDNORMAL, RBS_UNCHECKEDHOT, RBS_UNCHECKEDPRESSED); | |
301 } | |
302 Ux.drawBackground(g, Rect(0, 0, 13, c.height), "BUTTON", BP_RADIOBUTTON, uxState); | |
303 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
52
diff
changeset
|
304 if(c.focused && c.showFocus) |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
305 drawFocus(g, COLOR_WINDOWTEXT, |
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
306 15.5, 0.5, c.width-16, c.height-1); |
0 | 307 g.source = getColor(COLOR_WINDOWTEXT); |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
308 g.translate(16, 0); |
0 | 309 c.paintFore(g); |
310 return; | |
311 } | |
312 } | |
313 | |
314 if(c.state == ButtonState.Pressed) | |
315 g.source = getColor(COLOR_3DFACE); | |
316 else | |
317 g.source = getColor(COLOR_WINDOW); | |
318 | |
319 g.rectangle(2, 2, 8, 8); | |
320 g.fill(); | |
321 const double[][] outerLines = [ | |
322 [1.5, 8, 1.5, 10], [0.5, 4, 0.5, 8], | |
323 [1.5, 2, 1.5, 4], [2.0, 1.5, 4, 1.5], | |
324 [4.0, 0.5, 8, 0.5], [8.0, 1.5, 10, 1.5]]; | |
325 const double[][] innerLines = [ | |
326 [2.5, 8, 2.5, 9], [1.5, 4, 1.5, 8], | |
327 [2.5, 2, 2.5, 4], [3.0, 2.5, 4, 2.5], | |
328 [4.0, 1.5, 8, 1.5], [8.0, 2.5, 10, 2.5]]; | |
329 g.source = getColor(COLOR_3DSHADOW); | |
330 foreach(line; outerLines) { | |
331 g.moveTo(line[0], line[1]); | |
332 g.lineTo(line[2], line[3]); | |
333 g.stroke(); | |
334 } | |
335 g.source = getColor(COLOR_3DDKSHADOW); | |
336 foreach(line; innerLines) { | |
337 g.moveTo(line[0], line[1]); | |
338 g.lineTo(line[2], line[3]); | |
339 g.stroke(); | |
340 } | |
341 g.source = getColor(COLOR_3DHIGHLIGHT); | |
342 foreach(line; outerLines) { | |
343 g.moveTo(12-line[0], 12-line[1]); | |
344 g.lineTo(12-line[2], 12-line[3]); | |
345 g.stroke(); | |
346 } | |
347 g.source = getColor(COLOR_3DLIGHT); | |
348 foreach(line; innerLines) { | |
349 g.moveTo(12-line[0], 12-line[1]); | |
350 g.lineTo(12-line[2], 12-line[3]); | |
351 g.stroke(); | |
352 } | |
353 | |
354 if(c.checked) { | |
355 g.source = getColor(COLOR_WINDOWTEXT); | |
356 g.translate(4, 4); | |
357 g.rectangle(1, 0, 2, 1); | |
358 g.rectangle(0, 1, 4, 2); | |
359 g.rectangle(1, 3, 2, 1); | |
360 g.fill(); | |
361 g.translate(-4, -4); | |
362 } | |
363 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
52
diff
changeset
|
364 if(c.focused && c.showFocus) |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
365 drawFocus(g, COLOR_WINDOWTEXT, 15.5, 0.5, c.width-16, c.height-1); |
0 | 366 g.source = getColor(COLOR_WINDOWTEXT); |
52
d82c7e5b037b
Draw focus rectangles for buttons, check boxes, and radio buttons in WindowsTheme.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
367 g.translate(16, 0); |
0 | 368 c.paintFore(g); |
369 } | |
370 //}}} | |
371 | |
372 //{{{ ScrollBar | |
373 void ScrollBarTrack_paint(ScrollBarTrack c, Graphics g) { | |
374 version(Windows) { | |
375 if(Ux.isThemeActive()) { | |
376 auto uxState = findUxState(c, SCRBS_DISABLED, SCRBS_NORMAL, SCRBS_HOT, SCRBS_PRESSED); | |
377 if(cast(VScrollBar)c.parent) { | |
378 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_UPPERTRACKVERT, uxState); | |
379 } else { | |
380 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_UPPERTRACKHORZ, uxState); | |
381 } | |
382 return; | |
383 } | |
384 } | |
385 | |
386 Color c1 = getColor(COLOR_3DHIGHLIGHT), c2 = getColor(COLOR_SCROLLBAR); | |
387 if(c.state == ButtonState.Pressed) { | |
388 c1.invert(); | |
389 c2.invert(); | |
390 } | |
391 int x = cast(int)round(c.x), y = cast(int)round(c.y); | |
392 drawCheckerboard(g, -(x & 1), -(y & 1), c.width + 1, c.height + 1, | |
393 c1, c2); | |
394 } | |
395 | |
396 void ScrollBarThumb_paint(ScrollBarThumb c, Graphics g) { | |
397 version(Windows) { | |
398 if(Ux.isThemeActive()) { | |
399 auto uxState = findUxState(c, SCRBS_DISABLED, SCRBS_NORMAL, SCRBS_HOT, SCRBS_PRESSED); | |
400 if(cast(VScrollBar)c.parent) { | |
401 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_THUMBBTNVERT, uxState); | |
402 if(c.height > 16) | |
403 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_GRIPPERVERT, 0); | |
404 } else { | |
405 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_THUMBBTNHORZ, uxState); | |
406 if(c.width > 16) | |
407 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_GRIPPERHORZ, 0); | |
408 } | |
409 return; | |
410 } | |
411 } | |
412 | |
413 g.source = getColor(COLOR_3DFACE); | |
414 g.paint(); | |
415 draw3dRectangle(g, 0, 0, c.width, c.height, | |
416 getColor(COLOR_3DLIGHT), getColor(COLOR_3DDKSHADOW)); | |
417 draw3dRectangle(g, 1, 1, c.width-2, c.height-2, | |
418 getColor(COLOR_3DHIGHLIGHT), getColor(COLOR_3DSHADOW)); | |
419 } | |
420 | |
421 real ScrollBar_size() { | |
422 // TODO: all themes should get this from SystemGui.ScrollBarSize | |
423 version(Windows) | |
424 return GetSystemMetrics(SM_CXVSCROLL); | |
425 else | |
426 return 18; | |
427 } | |
428 | |
429 void ArrowButton_paint(ArrowButton c, Graphics g) { | |
430 version(Windows) { | |
431 if(Ux.isThemeActive()) { | |
432 int uxState; | |
433 if(c.direction == ArrowDirection.Left) | |
434 uxState = findUxState(c, ABS_LEFTDISABLED, ABS_LEFTNORMAL, ABS_LEFTHOT, ABS_LEFTPRESSED); | |
435 else if(c.direction == ArrowDirection.Right) | |
436 uxState = findUxState(c, ABS_RIGHTDISABLED, ABS_RIGHTNORMAL, ABS_RIGHTHOT, ABS_RIGHTPRESSED); | |
437 else if(c.direction == ArrowDirection.Up) | |
438 uxState = findUxState(c, ABS_UPDISABLED, ABS_UPNORMAL, ABS_UPHOT, ABS_UPPRESSED); | |
439 else | |
440 uxState = findUxState(c, ABS_DOWNDISABLED, ABS_DOWNNORMAL, ABS_DOWNHOT, ABS_DOWNPRESSED); | |
441 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "SCROLLBAR", SBP_ARROWBTN, uxState); | |
442 return; | |
443 } | |
444 } | |
445 | |
446 g.source = getColor(COLOR_3DFACE); | |
447 g.paint(); | |
448 if(c.state == ButtonState.Pressed) { | |
449 g.source = getColor(COLOR_3DDKSHADOW); | |
450 g.rectangle(0.5, 0.5, c.width-1, c.height-1); | |
451 g.stroke(); | |
452 } else { | |
453 draw3dRectangle(g, 0, 0, c.width, c.height, | |
454 getColor(COLOR_3DLIGHT), getColor(COLOR_3DDKSHADOW)); | |
455 draw3dRectangle(g, 1, 1, c.width-2, c.height-2, | |
456 getColor(COLOR_3DHIGHLIGHT), getColor(COLOR_3DSHADOW)); | |
457 } | |
458 } | |
459 //}}} | |
460 | |
461 //{{{ Scrollable | |
462 BorderSize Scrollable_borderSize(Scrollable c) { | |
463 return BorderSize(2, 2, 2, 2); | |
464 } | |
465 | |
466 void Scrollable_paint(Scrollable c, Graphics g) { | |
467 version(Windows) { | |
468 if(Ux.isThemeActive()) { | |
469 Ux.drawBackground(g, Rect(0, 0, c.width, c.height), "EDIT", EP_EDITTEXT, ETS_NORMAL); | |
470 // TODO: get this working | |
471 //g.Source = c.backColor; | |
472 g.source = getColor(COLOR_WINDOW); | |
473 g.rectangle(1.5, 1.5, c.width-3, c.height-3); | |
474 g.stroke(); | |
475 return; | |
476 } | |
477 } | |
478 draw3dRectangle(g, 0, 0, c.width, c.height, | |
479 getColor(COLOR_3DSHADOW), getColor(COLOR_3DHIGHLIGHT)); | |
480 draw3dRectangle(g, 1, 1, c.width-2, c.height-2, | |
481 getColor(COLOR_3DDKSHADOW), getColor(COLOR_3DLIGHT)); | |
482 } | |
483 //}}} | |
484 | |
485 //{{{ Notebook | |
486 BorderSize Notebook_borderSize(Notebook c) { | |
487 version(Windows) { | |
488 if(Ux.isThemeActive()) | |
489 return BorderSize(2, 2, 4, 4); | |
490 } | |
491 return BorderSize(2, 2, 2, 2); | |
492 } | |
493 void Tab_paint(TabPage page, Notebook c, Graphics g) { | |
494 version(Windows) { | |
495 if(Ux.isThemeActive()) { | |
496 g.translate(page.tabLocation); | |
497 //auto uxState = findUxState(c, PBS_DISABLED, PBS_NORMAL, PBS_HOT, PBS_PRESSED); | |
498 auto uxState = TIS_NORMAL; | |
499 BorderSize selectedDelta; | |
500 if(page is c.selectedTabPage) { | |
501 uxState = TIS_SELECTED; | |
502 selectedDelta = BorderSize(2, 2, 2, 2); | |
503 } | |
504 Ux.drawBackground(g, Point() + page.tabSize + selectedDelta, "TAB", TABP_TABITEM, uxState); | |
505 g.drawText(page.text, 5, (page.tabSize.height-g.getTextExtents(page.text).height)/2); | |
506 g.translate(-page.tabLocation); | |
507 return; | |
508 } | |
509 } | |
510 g.translate(page.tabLocation); | |
511 g.source = getColor(COLOR_3DHIGHLIGHT); | |
512 g.moveTo(0.5, 2); | |
513 g.lineTo(0.5, page.tabSize.height); | |
514 g.moveTo(1, 1.5); | |
515 g.lineTo(2, 1.5); | |
516 g.moveTo(2, 0.5); | |
517 g.lineTo(page.tabSize.width-2, 0.5); | |
518 g.stroke(); | |
519 g.source = Color(128, 128, 128); | |
520 g.moveTo(page.tabSize.width-1.5, 2); | |
521 g.lineTo(page.tabSize.width-1.5, page.tabSize.height); | |
522 g.stroke(); | |
523 g.source = Color(64, 64, 64); | |
524 g.moveTo(page.tabSize.width-2, 1.5); | |
525 g.lineTo(page.tabSize.width-1, 1.5); | |
526 g.moveTo(page.tabSize.width-0.5, 2); | |
527 g.lineTo(page.tabSize.width-0.5, page.tabSize.height); | |
528 g.stroke(); | |
529 g.source = getColor(COLOR_WINDOWTEXT); | |
530 g.drawText(page.text, 5, (page.tabSize.height-g.getTextExtents(page.text).height)/2); | |
531 g.translate(-page.tabLocation); | |
532 } | |
533 void Notebook_paint(Notebook c, Graphics g) { | |
534 version(Windows) { | |
535 if(Ux.isThemeActive()) { | |
536 //auto uxState = findUxState(c, PBS_DISABLED, PBS_NORMAL, PBS_HOT, PBS_PRESSED); | |
537 Ux.drawBackground(g, Rect(0, c._tabAreaSize, c.width, c.height-c._tabAreaSize), "TAB", TABP_PANE, 0); | |
538 g.save(); | |
539 g.rectangle(4, 4, c.width-8, c.height-8); | |
540 g.clip(); | |
541 for(float i = 4; i < c.width-8+10; i += 10) | |
542 Ux.drawBackground(g, Rect(i, c._tabAreaSize+4, 10, c.height*1.7-8-(c._tabAreaSize+4)), "TAB", TABP_BODY, 0); | |
543 g.restore(); | |
544 | |
545 return; | |
546 } | |
547 } | |
548 draw3dRectangle(g, 0, c._tabAreaSize, c.width, c.height, | |
549 getColor(COLOR_3DHIGHLIGHT), Color(64, 64, 64)); | |
550 draw3dRectangle(g, 1, c._tabAreaSize+1, c.width-2, c.height-2, | |
551 Color(212, 208, 200), Color(128, 128, 128)); | |
552 | |
553 } | |
554 //}}} | |
555 | |
556 } | |
557 |