*** empty log message ***
[wmaker-crm.git] / WINGs / wbox.c
blobc65941b662ae813597112d23458a55f882511a01
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
35 static void destroyBox(Box *bPtr);
37 static void handleEvents(XEvent *event, void *data);
39 static void didResize(struct W_ViewDelegate*, WMView*);
41 static W_ViewDelegate delegate = {
42 NULL,
43 NULL,
44 didResize,
45 NULL,
46 NULL
52 static void resizedParent(void *self, WMNotification *notif)
54 WMView *view = (WMView*)WMGetNotificationObject(notif);
55 WMSize size = WMGetViewSize(view);
57 WMResizeWidget((WMWidget*)self, size.width, size.height);
61 WMBox*
62 WMCreateBox(WMWidget *parent)
64 Box *bPtr;
66 bPtr = wmalloc(sizeof(Box));
67 memset(bPtr, 0, sizeof(Box));
69 bPtr->widgetClass = WC_Box;
71 bPtr->view = W_CreateView(W_VIEW(parent));
72 if (!bPtr->view) {
73 wfree(bPtr);
74 return NULL;
76 bPtr->view->self = bPtr;
78 bPtr->view->delegate = &delegate;
80 WMCreateEventHandler(bPtr->view, StructureNotifyMask,
81 handleEvents, bPtr);
83 WMResizeWidget(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
85 bPtr->subviews = NULL;
86 bPtr->subviewCount = 0;
88 return bPtr;
92 static void
93 rearrange(WMBox *box)
95 int i;
96 int x, y;
97 int xe, ye;
98 int w = 1, h = 1;
99 int total;
100 int expands = 0;
102 x = box->borderWidth;
103 y = box->borderWidth;
105 if (box->horizontal) {
106 ye = box->borderWidth;
107 xe = WMWidgetWidth(box) - box->borderWidth;
108 h = WMWidgetHeight(box) - 2 * box->borderWidth;
109 total = WMWidgetWidth(box) - 2 * box->borderWidth;
110 } else {
111 xe = box->borderWidth;
112 ye = WMWidgetHeight(box) - box->borderWidth;
113 w = WMWidgetWidth(box) - 2 * box->borderWidth;
114 total = WMWidgetHeight(box) - 2 * box->borderWidth;
117 if (w <= 0 || h <= 0 || total <= 0) {
118 return;
121 for (i = 0; i < box->subviewCount; i++) {
122 total -= box->subviews[i].minSize;
123 total -= box->subviews[i].space;
124 if (box->subviews[i].expand) {
125 expands++;
129 for (i = 0; i < box->subviewCount; i++) {
130 if (box->horizontal) {
131 w = box->subviews[i].minSize;
132 if (box->subviews[i].expand)
133 w += total/expands;
134 } else {
135 h = box->subviews[i].minSize;
136 if (box->subviews[i].expand)
137 h += total/expands;
139 if (!box->subviews[i].end) {
140 W_MoveView(box->subviews[i].view, x, y);
142 W_ResizeView(box->subviews[i].view, w, h);
143 if (box->horizontal) {
144 if (box->subviews[i].end)
145 xe -= w + box->subviews[i].space;
146 else
147 x += w + box->subviews[i].space;
148 } else {
149 if (box->subviews[i].end)
150 ye -= h + box->subviews[i].space;
151 else
152 y += h + box->subviews[i].space;
154 if (box->subviews[i].end) {
155 W_MoveView(box->subviews[i].view, xe, ye);
161 void
162 WMSetBoxBorderWidth(WMBox *box, unsigned width)
164 box->borderWidth = width;
166 rearrange(box);
170 void
171 WMAddBoxSubview(WMBox *bPtr, WMView *view, Bool expand, Bool fill,
172 int minSize, int maxSize, int space)
174 int i = bPtr->subviewCount;
176 bPtr->subviewCount++;
177 if (!bPtr->subviews)
178 bPtr->subviews = wmalloc(sizeof(SubviewItem));
179 else
180 bPtr->subviews = wrealloc(bPtr->subviews,
181 bPtr->subviewCount*sizeof(SubviewItem));
182 bPtr->subviews[i].view = view;
183 bPtr->subviews[i].minSize = minSize;
184 bPtr->subviews[i].maxSize = maxSize;
185 bPtr->subviews[i].expand = expand;
186 bPtr->subviews[i].fill = fill;
187 bPtr->subviews[i].space = space;
188 bPtr->subviews[i].end = 0;
190 rearrange(bPtr);
195 void
196 WMAddBoxSubviewAtEnd(WMBox *bPtr, WMView *view, Bool expand, Bool fill,
197 int minSize, int maxSize, int space)
199 int i = bPtr->subviewCount;
201 bPtr->subviewCount++;
202 if (!bPtr->subviews)
203 bPtr->subviews = wmalloc(sizeof(SubviewItem));
204 else
205 bPtr->subviews = wrealloc(bPtr->subviews,
206 bPtr->subviewCount*sizeof(SubviewItem));
207 bPtr->subviews[i].view = view;
208 bPtr->subviews[i].minSize = minSize;
209 bPtr->subviews[i].maxSize = maxSize;
210 bPtr->subviews[i].expand = expand;
211 bPtr->subviews[i].fill = fill;
212 bPtr->subviews[i].space = space;
213 bPtr->subviews[i].end = 1;
215 rearrange(bPtr);
219 void
220 WMRemoveBoxSubview(WMBox *bPtr, WMView *view)
222 int i;
224 for (i = 0; i < bPtr->subviewCount; i++) {
225 if (bPtr->subviews[i].view == view) {
226 memmove(&bPtr->subviews[i], &bPtr->subviews[i+1],
227 (bPtr->subviewCount - i - 1) * sizeof(void*));
228 bPtr->subviewCount--;
229 break;
232 rearrange(bPtr);
236 void
237 WMSetBoxHorizontal(WMBox *box, Bool flag)
239 box->horizontal = flag;
240 rearrange(box);
244 void
245 WMSetBoxExpandsToParent(WMBox *box)
247 WMSize size = W_VIEW(box)->parent->size;
249 WMAddNotificationObserver(resizedParent, box,
250 WMViewSizeDidChangeNotification,
251 W_VIEW(box)->parent);
252 WMSetViewNotifySizeChanges(W_VIEW(box)->parent, True);
254 WMResizeWidget(box, size.width, size.height);
258 static void
259 destroyBox(Box *bPtr)
261 WMRemoveNotificationObserver(bPtr);
262 wfree(bPtr);
266 static void
267 didResize(struct W_ViewDelegate *delegate, WMView *view)
269 rearrange(view->self);
273 static void
274 handleEvents(XEvent *event, void *data)
276 Box *bPtr = (Box*)data;
278 CHECK_CLASS(data, WC_Box);
280 switch (event->type) {
281 case DestroyNotify:
282 destroyBox(bPtr);
283 break;
285 case ConfigureNotify:
286 rearrange(bPtr);
287 break;