fixed redraw problem when frame title changes
[wmaker-crm.git] / WINGs / wframe.c
blob0f95ded602dbb3c3e98bea8824d6bd92a18e9fc8
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 int tx, ty, tw, th;
86 int fy, fh;
87 Bool drawTitle;
89 if (fPtr->caption!=NULL)
90 th = WMFontHeight(scrPtr->normalFont);
91 else {
92 th = 0;
95 fh = view->size.height;
96 fy = 0;
98 switch (fPtr->flags.titlePosition) {
99 case WTPAboveTop:
100 ty = 0;
101 fy = th + 4;
102 fh = view->size.height - fy;
103 break;
105 case WTPAtTop:
106 ty = 0;
107 fy = th/2;
108 fh = view->size.height - fy;
109 break;
111 case WTPBelowTop:
112 ty = 4;
113 fy = 0;
114 fh = view->size.height;
115 break;
117 case WTPAboveBottom:
118 ty = view->size.height - th - 4;
119 fy = 0;
120 fh = view->size.height;
121 break;
123 case WTPAtBottom:
124 ty = view->size.height - th;
125 fy = 0;
126 fh = view->size.height - th/2;
127 break;
129 case WTPBelowBottom:
130 ty = view->size.height - th;
131 fy = 0;
132 fh = view->size.height - th - 4;
133 break;
135 default:
136 ty = 0;
137 fy = 0;
138 fh = view->size.height;
141 if (fPtr->caption!=NULL && fPtr->flags.titlePosition!=WTPNoTitle) {
142 tw = WMWidthOfString(scrPtr->normalFont, fPtr->caption,
143 strlen(fPtr->caption));
145 tx = (view->size.width - tw) / 2;
147 drawTitle = True;
148 } else {
149 drawTitle = False;
153 XRectangle rect;
154 Region region, tmp;
155 GC gc[4];
156 int i;
158 region = XCreateRegion();
160 if (drawTitle) {
161 tmp = XCreateRegion();
162 rect.x = tx;
163 rect.y = ty;
164 rect.width = tw;
165 rect.height = th;
166 XUnionRectWithRegion(&rect, tmp, tmp);
168 rect.x = 0;
169 rect.y = 0;
170 rect.width = view->size.width;
171 rect.height = view->size.height;
172 XUnionRectWithRegion(&rect, region, region);
173 if (drawTitle) {
174 XSubtractRegion(region, tmp, region);
175 XDestroyRegion(tmp);
177 gc[0] = WMColorGC(scrPtr->black);
178 gc[1] = WMColorGC(scrPtr->darkGray);
179 gc[2] = WMColorGC(scrPtr->gray);
180 gc[3] = WMColorGC(scrPtr->white);
182 for (i = 0; i < 4; i++) {
183 XSetRegion(scrPtr->display, gc[i], region);
185 XDestroyRegion(region);
187 W_DrawReliefWithGC(scrPtr, view->window, 0, fy, view->size.width, fh,
188 fPtr->flags.relief, gc[0], gc[1], gc[2], gc[3]);
190 for (i = 0; i < 4; i++) {
191 XSetClipMask(scrPtr->display, gc[i], None);
195 if (drawTitle) {
196 WMDrawString(scrPtr, view->window, WMColorGC(scrPtr->black),
197 scrPtr->normalFont, tx, ty, fPtr->caption,
198 strlen(fPtr->caption));
206 static void
207 handleEvents(XEvent *event, void *data)
209 Frame *fPtr = (Frame*)data;
211 CHECK_CLASS(data, WC_Frame);
213 switch (event->type) {
214 case Expose:
215 if (event->xexpose.count == 0)
216 paintFrame(fPtr);
217 break;
219 case DestroyNotify:
220 destroyFrame(fPtr);
221 break;
226 WMFrame*
227 WMCreateFrame(WMWidget *parent)
229 Frame *fPtr;
231 fPtr = wmalloc(sizeof(Frame));
232 memset(fPtr, 0, sizeof(Frame));
234 fPtr->widgetClass = WC_Frame;
236 fPtr->view = W_CreateView(W_VIEW(parent));
237 if (!fPtr->view) {
238 wfree(fPtr);
239 return NULL;
241 fPtr->view->self = fPtr;
243 WMCreateEventHandler(fPtr->view, ExposureMask|StructureNotifyMask,
244 handleEvents, fPtr);
247 fPtr->flags.relief = DEFAULT_RELIEF;
248 fPtr->flags.titlePosition = DEFAULT_TITLE_POSITION;
250 WMResizeWidget(fPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
252 return fPtr;
256 static void
257 destroyFrame(Frame *fPtr)
259 if (fPtr->caption)
260 wfree(fPtr->caption);
262 wfree(fPtr);