Initial revision
[wmaker-crm.git] / WINGs / wmisc.c
blob942d78bfddeaed0696d54e8e4f1db310c5926c2e
2 #include "WINGsP.h"
4 #include <wraster.h>
5 #include <ctype.h>
8 void
9 W_DrawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
10 unsigned int height, WMReliefType relief)
12 Display *dpy = scr->display;
13 GC bgc;
14 GC wgc;
15 GC lgc;
16 GC dgc;
18 switch (relief) {
19 case WRSimple:
20 XDrawRectangle(dpy, d, W_GC(scr->black), x, y, width-1, height-1);
21 return;
22 break;
24 case WRRaised:
25 bgc = W_GC(scr->black);
26 dgc = W_GC(scr->darkGray);
27 wgc = W_GC(scr->white);
28 lgc = W_GC(scr->gray);
29 break;
31 case WRSunken:
32 wgc = W_GC(scr->darkGray);
33 lgc = W_GC(scr->black);
34 bgc = W_GC(scr->white);
35 dgc = W_GC(scr->gray);
36 break;
38 case WRPushed:
39 lgc = wgc = W_GC(scr->black);
40 dgc = bgc = W_GC(scr->white);
41 break;
43 case WRRidge:
44 lgc = bgc = W_GC(scr->darkGray);
45 dgc = wgc = W_GC(scr->white);
46 break;
48 case WRGroove:
49 wgc = dgc = W_GC(scr->darkGray);
50 lgc = bgc = W_GC(scr->white);
51 break;
53 default:
54 return;
56 /* top left */
57 XDrawLine(dpy, d, wgc, x, y, x+width-1, y);
58 if (width > 2 && relief != WRRaised && relief!=WRPushed) {
59 XDrawLine(dpy, d, lgc, x+1, y+1, x+width-3, y+1);
62 XDrawLine(dpy, d, wgc, x, y, x, y+height-1);
63 if (height > 2 && relief != WRRaised && relief!=WRPushed) {
64 XDrawLine(dpy, d, lgc, x+1, y+1, x+1, y+height-3);
67 /* bottom right */
68 XDrawLine(dpy, d, bgc, x, y+height-1, x+width-1, y+height-1);
69 if (width > 2 && relief!=WRPushed) {
70 XDrawLine(dpy, d, dgc, x+1, y+height-2, x+width-2, y+height-2);
73 XDrawLine(dpy, d, bgc, x+width-1, y, x+width-1, y+height-1);
74 if (height > 2 && relief!=WRPushed) {
75 XDrawLine(dpy, d, dgc, x+width-2, y+2, x+width-2, y+height-3);
80 static int
81 fitText(char *text, WMFont *font, int width, int wrap)
83 int i, j;
84 int w;
86 if (text[0]==0)
87 return 0;
88 i = 0;
89 if (wrap) {
90 do {
91 i++;
92 w = WMWidthOfString(font, text, i);
93 } while (w < width && text[i]!='\n' && text[i]!=0);
95 /* keep words complete */
96 if (!isspace(text[i])) {
97 j = i;
98 while (j>1 && !isspace(text[j]) && text[j]!=0)
99 j--;
100 if (j>1)
101 i = j;
103 } else {
104 while (text[i]!='\n' && text[i]!=0)
105 i++;
108 return i;
113 W_GetTextHeight(WMFont *font, char *text, int width, int wrap)
115 char *ptr = text;
116 int count;
117 int length = strlen(text);
118 int h;
120 h = 0;
121 while (length > 0) {
122 count = fitText(ptr, font, width, wrap);
124 h += font->height;
126 if (isspace(ptr[count]))
127 count++;
129 ptr += count;
130 length -= count;
132 return h;
136 void
137 W_PaintText(W_View *view, Drawable d, WMFont *font, int x, int y,
138 int width, WMAlignment alignment, GC gc,
139 int wrap, char *text, int length)
141 char *ptr = text;
142 int line_width;
143 int line_x;
144 int count;
146 while (length > 0) {
147 count = fitText(ptr, font, width, wrap);
149 line_width = WMWidthOfString(font, ptr, count);
150 if (alignment==WALeft)
151 line_x = x;
152 else if (alignment==WARight)
153 line_x = x + width - line_width;
154 else
155 line_x = x + (width - line_width) / 2;
157 WMDrawString(view->screen, d, gc, font, line_x, y, ptr, count);
159 y += font->height;
161 if (isspace(ptr[count]))
162 count++;
164 ptr += count;
165 length -= count;
170 void
171 W_PaintTextAndImage(W_View *view, int wrap, GC textGC, W_Font *font,
172 WMReliefType relief, char *text,
173 WMAlignment alignment, W_Pixmap *image,
174 WMImagePosition position, GC backGC, int ofs)
176 W_Screen *screen = view->screen;
177 int ix, iy;
178 int x, y, w, h;
179 Drawable d = view->window;
182 #ifdef DOUBLE_BUFFER
183 d = XCreatePixmap(screen->display, view->window,
184 view->size.width, view->size.height, screen->depth);
185 #endif
187 /* background */
188 #ifndef DOUBLE_BUFFER
189 if (backGC) {
190 XFillRectangle(screen->display, d, backGC,
191 0, 0, view->size.width, view->size.height);
192 } else {
193 XClearWindow(screen->display, d);
195 #else
196 if (backGC)
197 XFillRectangle(screen->display, d, backGC, 0, 0,
198 view->size.width, view->size.height);
199 else {
200 XSetForeground(screen->display, screen->copyGC,
201 view->attribs.background_pixel);
202 XFillRectangle(screen->display, d, screen->copyGC, 0, 0,
203 view->size.width, view->size.height);
205 #endif
208 if (relief == WRFlat) {
209 x = 0;
210 y = 0;
211 w = view->size.width;
212 h = view->size.height;
213 } else {
214 x = 2;
215 y = 2;
216 w = view->size.width - 4;
217 h = view->size.height - 4;
220 /* calc. image alignment */
221 if (position!=WIPNoImage && image!=NULL) {
222 switch (position) {
223 case WIPOverlaps:
224 case WIPImageOnly:
225 ix = (view->size.width - image->width) / 2;
226 iy = (view->size.height - image->height) / 2;
228 x = 2;
229 y = 0;
231 break;
233 case WIPLeft:
234 ix = x;
235 iy = y + (h - image->height) / 2;
236 x = x + image->width + 5;
237 y = 0;
238 w -= image->width + 5;
239 break;
241 case WIPRight:
242 ix = view->size.width - image->width - x;
243 iy = y + (h - image->height) / 2;
244 w -= image->width + 5;
245 break;
247 case WIPBelow:
248 ix = (view->size.width - image->width) / 2;
249 iy = h - image->height;
250 y = 0;
251 h -= image->height;
252 break;
254 default:
255 case WIPAbove:
256 ix = (view->size.width - image->width) / 2;
257 iy = y;
258 y = image->height;
259 h -= image->height;
260 break;
263 ix += ofs;
264 iy += ofs;
266 XSetClipOrigin(screen->display, screen->clipGC, ix, iy);
267 XSetClipMask(screen->display, screen->clipGC, image->mask);
269 if (image->depth==1)
270 XCopyPlane(screen->display, image->pixmap, d, screen->clipGC,
271 0, 0, image->width, image->height, ix, iy, 1);
272 else
273 XCopyArea(screen->display, image->pixmap, d, screen->clipGC,
274 0, 0, image->width, image->height, ix, iy);
277 /* draw text */
278 if (position != WIPImageOnly && text!=NULL) {
279 int textHeight;
281 textHeight = W_GetTextHeight(font, text, w-8, wrap);
282 W_PaintText(view, d, font, x+ofs+4, y+ofs + (h-textHeight)/2, w-8,
283 alignment, textGC, wrap, text, strlen(text));
287 /* draw relief */
288 W_DrawRelief(screen, d, 0, 0, view->size.width, view->size.height, relief);
290 #ifdef DOUBLE_BUFFER
291 XCopyArea(screen->display, d, view->window, screen->copyGC, 0, 0,
292 view->size.width, view->size.height, 0, 0);
293 XFreePixmap(screen->display, d);
294 #endif