]>
Commit | Line | Data |
---|---|---|
efef92ce | 1 | Index: vcl/source/window/menu.cxx |
2 | =================================================================== | |
3 | RCS file: /cvs/gsl/vcl/source/window/menu.cxx,v | |
4 | retrieving revision 1.96 | |
5 | diff -u -p -u -r1.96 menu.cxx | |
6 | --- vcl/source/window/menu.cxx 12 Jun 2003 07:51:30 -0000 1.96 | |
7 | +++ vcl/source/window/menu.cxx 6 Aug 2003 16:44:44 -0000 | |
8 | @@ -171,6 +171,339 @@ | |
9 | ||
10 | #include <map> | |
11 | ||
12 | + | |
13 | +#include <ctype.h> | |
14 | +#include <stdio.h> | |
15 | + | |
16 | +#include <salbtype.hxx> | |
17 | +#include <bmpacc.hxx> | |
18 | + | |
19 | +#include "menu-checkbox-off.xpm" | |
20 | +#include "menu-checkbox-on.xpm" | |
21 | +#include "menu-radio-off.xpm" | |
22 | +#include "menu-radio-on.xpm" | |
23 | + | |
24 | +static void | |
25 | +rgb_to_hls (double *r, | |
26 | + double *g, | |
27 | + double *b) | |
28 | +{ | |
29 | + double min; | |
30 | + double max; | |
31 | + double red; | |
32 | + double green; | |
33 | + double blue; | |
34 | + double h, l, s; | |
35 | + double delta; | |
36 | + | |
37 | + red = *r; | |
38 | + green = *g; | |
39 | + blue = *b; | |
40 | + | |
41 | + if (red > green) { | |
42 | + if (red > blue) | |
43 | + max = red; | |
44 | + else | |
45 | + max = blue; | |
46 | + | |
47 | + if (green < blue) | |
48 | + min = green; | |
49 | + else | |
50 | + min = blue; | |
51 | + } else { | |
52 | + if (green > blue) | |
53 | + max = green; | |
54 | + else | |
55 | + max = blue; | |
56 | + | |
57 | + if (red < blue) | |
58 | + min = red; | |
59 | + else | |
60 | + min = blue; | |
61 | + } | |
62 | + | |
63 | + l = (max + min) / 2; | |
64 | + s = 0; | |
65 | + h = 0; | |
66 | + | |
67 | + if (max != min) { | |
68 | + if (l <= 0.5) | |
69 | + s = (max - min) / (max + min); | |
70 | + else | |
71 | + s = (max - min) / (2 - max - min); | |
72 | + | |
73 | + delta = max -min; | |
74 | + if (red == max) | |
75 | + h = (green - blue) / delta; | |
76 | + else if (green == max) | |
77 | + h = 2 + (blue - red) / delta; | |
78 | + else if (blue == max) | |
79 | + h = 4 + (red - green) / delta; | |
80 | + | |
81 | + h *= 60; | |
82 | + if (h < 0.0) | |
83 | + h += 360; | |
84 | + } | |
85 | + | |
86 | + *r = h; | |
87 | + *g = l; | |
88 | + *b = s; | |
89 | +} | |
90 | + | |
91 | +static void | |
92 | +hls_to_rgb (double *h, | |
93 | + double *l, | |
94 | + double *s) | |
95 | +{ | |
96 | + double hue; | |
97 | + double lightness; | |
98 | + double saturation; | |
99 | + double m1, m2; | |
100 | + double r, g, b; | |
101 | + | |
102 | + lightness = *l; | |
103 | + saturation = *s; | |
104 | + | |
105 | + if (lightness <= 0.5) | |
106 | + m2 = lightness * (1 + saturation); | |
107 | + else | |
108 | + m2 = lightness + saturation - lightness * saturation; | |
109 | + m1 = 2 * lightness - m2; | |
110 | + | |
111 | + if (saturation == 0) { | |
112 | + *h = lightness; | |
113 | + *l = lightness; | |
114 | + *s = lightness; | |
115 | + } else { | |
116 | + hue = *h + 120; | |
117 | + while (hue > 360) | |
118 | + hue -= 360; | |
119 | + while (hue < 0) | |
120 | + hue += 360; | |
121 | + | |
122 | + if (hue < 60) | |
123 | + r = m1 + (m2 - m1) * hue / 60; | |
124 | + else if (hue < 180) | |
125 | + r = m2; | |
126 | + else if (hue < 240) | |
127 | + r = m1 + (m2 - m1) * (240 - hue) / 60; | |
128 | + else | |
129 | + r = m1; | |
130 | + | |
131 | + hue = *h; | |
132 | + while (hue > 360) | |
133 | + hue -= 360; | |
134 | + while (hue < 0) | |
135 | + hue += 360; | |
136 | + | |
137 | + if (hue < 60) | |
138 | + g = m1 + (m2 - m1) * hue / 60; | |
139 | + else if (hue < 180) | |
140 | + g = m2; | |
141 | + else if (hue < 240) | |
142 | + g = m1 + (m2 - m1) * (240 - hue) / 60; | |
143 | + else | |
144 | + g = m1; | |
145 | + | |
146 | + hue = *h - 120; | |
147 | + while (hue > 360) | |
148 | + hue -= 360; | |
149 | + while (hue < 0) | |
150 | + hue += 360; | |
151 | + | |
152 | + if (hue < 60) | |
153 | + b = m1 + (m2 - m1) * hue / 60; | |
154 | + else if (hue < 180) | |
155 | + b = m2; | |
156 | + else if (hue < 240) | |
157 | + b = m1 + (m2 - m1) * (240 - hue) / 60; | |
158 | + else | |
159 | + b = m1; | |
160 | + | |
161 | + *h = r; | |
162 | + *l = g; | |
163 | + *s = b; | |
164 | + } | |
165 | +} | |
166 | + | |
167 | +/* Does some weird shading from the bg and fg colors and puts the result in (ir, ig, ib) */ | |
168 | +static void | |
169 | +shade_rgb (int *ir, int *ig, int *ib, const Color &fg_color, const Color &bg_color, double value) | |
170 | +{ | |
171 | + double r, g, b; | |
172 | + double f_r, f_g, f_b; | |
173 | + | |
174 | + r = bg_color.GetRed () / 255.0; | |
175 | + g = bg_color.GetGreen () / 255.0; | |
176 | + b = bg_color.GetBlue () / 255.0; | |
177 | + | |
178 | + f_r = fg_color.GetRed () / 255.0; | |
179 | + f_g = fg_color.GetGreen () / 255.0; | |
180 | + f_b = fg_color.GetBlue () / 255.0; | |
181 | + | |
182 | + rgb_to_hls (&r, &g, &b); | |
183 | + rgb_to_hls (&f_r, &f_g, &f_b); | |
184 | + | |
185 | + /* now green is the lightness */ | |
186 | + | |
187 | + g = (g - f_g) * value + f_g; | |
188 | + if (g > 1.0) | |
189 | + g = 1.0; | |
190 | + else if (g < 0.0) | |
191 | + g = 0.0; | |
192 | + | |
193 | + hls_to_rgb (&r, &g, &b); | |
194 | + | |
195 | + *ir = (r * 255.0) + 0.5; | |
196 | + *ig = (g * 255.0) + 0.5; | |
197 | + *ib = (b * 255.0) + 0.5; | |
198 | +} | |
199 | + | |
200 | +/* Takes a grayscale XPM and shades it into a Bitmap */ | |
201 | +static Bitmap * | |
202 | +create_shaded_bitmap (char **xpm, const Color &fg_color, const Color &bg_color) | |
203 | +{ | |
204 | + char *line; | |
205 | + int width, height, n_colors, color_len; | |
206 | + int palette[256]; /* 0xRRGGBBAA */ | |
207 | + Bitmap *bitmap; | |
208 | + BitmapWriteAccess *wa; | |
209 | + int i; | |
210 | + int y; | |
211 | + int br, bg, bb; | |
212 | + | |
213 | + line = xpm[0]; | |
214 | + | |
215 | + if (sscanf (line, "%d%d%d%d", &width, &height, &n_colors, &color_len) != 4) | |
216 | + return NULL; | |
217 | + | |
218 | + if (color_len != 1) | |
219 | + return NULL; | |
220 | + | |
221 | + /* Read the palette */ | |
222 | + | |
223 | + for (i = 0; i < 256; i++) | |
224 | + palette[i] = 0; | |
225 | + | |
226 | + for (i = 0; i < n_colors; i++) { | |
227 | + char *p; | |
228 | + int color_id; | |
229 | + int color; | |
230 | + BOOL is_transparent; | |
231 | + | |
232 | + line = xpm[i + 1]; | |
233 | + p = line; | |
234 | + | |
235 | + color_id = *p++; | |
236 | + | |
237 | + while (*p && isspace (*p)) | |
238 | + p++; | |
239 | + | |
240 | + if (*p != 'c') | |
241 | + return NULL; | |
242 | + | |
243 | + p++; | |
244 | + | |
245 | + while (*p && isspace (*p)) | |
246 | + p++; | |
247 | + | |
248 | + color = 0; | |
249 | + is_transparent = TRUE; | |
250 | + | |
251 | + if (*p == '#') { | |
252 | + p++; | |
253 | + is_transparent = FALSE; | |
254 | + | |
255 | + while (*p) { | |
256 | + color = (color << 4); | |
257 | + | |
258 | + if (*p >= '0' && *p <= '9') | |
259 | + color += *p - '0'; | |
260 | + else if (*p >= 'A' && *p <= 'Z') | |
261 | + color += *p - 'A' + 10; | |
262 | + else | |
263 | + break; | |
264 | + | |
265 | + p++; | |
266 | + } | |
267 | + } | |
268 | + | |
269 | + color = color << 8; | |
270 | + if (!is_transparent) | |
271 | + color = color | 0xFF; | |
272 | + | |
273 | + palette[color_id] = color; | |
274 | + } | |
275 | + | |
276 | + /* Create the bitmap */ | |
277 | + | |
278 | + bitmap = new Bitmap (Size (width, height), 24); | |
279 | + if (!bitmap) | |
280 | + return NULL; | |
281 | + | |
282 | + wa = bitmap->AcquireWriteAccess (); | |
283 | + if (!wa) { | |
284 | + delete bitmap; | |
285 | + return NULL; | |
286 | + } | |
287 | + | |
288 | + br = bg_color.GetRed (); | |
289 | + bg = bg_color.GetGreen (); | |
290 | + bb = bg_color.GetBlue (); | |
291 | + | |
292 | + for (y = 0; y < height; y++) { | |
293 | + int x; | |
294 | + | |
295 | + line = xpm[y + n_colors + 1]; | |
296 | + | |
297 | + for (x = 0; x < width; x++) { | |
298 | + int color; | |
299 | + double gray; | |
300 | + int r, g, b, a; | |
301 | + int tmp; | |
302 | + | |
303 | + color = palette[line[x]]; | |
304 | + gray = ((color & 0xFF00) >> 8) / 254.0; /* who knows why that is the maximum value in the files */ | |
305 | + a = color & 0xFF; | |
306 | + | |
307 | + shade_rgb (&r, &g, &b, fg_color, bg_color, gray); | |
308 | + | |
309 | + tmp = (r - br) * a; | |
310 | + r = br + ((tmp + (tmp >> 8) + 0x80) >> 8); | |
311 | + | |
312 | + tmp = (g - bg) * a; | |
313 | + g = bg + ((tmp + (tmp >> 8) + 0x80) >> 8); | |
314 | + | |
315 | + tmp = (b - bb) * a; | |
316 | + b = bb + ((tmp + (tmp >> 8) + 0x80) >> 8); | |
317 | + | |
318 | + wa->SetPixel (y, x, BitmapColor (r, g, b)); | |
319 | + } | |
320 | + } | |
321 | + | |
322 | + bitmap->ReleaseAccess (wa); | |
323 | + | |
324 | + return bitmap; | |
325 | +} | |
326 | + | |
327 | +/* Generates the appropriate image for a check or radio menu item */ | |
328 | +static Bitmap * | |
329 | +create_option_bitmap (BOOL is_radio, BOOL is_active, const Color &fg_color, const Color &bg_color) | |
330 | +{ | |
331 | + static char **xpms[] = { | |
332 | + menu_checkbox_off_xpm, | |
333 | + menu_checkbox_on_xpm, | |
334 | + menu_radio_off_xpm, | |
335 | + menu_radio_on_xpm | |
336 | + }; | |
337 | + | |
338 | + char **xpm; | |
339 | + | |
340 | + xpm = xpms[(is_radio ? 2 : 0) | (is_active ? 1 : 0)]; | |
341 | + | |
342 | + return create_shaded_bitmap (xpm, fg_color, bg_color); | |
343 | +} | |
344 | + | |
345 | namespace vcl | |
346 | { | |
347 | ||
348 | @@ -2093,6 +2435,7 @@ void Menu::ImplPaint( Window* pWin, USHO | |
349 | } | |
350 | ||
351 | // CheckMark | |
352 | +#if 0 | |
353 | if ( !bLayout && !bIsMenuBar && pData->bChecked ) | |
354 | { | |
355 | Rectangle aRect; | |
356 | @@ -2116,6 +2459,37 @@ void Menu::ImplPaint( Window* pWin, USHO | |
357 | } | |
358 | aDecoView.DrawSymbol( aRect, eSymbol, pWin->GetTextColor(), nSymbolStyle ); | |
359 | } | |
360 | +#endif | |
361 | + if ( !bIsMenuBar | |
362 | + && !pData->pSubMenu | |
363 | + && ( pData->bChecked || (pData->nBits & (MIB_RADIOCHECK | MIB_CHECKABLE | MIB_AUTOCHECK)) ) ) | |
364 | + { | |
365 | + Bitmap *bitmap; | |
366 | + BOOL is_radio; | |
367 | + BOOL is_active; | |
368 | + const StyleSettings &settings = pWin->GetSettings().GetStyleSettings(); | |
369 | + | |
370 | + is_radio = (pData->nBits & MIB_RADIOCHECK) != 0; | |
371 | + is_active = pData->bChecked; | |
372 | + | |
373 | + bitmap = create_option_bitmap (is_radio, | |
374 | + is_active, | |
375 | + settings.GetMenuTextColor (), | |
376 | + pWin->GetFillColor ()); | |
377 | + | |
378 | + if (bitmap) { | |
379 | + Point p; | |
380 | + int text_yofs; | |
381 | + | |
382 | + text_yofs = (pData->aSz.Height() - nFontHeight) / 2; | |
383 | + | |
384 | + p.X () = aPos.X () + nCheckPos; | |
385 | + p.Y () = aPos.Y () + text_yofs + nFontHeight / 2 - bitmap->GetSizePixel ().Height () / 2; | |
386 | + | |
387 | + pWin->DrawBitmap (p, *bitmap); | |
388 | + delete bitmap; | |
389 | + } | |
390 | + } | |
391 | ||
392 | // SubMenu? | |
393 | if ( !bLayout && !bIsMenuBar && pData->pSubMenu ) |