WINGs: Added 'const' attribute to function 'WMCreateHashTable'
[wmaker-crm.git] / WINGs / wbox.c
blob8eff6ca795640d06131015522b8e57044183ceb5
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));
48 bPtr->widgetClass = WC_Box;
50 bPtr->view = W_CreateView(W_VIEW(parent));
51 if (!bPtr->view) {
52 wfree(bPtr);
53 return NULL;
55 bPtr->view->self = bPtr;
57 bPtr->view->delegate = &delegate;
59 bPtr->subviews = WMCreateArrayWithDestructor(2, wfree);
61 WMCreateEventHandler(bPtr->view, StructureNotifyMask, handleEvents, bPtr);
63 WMResizeWidget(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
65 return bPtr;
68 typedef struct {
69 WMBox *box;
70 int total;
71 int expands;
72 int x, y;
73 int xe, ye;
74 int w, h;
75 } BoxData;
77 static void computeExpansion(void *object, void *cdata)
79 SubviewItem *item = (SubviewItem *) object;
80 BoxData *eData = (BoxData *) cdata;
82 eData->total -= item->minSize;
83 eData->total -= item->space;
84 if (item->expand) {
85 eData->expands++;
89 static void doRearrange(void *object, void *cdata)
91 SubviewItem *item = (SubviewItem *) object;
92 BoxData *eData = (BoxData *) cdata;
94 if (eData->box->horizontal) {
95 eData->w = item->minSize;
96 if (item->expand)
97 eData->w += eData->total / eData->expands;
98 } else {
99 eData->h = item->minSize;
100 if (item->expand)
101 eData->h += eData->total / eData->expands;
103 if (!item->end) {
104 W_MoveView(item->view, eData->x, eData->y);
106 W_ResizeView(item->view, eData->w, eData->h);
107 if (eData->box->horizontal) {
108 if (item->end)
109 eData->xe -= eData->w + item->space;
110 else
111 eData->x += eData->w + item->space;
112 } else {
113 if (item->end)
114 eData->ye -= eData->h + item->space;
115 else
116 eData->y += eData->h + item->space;
118 if (item->end) {
119 W_MoveView(item->view, eData->xe, eData->ye);
123 static void rearrange(WMBox * box)
125 BoxData eData;
127 eData.box = box;
128 eData.x = eData.y = box->borderWidth;
129 eData.w = eData.h = 1;
130 eData.expands = 0;
132 if (box->horizontal) {
133 eData.ye = box->borderWidth;
134 eData.xe = WMWidgetWidth(box) - box->borderWidth;
135 eData.h = WMWidgetHeight(box) - 2 * box->borderWidth;
136 eData.total = WMWidgetWidth(box) - 2 * box->borderWidth;
137 } else {
138 eData.xe = box->borderWidth;
139 eData.ye = WMWidgetHeight(box) - box->borderWidth;
140 eData.w = WMWidgetWidth(box) - 2 * box->borderWidth;
141 eData.total = WMWidgetHeight(box) - 2 * box->borderWidth;
144 if (eData.w <= 0 || eData.h <= 0 || eData.total <= 0) {
145 return;
148 WMMapArray(box->subviews, computeExpansion, &eData);
149 WMMapArray(box->subviews, doRearrange, &eData);
152 void WMSetBoxBorderWidth(WMBox * box, unsigned width)
154 if (box->borderWidth != width) {
155 box->borderWidth = width;
156 rearrange(box);
160 void WMAddBoxSubview(WMBox * bPtr, WMView * view, Bool expand, Bool fill, int minSize, int maxSize, int space)
162 SubviewItem *subView;
164 subView = wmalloc(sizeof(SubviewItem));
165 subView->view = view;
166 subView->minSize = minSize;
167 subView->maxSize = maxSize;
168 subView->expand = expand;
169 subView->fill = fill;
170 subView->space = space;
171 subView->end = 0;
173 WMAddToArray(bPtr->subviews, subView);
175 rearrange(bPtr);
178 void WMAddBoxSubviewAtEnd(WMBox * bPtr, WMView * view, Bool expand, Bool fill, int minSize, int maxSize, int space)
180 SubviewItem *subView;
182 subView = wmalloc(sizeof(SubviewItem));
183 subView->view = view;
184 subView->minSize = minSize;
185 subView->maxSize = maxSize;
186 subView->expand = expand;
187 subView->fill = fill;
188 subView->space = space;
189 subView->end = 1;
191 WMAddToArray(bPtr->subviews, subView);
193 rearrange(bPtr);
196 static int matchView(const void *item, const void *cdata)
198 return (((SubviewItem *) item)->view == (WMView *) cdata);
201 void WMRemoveBoxSubview(WMBox * bPtr, WMView * view)
203 if (WMRemoveFromArrayMatching(bPtr->subviews, matchView, view)) {
204 rearrange(bPtr);
208 void WMSetBoxHorizontal(WMBox * box, Bool flag)
210 /* make sure flag is either 0 or 1 no matter what true value was passed */
211 flag = ((flag == 0) ? 0 : 1);
212 if (box->horizontal != flag) {
213 box->horizontal = flag;
214 rearrange(box);
218 static void destroyBox(Box * bPtr)
220 WMFreeArray(bPtr->subviews);
221 wfree(bPtr);
224 static void didResize(struct W_ViewDelegate *delegate, WMView * view)
226 /* Parameter not used, but tell the compiler that it is ok */
227 (void) delegate;
229 rearrange(view->self);
232 static void handleEvents(XEvent * event, void *data)
234 Box *bPtr = (Box *) data;
236 CHECK_CLASS(data, WC_Box);
238 switch (event->type) {
239 case DestroyNotify:
240 destroyBox(bPtr);
241 break;
243 case ConfigureNotify:
244 rearrange(bPtr);
245 break;