Radio and Check buttons now work
[wmaker-crm.git] / WINGs / wmisc.c
blob6c51f193641fdd4c21081dca752a33449e6934a3
2 #include "WINGsP.h"
4 #include <ctype.h>
6 //static void curve_rectangle(cairo_t *cr,
7 // double x0, double y0, double rect_width, double rect_height,
8 // double radius)
9 //{
10 // double x1,y1;
12 // x1=x0+rect_width;
13 // y1=y0+rect_height;
14 // if (!rect_width || !rect_height)
15 // return;
16 // if (rect_width/2<radius) {
17 // if (rect_height/2<radius) {
18 // cairo_move_to (cr, x0, (y0 + y1)/2);
19 // cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
20 // cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
21 // cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
22 // cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
23 // } else {
24 // cairo_move_to (cr, x0, y0 + radius);
25 // cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
26 // cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
27 // cairo_line_to (cr, x1 , y1 - radius);
28 // cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
29 // cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
30 // }
31 // } else {
32 // if (rect_height/2<radius) {
33 // cairo_move_to (cr, x0, (y0 + y1)/2);
34 // cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
35 // cairo_line_to (cr, x1 - radius, y0);
36 // cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
37 // cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
38 // cairo_line_to (cr, x0 + radius, y1);
39 // cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
40 // } else {
41 // cairo_move_to (cr, x0, y0 + radius);
42 // cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
43 // cairo_line_to (cr, x1 - radius, y0);
44 // cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
45 // cairo_line_to (cr, x1 , y1 - radius);
46 // cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
47 // cairo_line_to (cr, x0 + radius, y1);
48 // cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
49 // }
50 // }
51 // cairo_close_path (cr);
52 //}
54 //void W_DrawButtonRelief(W_Screen *scr, cairo_t *cairo, int x, int y, unsigned int width, unsigned int height,
55 // WMReliefType relief, unsigned int pushLight)
56 //{
57 // cairo_save(cairo);
59 // WMColorSpec outerlefttop;
60 // WMColorSpec innerlefttop;
61 // WMColorSpec outerbottomright;
62 // WMColorSpec innerbottomright;
64 //#define NEW_LOOK 1
65 //#ifdef NEW_LOOK
66 //#define TOPFILL WMLightGrayColorSpec()
67 //#define BOTFILL WMGrayColorSpec()
68 //#else
69 //#define TOPFILL WMGrayColorSpec()
70 //#define BOTFILL WMGrayColorSpec()
71 //#endif
73 // WMColorSpec topfill = TOPFILL;
74 // WMColorSpec bottomfill = BOTFILL;
76 // //the highlight colors depend on the button relief
77 // switch (relief) {
78 // case WRSimple:
79 // {
80 // outerlefttop = WMBlackColorSpec();
81 // outerbottomright = WMBlackColorSpec();
82 // innerlefttop = WMTransparentColorSpec();
83 // innerbottomright = WMTransparentColorSpec();
84 // break;
85 // }
86 // case WRRaised:
87 // {
88 // outerlefttop = WMWhiteColorSpec();
89 // outerbottomright = WMBlackColorSpec();
90 // innerlefttop = WMTransparentColorSpec();
91 // innerbottomright = WMDarkGrayColorSpec();
92 // break;
93 // }
94 // case WRSunken:
95 // {
96 // outerlefttop = WMDarkGrayColorSpec();
97 // outerbottomright = WMWhiteColorSpec();
98 // innerlefttop = WMBlackColorSpec();
99 // innerbottomright = WMTransparentColorSpec();
100 // break;
101 // }
102 // case WRPushed:
103 // {
104 // if (pushLight) {
105 // topfill = WMWhiteColorSpec();
106 // bottomfill = WMWhiteColorSpec();
107 // }
108 // outerlefttop = WMBlackColorSpec();
109 // outerbottomright = WMWhiteColorSpec();
110 // innerlefttop = WMTransparentColorSpec();
111 // innerbottomright = WMTransparentColorSpec();
112 // break;
113 // }
114 // case WRRidge:
115 // {
116 // outerlefttop = WMWhiteColorSpec();
117 // outerbottomright = WMDarkGrayColorSpec();
118 // innerlefttop = WMTransparentColorSpec();
119 // innerbottomright = WMTransparentColorSpec();
120 // break;
121 // }
122 // case WRGroove:
123 // {
124 // outerlefttop = WMDarkGrayColorSpec();
125 // outerbottomright = WMDarkGrayColorSpec();
126 // innerlefttop = WMTransparentColorSpec();
127 // innerbottomright = WMTransparentColorSpec();
128 // break;
129 // }
130 // }
132 // //draw main gradient
133 // cairo_pattern_t *linpat;
134 // linpat = cairo_pattern_create_linear(0, 0, 0, height);
135 // cairo_pattern_add_color_stop_rgba(linpat, 0, topfill.red/255.0, topfill.green/255.0, topfill.blue/255.0, topfill.alpha/255.0);
136 // cairo_pattern_add_color_stop_rgba(linpat, 0, bottomfill.red/255.0, bottomfill.green/255.0, bottomfill.blue/255.0, bottomfill.alpha/255.0);
137 // cairo_set_source(cairo, linpat);
138 // cairo_rectangle(cairo, 0, 0, width, height);
139 // cairo_fill(cairo);
140 // cairo_stroke(cairo);
142 // //draw highlights
143 // cairo_set_line_width(cairo,1);
145 // WMColorSpecSet(cairo,&outerlefttop);
146 // cairo_rectangle(cairo,0,0,width-1,0);
147 // cairo_rectangle(cairo,0,0,0,height-1);
148 // cairo_stroke(cairo);
150 // WMColorSpecSet(cairo,&innerlefttop);
151 // cairo_rectangle(cairo,1,1,width-2,0);
152 // cairo_rectangle(cairo,1,1,0,height-2);
153 // cairo_stroke(cairo);
155 // WMColorSpecSet(cairo,&innerbottomright);
156 // cairo_rectangle(cairo,1,height-2,width-1,1);
157 // cairo_rectangle(cairo,width-2,1,1,height-2);
158 // cairo_stroke(cairo);
160 // WMColorSpecSet(cairo,&outerbottomright);
161 // cairo_rectangle(cairo,0,height-1,width,1);
162 // cairo_rectangle(cairo,width-1,0,1,height);
163 // cairo_stroke(cairo);
165 // cairo_pattern_destroy(linpat);
167 // cairo_restore(cairo);
170 void W_DrawRelief(W_Screen *scr, cairo_t *cairo, int x, int y, unsigned int width, unsigned int height,
171 WMReliefType relief)
173 // WMColorSpec b;
174 // WMColorSpec w;
175 // WMColorSpec d;
176 // WMColorSpec l;
178 // switch (relief) {
179 // case WRSimple:
180 // WMColorSpecSet(cairo, &b);
181 // cairo_rectangle(cairo, x, y, width-1, height-1);
182 // cairo_stroke(cairo);
183 // return;
185 // case WRRaised:
186 // b= WMBlackColorSpec();
187 // w= WMWhiteColorSpec();
188 // d= WMDarkGrayColorSpec();
189 // l= WMGrayColorSpec();
190 // break;
192 // case WRSunken:
193 // l= WMBlackColorSpec();
194 // b= WMWhiteColorSpec();
195 // w= WMDarkGrayColorSpec();
196 // d= WMGrayColorSpec();
197 // break;
199 // case WRPushed:
200 // l= w= WMBlackColorSpec();
201 // d= b= WMWhiteColorSpec();
202 // break;
204 // case WRRidge:
205 // l= b= WMDarkGrayColorSpec();
206 // d= w= WMWhiteColorSpec();
207 // break;
209 // case WRGroove:
210 // w= d= WMDarkGrayColorSpec();
211 // l= b= WMWhiteColorSpec();
212 // break;
214 // default:
215 // return;
216 // }
217 // /* top left */
218 // WMColorSpecSet(cairo, &w);
219 // cairo_move_to(cairo, x, y);
220 // cairo_line_to(cairo, x+width-1, y);
221 // cairo_stroke(cairo);
222 // if (width > 2 && relief != WRRaised && relief!=WRPushed) {
223 // WMColorSpecSet(cairo, &l);
224 // cairo_move_to(cairo, x+1, y+1);
225 // cairo_line_to(cairo, x+width-3, y+1);
226 // cairo_stroke(cairo);
227 // }
229 // WMColorSpecSet(cairo, &w);
230 // cairo_move_to(cairo, x, y);
231 // cairo_line_to(cairo, x, y+height-1);
232 // cairo_stroke(cairo);
233 // if (height > 2 && relief != WRRaised && relief!=WRPushed) {
234 // WMColorSpecSet(cairo, &l);
235 // cairo_move_to(cairo, x+1, y+1);
236 // cairo_line_to(cairo, x+1, y+height-3);
237 // cairo_stroke(cairo);
238 // }
240 // /* bottom right */
241 // WMColorSpecSet(cairo, &b);
242 // cairo_move_to(cairo, x, y+height-1);
243 // cairo_line_to(cairo, x+width-1, y+height-1);
244 // cairo_stroke(cairo);
245 // if (width > 2 && relief!=WRPushed) {
246 // WMColorSpecSet(cairo, &d);
247 // cairo_move_to(cairo, x+1, y+height-2);
248 // cairo_line_to(cairo, x+width-2, y+height-2);
249 // cairo_stroke(cairo);
250 // }
252 // WMColorSpecSet(cairo, &b);
253 // cairo_move_to(cairo, x+width-1, y);
254 // cairo_line_to(cairo, x+width-1, y+height-1);
255 // cairo_stroke(cairo);
256 // if (height > 2 && relief!=WRPushed) {
257 // WMColorSpecSet(cairo, &d);
258 // cairo_move_to(cairo, x+width-2, y+1);
259 // cairo_line_to(cairo, x+width-2, y+height-2);
260 // cairo_stroke(cairo);
261 // }
264 static int findNextWord(const char *text, int limit)
266 int pos, len;
268 //XXX this is broken
269 len = strcspn(text, " \t\n\r");
270 pos = len + strspn(text + len, " \t\n\r");
271 if (pos > limit)
272 pos = limit;
274 return pos;
277 static int fitText(const char *text, WMFont * font, int width, int wrap)
279 int i, w, beforecrlf, word1, word2;
281 /* text length before first cr/lf */
282 beforecrlf = strcspn(text, "\n");
284 if (!wrap || beforecrlf == 0)
285 return beforecrlf;
287 w = WMWidthOfString(font, text);
288 if (w <= width) {
289 /* text up to first crlf fits */
290 return beforecrlf;
293 word1 = 0;
294 while (1) {
295 word2 = word1 + findNextWord(text + word1, beforecrlf - word1);
296 if (word2 >= beforecrlf)
297 break;
298 w = WMWidthOfString(font, text);
299 if (w > width)
300 break;
301 word1 = word2;
304 for (i = word1; i < word2; i++) {
305 w = WMWidthOfString(font, text);
306 if (w > width) {
307 break;
311 /* keep words complete if possible */
312 if (!isspace(text[i]) && word1 > 0) {
313 i = word1;
314 } else if (isspace(text[i]) && i < beforecrlf) {
315 /* keep space on current row, so new row has next word in column 1 */
316 i++;
319 return i;
322 #ifdef OLD_CODE
323 static int fitText(char *text, WMFont * font, int width, int wrap)
325 int i, j;
326 int w;
328 if (text[0] == 0)
329 return 0;
331 i = 0;
332 if (wrap) {
333 if (text[0] == '\n')
334 return 0;
336 do {
337 i++;
338 w = WMWidthOfString(font, text, i);
339 } while (w < width && text[i] != '\n' && text[i] != 0);
341 if (text[i] == '\n')
342 return i;
344 /* keep words complete */
345 if (!isspace(text[i])) {
346 j = i;
347 while (j > 1 && !isspace(text[j]) && text[j] != 0)
348 j--;
349 if (j > 1)
350 i = j;
352 } else {
353 i = strcspn(text, "\n");
355 return i;
357 #endif
359 int W_GetTextHeight(cairo_t *cairo, WMFont *font, const char *text, int width, int wrap)
361 const char *ptr = text;
362 int count;
363 int length = strlen(text);
364 int h;
365 int fheight = WMFontHeight(font);
367 h = 0;
368 while (length > 0) {
369 count = fitText(ptr, font, width, wrap);
371 h += fheight;
373 if (isspace(ptr[count]))
374 count++;
376 ptr += count;
377 length -= count;
379 return h;
382 void W_PaintText(cairo_t *cairo, WMFont *font, int x, int y,
383 int width, WMAlignment alignment, WMColorSpec *color,
384 int wrap, const char *text)
386 const char *ptr = text;
387 int length= strlen(ptr);
388 int line_width;
389 int line_x= 0;
390 int count;
391 int fheight = WMFontHeight(font);
393 if (alignment == WALeft)
394 line_x = x;
395 else if (alignment == WARight)
396 line_x = x + width - WMWidthOfString(font,ptr);
397 else
398 line_x = x + (width - WMWidthOfString(font,ptr)) / 2;
399 WMDrawString(cairo, color, font, line_x, y, ptr);
400 return;
402 // while (length > 0) {
403 // count = fitText(ptr, font, width, wrap);
405 // line_width = WMWidthOfString(font, text);
407 // if (alignment == WALeft)
408 // line_x = x;
409 // else if (alignment == WARight)
410 // line_x = x + width - line_width;
411 // else
412 // line_x = x + (width - line_width) / 2;
414 // WMDrawString(cairo, color, font, line_x, y, ptr);
416 // if (wrap && ptr[count] != '\n')
417 // y += fheight;
419 // while (ptr[count] && ptr[count] == '\n') {
420 // y += fheight;
421 // count++;
422 // }
424 // ptr += count;
425 // length -= count;
426 // }
429 void W_PaintTextAndImage(W_Screen *screen, cairo_t *cairo, W_View *view, int wrap, WMColorSpec *textColor, W_Font *font,
430 WMReliefType relief, const char *text,
431 WMAlignment alignment, WMImage *image,
432 WMImagePosition position, WMColorSpec *backColor, int ofs)
434 int ix, iy;
435 int x, y, w, h;
437 cairo_save(cairo);
439 if (relief == WRFlat) {
440 x = 0;
441 y = 0;
442 w = view->size.width;
443 h = view->size.height;
444 } else {
445 x = 1;
446 y = 1;
447 w = view->size.width - 3;
448 h = view->size.height - 3;
451 /* calc. image alignment */
452 if (position != WIPNoImage && image != NULL) {
453 switch (position) {
454 case WIPOverlaps:
455 case WIPImageOnly:
456 ix = (view->size.width - WMGetImageWidth(image)) / 2;
457 iy = (view->size.height - WMGetImageHeight(image)) / 2;
459 x = 2;
460 y = 0;
462 break;
464 case WIPLeft:
465 ix = x;
466 iy = y + (h - WMGetImageHeight(image)) / 2;
467 x = x + WMGetImageWidth(image) + 5;
468 y = 0;
469 w -= WMGetImageWidth(image) + 5;
470 break;
472 case WIPRight:
473 ix = view->size.width - WMGetImageWidth(image) - x;
474 iy = y + (h - WMGetImageHeight(image)) / 2;
475 w -= WMGetImageWidth(image) + 5;
476 break;
478 case WIPBelow:
479 ix = (view->size.width - WMGetImageWidth(image)) / 2;
480 iy = h - WMGetImageHeight(image);
481 y = 0;
482 h -= WMGetImageHeight(image);
483 break;
485 default:
486 case WIPAbove:
487 ix = (view->size.width - WMGetImageWidth(image)) / 2;
488 iy = y;
489 y = WMGetImageHeight(image);
490 h -= WMGetImageHeight(image);
491 break;
494 cairo_set_operator(cairo,CAIRO_OPERATOR_SOURCE);
495 ix += ofs;
496 iy += ofs;
497 cairo_set_source_surface(cairo,image,ix+0.5,iy+0.5);
498 cairo_mask_surface(cairo,image,ix+0.5,iy+0.5);
499 cairo_stroke(cairo);
500 cairo_set_operator(cairo,CAIRO_OPERATOR_OVER);
504 /* draw text */
505 if (position != WIPImageOnly && text!=NULL) {
506 int textHeight;
508 textHeight = W_GetTextHeight(cairo, font, text, w-8, wrap);
509 W_PaintText(cairo, font, x+ofs+4, y+ofs + (h-textHeight)/2, w-8,
510 alignment, textColor, wrap, text);
513 cairo_restore(cairo);
514 /* draw relief */
515 //W_DrawRelief(screen, cairo, 0, 0, view->size.width, view->size.height, relief);
518 WMPoint wmkpoint(int x, int y)
520 WMPoint point;
522 point.x = x;
523 point.y = y;
525 return point;
528 WMSize wmksize(unsigned int width, unsigned int height)
530 WMSize size;
532 size.width = width;
533 size.height = height;
535 return size;
538 WMRect wmkrect(int x, int y, unsigned int width, unsigned int height)
540 WMRect rect;
542 rect.pos.x = x;
543 rect.pos.y = y;
544 rect.size.width = width;
545 rect.size.height = height;
547 return rect;