new style
[wmaker-crm.git] / WINGs / wbox.c
blob32318e5c9148d47bc4a25aba93e3775be6bf5339
3 #include "WINGsP.h"
6 typedef struct {
7 WMView *view;
8 int minSize;
9 int maxSize;
10 int space;
11 unsigned expand:1;
12 unsigned fill:1;
13 unsigned end:1;
14 } SubviewItem;
17 typedef struct W_Box {
18 W_Class widgetClass;
19 W_View *view;
21 SubviewItem *subviews;
22 int subviewCount;
24 short borderWidth;
26 unsigned horizontal:1;
27 } Box;
30 #define DEFAULT_WIDTH 40
31 #define DEFAULT_HEIGHT 40
34 static void destroyBox(Box *bPtr);
36 static void handleEvents(XEvent *event, void *data);
38 static void didResize(struct W_ViewDelegate*, WMView*);
40 static W_ViewDelegate delegate = {
41 NULL,
42 NULL,
43 didResize,
44 NULL,
45 NULL
50 WMBox*
51 WMCreateBox(WMWidget *parent)
53 Box *bPtr;
55 bPtr = wmalloc(sizeof(Box));
56 memset(bPtr, 0, sizeof(Box));
58 bPtr->widgetClass = WC_Box;
60 bPtr->view = W_CreateView(W_VIEW(parent));
61 if (!bPtr->view) {
62 wfree(bPtr);
63 return NULL;
65 bPtr->view->self = bPtr;
67 bPtr->view->delegate = &delegate;
69 WMCreateEventHandler(bPtr->view, StructureNotifyMask,
70 handleEvents, bPtr);
72 WMResizeWidget(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
74 bPtr->subviews = NULL;
75 bPtr->subviewCount = 0;
77 return bPtr;
81 static void
82 rearrange(WMBox *box)
84 int i;
85 int x, y;
86 int xe, ye;
87 int w = 1, h = 1;
88 int total;
89 int expands = 0;
91 x = box->borderWidth;
92 y = box->borderWidth;
94 if (box->horizontal) {
95 ye = box->borderWidth;
96 xe = WMWidgetWidth(box) - box->borderWidth;
97 h = WMWidgetHeight(box) - 2 * box->borderWidth;
98 total = WMWidgetWidth(box) - 2 * box->borderWidth;
99 } else {
100 xe = box->borderWidth;
101 ye = WMWidgetHeight(box) - box->borderWidth;
102 w = WMWidgetWidth(box) - 2 * box->borderWidth;
103 total = WMWidgetHeight(box) - 2 * box->borderWidth;
106 if (w <= 0 || h <= 0 || total <= 0) {
107 return;
110 for (i = 0; i < box->subviewCount; i++) {
111 total -= box->subviews[i].minSize;
112 total -= box->subviews[i].space;
113 if (box->subviews[i].expand) {
114 expands++;
118 for (i = 0; i < box->subviewCount; i++) {
119 if (box->horizontal) {
120 w = box->subviews[i].minSize;
121 if (box->subviews[i].expand)
122 w += total/expands;
123 } else {
124 h = box->subviews[i].minSize;
125 if (box->subviews[i].expand)
126 h += total/expands;
128 if (!box->subviews[i].end) {
129 W_MoveView(box->subviews[i].view, x, y);
131 W_ResizeView(box->subviews[i].view, w, h);
132 if (box->horizontal) {
133 if (box->subviews[i].end)
134 xe -= w + box->subviews[i].space;
135 else
136 x += w + box->subviews[i].space;
137 } else {
138 if (box->subviews[i].end)
139 ye -= h + box->subviews[i].space;
140 else
141 y += h + box->subviews[i].space;
143 if (box->subviews[i].end) {
144 W_MoveView(box->subviews[i].view, xe, ye);
150 void
151 WMSetBoxBorderWidth(WMBox *box, unsigned width)
153 box->borderWidth = width;
155 rearrange(box);
159 void
160 WMAddBoxSubview(WMBox *bPtr, WMView *view, Bool expand, Bool fill,
161 int minSize, int maxSize, int space)
163 int i = bPtr->subviewCount;
165 bPtr->subviewCount++;
166 if (!bPtr->subviews)
167 bPtr->subviews = wmalloc(sizeof(SubviewItem));
168 else
169 bPtr->subviews = wrealloc(bPtr->subviews,
170 bPtr->subviewCount*sizeof(SubviewItem));
171 bPtr->subviews[i].view = view;
172 bPtr->subviews[i].minSize = minSize;
173 bPtr->subviews[i].maxSize = maxSize;
174 bPtr->subviews[i].expand = expand;
175 bPtr->subviews[i].fill = fill;
176 bPtr->subviews[i].space = space;
177 bPtr->subviews[i].end = 0;
179 rearrange(bPtr);
184 void
185 WMAddBoxSubviewAtEnd(WMBox *bPtr, WMView *view, Bool expand, Bool fill,
186 int minSize, int maxSize, int space)
188 int i = bPtr->subviewCount;
190 bPtr->subviewCount++;
191 if (!bPtr->subviews)
192 bPtr->subviews = wmalloc(sizeof(SubviewItem));
193 else
194 bPtr->subviews = wrealloc(bPtr->subviews,
195 bPtr->subviewCount*sizeof(SubviewItem));
196 bPtr->subviews[i].view = view;
197 bPtr->subviews[i].minSize = minSize;
198 bPtr->subviews[i].maxSize = maxSize;
199 bPtr->subviews[i].expand = expand;
200 bPtr->subviews[i].fill = fill;
201 bPtr->subviews[i].space = space;
202 bPtr->subviews[i].end = 1;
204 rearrange(bPtr);
208 void
209 WMSetBoxHorizontal(WMBox *box, Bool flag)
211 box->horizontal = flag;
212 rearrange(box);
216 static void
217 destroyBox(Box *bPtr)
219 wfree(bPtr);
223 static void
224 didResize(struct W_ViewDelegate *delegate, WMView *view)
226 rearrange(view->self);
229 static void
230 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;