14 typedef struct W_Box {
22 unsigned horizontal:1;
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 = {
42 WMBox *WMCreateBox(WMWidget * parent)
46 bPtr = wmalloc(sizeof(Box));
47 memset(bPtr, 0, sizeof(Box));
49 bPtr->widgetClass = WC_Box;
51 bPtr->view = W_CreateView(W_VIEW(parent));
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);
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;
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;
98 eData->w += eData->total / eData->expands;
100 eData->h = item->minSize;
102 eData->h += eData->total / eData->expands;
105 W_MoveView(item->view, eData->x, eData->y);
107 W_ResizeView(item->view, eData->w, eData->h);
108 if (eData->box->horizontal) {
110 eData->xe -= eData->w + item->space;
112 eData->x += eData->w + item->space;
115 eData->ye -= eData->h + item->space;
117 eData->y += eData->h + item->space;
120 W_MoveView(item->view, eData->xe, eData->ye);
124 static void rearrange(WMBox * box)
129 eData.x = eData.y = box->borderWidth;
130 eData.w = eData.h = 1;
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;
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) {
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;
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;
174 WMAddToArray(bPtr->subviews, subView);
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;
192 WMAddToArray(bPtr->subviews, subView);
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)) {
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;
219 static void destroyBox(Box * bPtr)
221 WMFreeArray(bPtr->subviews);
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) {
241 case ConfigureNotify: