Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wframe.c
1
2 #include "WINGsP.h"
3
4 typedef struct W_Frame {
5         W_Class widgetClass;
6         W_View *view;
7
8         char *caption;
9
10         struct {
11                 WMReliefType relief:4;
12                 WMTitlePosition titlePosition:4;
13         } flags;
14 } Frame;
15
16 #define DEFAULT_RELIEF  WRGroove
17 #define DEFAULT_TITLE_POSITION  WTPAtTop
18 #define DEFAULT_WIDTH           40
19 #define DEFAULT_HEIGHT          40
20
21 static void destroyFrame(Frame * fPtr);
22 static void paintFrame(Frame * fPtr);
23 static void repaintFrame(Frame * fPtr);
24
25 void WMSetFrameTitlePosition(WMFrame * fPtr, WMTitlePosition position)
26 {
27         fPtr->flags.titlePosition = position;
28
29         if (fPtr->view->flags.realized) {
30                 repaintFrame(fPtr);
31         }
32 }
33
34 void WMSetFrameRelief(WMFrame * fPtr, WMReliefType relief)
35 {
36         fPtr->flags.relief = relief;
37
38         if (fPtr->view->flags.realized) {
39                 repaintFrame(fPtr);
40         }
41 }
42
43 void WMSetFrameTitle(WMFrame * fPtr, char *title)
44 {
45         if (fPtr->caption)
46                 wfree(fPtr->caption);
47
48         if (title)
49                 fPtr->caption = wstrdup(title);
50         else
51                 fPtr->caption = NULL;
52
53         if (fPtr->view->flags.realized) {
54                 repaintFrame(fPtr);
55         }
56 }
57
58 static void repaintFrame(Frame * fPtr)
59 {
60         W_View *view = fPtr->view;
61         W_Screen *scrPtr = view->screen;
62
63         XClearWindow(scrPtr->display, view->window);
64         paintFrame(fPtr);
65 }
66
67 static void paintFrame(Frame * fPtr)
68 {
69         W_View *view = fPtr->view;
70         W_Screen *scrPtr = view->screen;
71         WMFont *font = scrPtr->normalFont;
72         Display *display = scrPtr->display;
73         int tx, ty, tw, th, tlen;
74         int fy, fh;
75         Bool drawTitle;
76
77         if (fPtr->caption != NULL) {
78                 th = WMFontHeight(font);
79                 tlen = strlen(fPtr->caption);
80         } else {
81                 th = 0;
82                 tlen = 0;
83         }
84
85         fh = view->size.height;
86         fy = 0;
87
88         switch (fPtr->flags.titlePosition) {
89         case WTPAboveTop:
90                 ty = 0;
91                 fy = th + 4;
92                 fh = view->size.height - fy;
93                 break;
94
95         case WTPAtTop:
96                 ty = 0;
97                 fy = th / 2;
98                 fh = view->size.height - fy;
99                 break;
100
101         case WTPBelowTop:
102                 ty = 4;
103                 fy = 0;
104                 fh = view->size.height;
105                 break;
106
107         case WTPAboveBottom:
108                 ty = view->size.height - th - 4;
109                 fy = 0;
110                 fh = view->size.height;
111                 break;
112
113         case WTPAtBottom:
114                 ty = view->size.height - th;
115                 fy = 0;
116                 fh = view->size.height - th / 2;
117                 break;
118
119         case WTPBelowBottom:
120                 ty = view->size.height - th;
121                 fy = 0;
122                 fh = view->size.height - th - 4;
123                 break;
124
125         default:
126                 ty = 0;
127                 fy = 0;
128                 fh = view->size.height;
129         }
130
131         if (tlen > 0 && fPtr->flags.titlePosition != WTPNoTitle) {
132                 tw = WMWidthOfString(font, fPtr->caption, tlen);
133
134                 tx = (view->size.width - tw) / 2;
135
136                 drawTitle = True;
137         } else {
138                 tw = tx = 0;
139                 drawTitle = False;
140         }
141
142         {
143                 XRectangle rect;
144                 Region region, tmp;
145                 GC gc[4];
146                 int i;
147
148                 region = XCreateRegion();
149
150                 rect.x = 0;
151                 rect.y = 0;
152                 rect.width = view->size.width;
153                 rect.height = view->size.height;
154                 XUnionRectWithRegion(&rect, region, region);
155                 if (drawTitle) {
156                         tmp = XCreateRegion();
157                         rect.x = tx;
158                         rect.y = ty;
159                         rect.width = tw;
160                         rect.height = th;
161                         XUnionRectWithRegion(&rect, tmp, tmp);
162                         XSubtractRegion(region, tmp, region);
163                         XDestroyRegion(tmp);
164                 }
165                 gc[0] = WMColorGC(scrPtr->black);
166                 gc[1] = WMColorGC(scrPtr->darkGray);
167                 gc[2] = WMColorGC(scrPtr->gray);
168                 gc[3] = WMColorGC(scrPtr->white);
169
170                 for (i = 0; i < 4; i++) {
171                         XSetRegion(display, gc[i], region);
172                 }
173                 XDestroyRegion(region);
174
175                 W_DrawReliefWithGC(scrPtr, view->window, 0, fy, view->size.width, fh,
176                                    fPtr->flags.relief, gc[0], gc[1], gc[2], gc[3]);
177
178                 for (i = 0; i < 4; i++) {
179                         XSetClipMask(display, gc[i], None);
180                 }
181         }
182
183         if (drawTitle) {
184                 /* can't draw AA text over and over again because it gets messed */
185                 /* // TODO create the dbl buffer pixmap when create/set frame title */
186                 if (scrPtr->antialiasedText) {
187                         Drawable d;
188
189                         d = XCreatePixmap(display, view->window, tw, th, scrPtr->depth);
190                         XFillRectangle(display, d, WMColorGC(view->backColor), 0, 0, tw, th);
191
192                         WMDrawString(scrPtr, d, scrPtr->black, font, 0, 0, fPtr->caption, tlen);
193                         XCopyArea(display, d, view->window, scrPtr->copyGC, 0, 0, tw, th, tx, ty);
194                         XFreePixmap(display, d);
195                 } else {
196                         WMDrawString(scrPtr, view->window, scrPtr->black, font, tx, ty, fPtr->caption, tlen);
197                 }
198         }
199 }
200
201 static void handleEvents(XEvent * event, void *data)
202 {
203         Frame *fPtr = (Frame *) data;
204
205         CHECK_CLASS(data, WC_Frame);
206
207         switch (event->type) {
208         case Expose:
209                 if (event->xexpose.count == 0)
210                         paintFrame(fPtr);
211                 break;
212
213         case DestroyNotify:
214                 destroyFrame(fPtr);
215                 break;
216         }
217 }
218
219 WMFrame *WMCreateFrame(WMWidget * parent)
220 {
221         Frame *fPtr;
222
223         fPtr = wmalloc(sizeof(Frame));
224         memset(fPtr, 0, sizeof(Frame));
225
226         fPtr->widgetClass = WC_Frame;
227
228         fPtr->view = W_CreateView(W_VIEW(parent));
229         if (!fPtr->view) {
230                 wfree(fPtr);
231                 return NULL;
232         }
233         fPtr->view->self = fPtr;
234
235         WMCreateEventHandler(fPtr->view, ExposureMask | StructureNotifyMask, handleEvents, fPtr);
236
237         fPtr->flags.relief = DEFAULT_RELIEF;
238         fPtr->flags.titlePosition = DEFAULT_TITLE_POSITION;
239
240         WMResizeWidget(fPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
241
242         return fPtr;
243 }
244
245 static void destroyFrame(Frame * fPtr)
246 {
247         if (fPtr->caption)
248                 wfree(fPtr->caption);
249
250         wfree(fPtr);
251 }