- Added double buffering when drawing a WMFrame title with an AA font to avoid
[wmaker-crm.git] / WINGs / wframe.c
blobe00fbb501b4c955edf2bb78cccb0e19b5327d8fb
2 #include "WINGsP.h"
5 typedef struct W_Frame {
6 W_Class widgetClass;
7 W_View *view;
9 char *caption;
12 struct {
13 WMReliefType relief:4;
14 WMTitlePosition titlePosition:4;
15 } flags;
16 } Frame;
19 #define DEFAULT_RELIEF WRGroove
20 #define DEFAULT_TITLE_POSITION WTPAtTop
21 #define DEFAULT_WIDTH 40
22 #define DEFAULT_HEIGHT 40
25 static void destroyFrame(Frame *fPtr);
26 static void paintFrame(Frame *fPtr);
27 static void repaintFrame(Frame *fPtr);
31 void
32 WMSetFrameTitlePosition(WMFrame *fPtr, WMTitlePosition position)
34 fPtr->flags.titlePosition = position;
36 if (fPtr->view->flags.realized) {
37 repaintFrame(fPtr);
42 void
43 WMSetFrameRelief(WMFrame *fPtr, WMReliefType relief)
45 fPtr->flags.relief = relief;
47 if (fPtr->view->flags.realized) {
48 repaintFrame(fPtr);
53 void
54 WMSetFrameTitle(WMFrame *fPtr, char *title)
56 if (fPtr->caption)
57 wfree(fPtr->caption);
58 if (title)
59 fPtr->caption = wstrdup(title);
60 else
61 fPtr->caption = NULL;
63 if (fPtr->view->flags.realized) {
64 repaintFrame(fPtr);
69 static void
70 repaintFrame(Frame *fPtr)
72 W_View *view = fPtr->view;
73 W_Screen *scrPtr = view->screen;
75 XClearWindow(scrPtr->display, view->window);
76 paintFrame(fPtr);
80 static void
81 paintFrame(Frame *fPtr)
83 W_View *view = fPtr->view;
84 W_Screen *scrPtr = view->screen;
85 WMFont *font = scrPtr->normalFont;
86 Display *display = scrPtr->display;
87 int tx, ty, tw, th, tlen;
88 int fy, fh;
89 Bool drawTitle;
91 if (fPtr->caption!=NULL) {
92 th = WMFontHeight(font);
93 tlen = strlen(fPtr->caption);
94 } else {
95 th = 0;
96 tlen = 0;
99 fh = view->size.height;
100 fy = 0;
102 switch (fPtr->flags.titlePosition) {
103 case WTPAboveTop:
104 ty = 0;
105 fy = th + 4;
106 fh = view->size.height - fy;
107 break;
109 case WTPAtTop:
110 ty = 0;
111 fy = th/2;
112 fh = view->size.height - fy;
113 break;
115 case WTPBelowTop:
116 ty = 4;
117 fy = 0;
118 fh = view->size.height;
119 break;
121 case WTPAboveBottom:
122 ty = view->size.height - th - 4;
123 fy = 0;
124 fh = view->size.height;
125 break;
127 case WTPAtBottom:
128 ty = view->size.height - th;
129 fy = 0;
130 fh = view->size.height - th/2;
131 break;
133 case WTPBelowBottom:
134 ty = view->size.height - th;
135 fy = 0;
136 fh = view->size.height - th - 4;
137 break;
139 default:
140 ty = 0;
141 fy = 0;
142 fh = view->size.height;
145 if (fPtr->caption!=NULL && fPtr->flags.titlePosition!=WTPNoTitle) {
146 tw = WMWidthOfString(font, fPtr->caption, tlen);
148 tx = (view->size.width - tw) / 2;
150 drawTitle = True;
151 } else {
152 drawTitle = False;
156 XRectangle rect;
157 Region region, tmp;
158 GC gc[4];
159 int i;
161 region = XCreateRegion();
163 if (drawTitle) {
164 tmp = XCreateRegion();
165 rect.x = tx;
166 rect.y = ty;
167 rect.width = tw;
168 rect.height = th;
169 XUnionRectWithRegion(&rect, tmp, tmp);
171 rect.x = 0;
172 rect.y = 0;
173 rect.width = view->size.width;
174 rect.height = view->size.height;
175 XUnionRectWithRegion(&rect, region, region);
176 if (drawTitle) {
177 XSubtractRegion(region, tmp, region);
178 XDestroyRegion(tmp);
180 gc[0] = WMColorGC(scrPtr->black);
181 gc[1] = WMColorGC(scrPtr->darkGray);
182 gc[2] = WMColorGC(scrPtr->gray);
183 gc[3] = WMColorGC(scrPtr->white);
185 for (i = 0; i < 4; i++) {
186 XSetRegion(display, gc[i], region);
188 XDestroyRegion(region);
190 W_DrawReliefWithGC(scrPtr, view->window, 0, fy, view->size.width, fh,
191 fPtr->flags.relief, gc[0], gc[1], gc[2], gc[3]);
193 for (i = 0; i < 4; i++) {
194 XSetClipMask(display, gc[i], None);
198 if (drawTitle) {
199 /* can't draw AA text over and over again because it gets messed */
200 if (font->antialiased) {
201 #ifdef DOUBLE_BUFFER
202 Drawable d;
204 d = XCreatePixmap(display, view->window, tw, th, scrPtr->depth);
205 XFillRectangle(display, d, WMColorGC(view->backColor), 0, 0, tw, th);
207 WMDrawString(scrPtr, d, scrPtr->black, font, 0, 0, fPtr->caption, tlen);
208 XCopyArea(display, d, view->window, scrPtr->copyGC, 0, 0, tw, th, tx, ty);
209 XFreePixmap(display, d);
210 #else
211 XClearArea(display, view->window, tx, ty, tw, th, False);
212 WMDrawString(scrPtr, view->window, scrPtr->black, font, tx, ty,
213 fPtr->caption, tlen);
214 #endif
215 } else {
216 WMDrawString(scrPtr, view->window, scrPtr->black, font, tx, ty,
217 fPtr->caption, tlen);
226 static void
227 handleEvents(XEvent *event, void *data)
229 Frame *fPtr = (Frame*)data;
231 CHECK_CLASS(data, WC_Frame);
233 switch (event->type) {
234 case Expose:
235 if (event->xexpose.count == 0)
236 paintFrame(fPtr);
237 break;
239 case DestroyNotify:
240 destroyFrame(fPtr);
241 break;
246 WMFrame*
247 WMCreateFrame(WMWidget *parent)
249 Frame *fPtr;
251 fPtr = wmalloc(sizeof(Frame));
252 memset(fPtr, 0, sizeof(Frame));
254 fPtr->widgetClass = WC_Frame;
256 fPtr->view = W_CreateView(W_VIEW(parent));
257 if (!fPtr->view) {
258 wfree(fPtr);
259 return NULL;
261 fPtr->view->self = fPtr;
263 WMCreateEventHandler(fPtr->view, ExposureMask|StructureNotifyMask,
264 handleEvents, fPtr);
267 fPtr->flags.relief = DEFAULT_RELIEF;
268 fPtr->flags.titlePosition = DEFAULT_TITLE_POSITION;
270 WMResizeWidget(fPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
272 return fPtr;
276 static void
277 destroyFrame(Frame *fPtr)
279 if (fPtr->caption)
280 wfree(fPtr->caption);
282 wfree(fPtr);