Change to the linux kernel coding style
[wmaker-crm.git] / WINGs / wbox.c
blobb5ee1bc88e54d335fcf57e4ff7bd4afc7f095aad
2 #include "WINGsP.h"
4 typedef struct {
5 WMView *view;
6 int minSize;
7 int maxSize;
8 int space;
9 unsigned expand:1;
10 unsigned fill:1;
11 unsigned end:1;
12 } SubviewItem;
14 typedef struct W_Box {
15 W_Class widgetClass;
16 W_View *view;
18 WMArray *subviews;
20 short borderWidth;
22 unsigned horizontal:1;
23 } Box;
25 #define DEFAULT_WIDTH 40
26 #define DEFAULT_HEIGHT 40
28 static void destroyBox(Box * bPtr);
30 static void handleEvents(XEvent * event, void *data);
32 static void didResize(struct W_ViewDelegate *, WMView *);
34 static W_ViewDelegate delegate = {
35 NULL,
36 NULL,
37 didResize,
38 NULL,
39 NULL
42 WMBox *WMCreateBox(WMWidget * parent)
44 Box *bPtr;
46 bPtr = wmalloc(sizeof(Box));
47 memset(bPtr, 0, sizeof(Box));
49 bPtr->widgetClass = WC_Box;
51 bPtr->view = W_CreateView(W_VIEW(parent));
52 if (!bPtr->view) {
53 wfree(bPtr);
54 return NULL;
56 bPtr->view->self = bPtr;
58 bPtr->view->delegate = &delegate;
60 bPtr->subviews = WMCreateArrayWithDestructor(2, wfree);
62 WMCreateEventHandler(bPtr->view, StructureNotifyMask, handleEvents, bPtr);
64 WMResizeWidget(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
66 return bPtr;
69 typedef struct {
70 WMBox *box;
71 int total;
72 int expands;
73 int x, y;
74 int xe, ye;
75 int w, h;
76 } BoxData;
78 static void computeExpansion(void *object, void *cdata)
80 SubviewItem *item = (SubviewItem *) object;
81 BoxData *eData = (BoxData *) cdata;
83 eData->total -= item->minSize;
84 eData->total -= item->space;
85 if (item->expand) {
86 eData->expands++;
90 static void doRearrange(void *object, void *cdata)
92 SubviewItem *item = (SubviewItem *) object;
93 BoxData *eData = (BoxData *) cdata;
95 if (eData->box->horizontal) {
96 eData->w = item->minSize;
97 if (item->expand)
98 eData->w += eData->total / eData->expands;
99 } else {
100 eData->h = item->minSize;
101 if (item->expand)
102 eData->h += eData->total / eData->expands;
104 if (!item->end) {
105 W_MoveView(item->view, eData->x, eData->y);
107 W_ResizeView(item->view, eData->w, eData->h);
108 if (eData->box->horizontal) {
109 if (item->end)
110 eData->xe -= eData->w + item->space;
111 else
112 eData->x += eData->w + item->space;
113 } else {
114 if (item->end)
115 eData->ye -= eData->h + item->space;
116 else
117 eData->y += eData->h + item->space;
119 if (item->end) {
120 W_MoveView(item->view, eData->xe, eData->ye);
124 static void rearrange(WMBox * box)
126 BoxData eData;
128 eData.box = box;
129 eData.x = eData.y = box->borderWidth;
130 eData.w = eData.h = 1;
131 eData.expands = 0;
133 if (box->horizontal) {
134 eData.ye = box->borderWidth;
135 eData.xe = WMWidgetWidth(box) - box->borderWidth;
136 eData.h = WMWidgetHeight(box) - 2 * box->borderWidth;
137 eData.total = WMWidgetWidth(box) - 2 * box->borderWidth;
138 } else {
139 eData.xe = box->borderWidth;
140 eData.ye = WMWidgetHeight(box) - box->borderWidth;
141 eData.w = WMWidgetWidth(box) - 2 * box->borderWidth;
142 eData.total = WMWidgetHeight(box) - 2 * box->borderWidth;
145 if (eData.w <= 0 || eData.h <= 0 || eData.total <= 0) {
146 return;
149 WMMapArray(box->subviews, computeExpansion, &eData);
150 WMMapArray(box->subviews, doRearrange, &eData);
153 void WMSetBoxBorderWidth(WMBox * box, unsigned width)
155 if (box->borderWidth != width) {
156 box->borderWidth = width;
157 rearrange(box);
161 void WMAddBoxSubview(WMBox * bPtr, WMView * view, Bool expand, Bool fill, int minSize, int maxSize, int space)
163 SubviewItem *subView;
165 subView = wmalloc(sizeof(SubviewItem));
166 subView->view = view;
167 subView->minSize = minSize;
168 subView->maxSize = maxSize;
169 subView->expand = expand;
170 subView->fill = fill;
171 subView->space = space;
172 subView->end = 0;
174 WMAddToArray(bPtr->subviews, subView);
176 rearrange(bPtr);
179 void WMAddBoxSubviewAtEnd(WMBox * bPtr, WMView * view, Bool expand, Bool fill, int minSize, int maxSize, int space)
181 SubviewItem *subView;
183 subView = wmalloc(sizeof(SubviewItem));
184 subView->view = view;
185 subView->minSize = minSize;
186 subView->maxSize = maxSize;
187 subView->expand = expand;
188 subView->fill = fill;
189 subView->space = space;
190 subView->end = 1;
192 WMAddToArray(bPtr->subviews, subView);
194 rearrange(bPtr);
197 static int matchView(void *item, void *cdata)
199 return (((SubviewItem *) item)->view == (WMView *) cdata);
202 void WMRemoveBoxSubview(WMBox * bPtr, WMView * view)
204 if (WMRemoveFromArrayMatching(bPtr->subviews, matchView, view)) {
205 rearrange(bPtr);
209 void WMSetBoxHorizontal(WMBox * box, Bool flag)
211 /* make sure flag is either 0 or 1 no matter what true value was passed */
212 flag = ((flag == 0) ? 0 : 1);
213 if (box->horizontal != flag) {
214 box->horizontal = flag;
215 rearrange(box);
219 static void destroyBox(Box * bPtr)
221 WMFreeArray(bPtr->subviews);
222 wfree(bPtr);
225 static void didResize(struct W_ViewDelegate *delegate, WMView * view)
227 rearrange(view->self);
230 static void handleEvents(XEvent * event, void *data)
232 Box *bPtr = (Box *) data;
234 CHECK_CLASS(data, WC_Box);
236 switch (event->type) {
237 case DestroyNotify:
238 destroyBox(bPtr);
239 break;
241 case ConfigureNotify:
242 rearrange(bPtr);
243 break;