fixed bugs of resized widgets
[wmaker-crm.git] / WINGs / wbox.c
blobe6bde7ea89b16f9dde93df3c3babe5a56075bcd9
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 } SubviewItem;
16 typedef struct W_Box {
17 W_Class widgetClass;
18 W_View *view;
20 SubviewItem *subviews;
21 int subviewCount;
23 short borderWidth;
25 unsigned horizontal:1;
26 } Box;
29 #define DEFAULT_WIDTH 40
30 #define DEFAULT_HEIGHT 40
33 static void destroyBox(Box *bPtr);
35 static void handleEvents(XEvent *event, void *data);
37 static void didResize(struct W_ViewDelegate*, WMView*);
39 static W_ViewDelegate delegate = {
40 NULL,
41 NULL,
42 didResize,
43 NULL,
44 NULL
49 WMBox*
50 WMCreateBox(WMWidget *parent)
52 Box *bPtr;
54 bPtr = wmalloc(sizeof(Box));
55 memset(bPtr, 0, sizeof(Box));
57 bPtr->widgetClass = WC_Box;
59 bPtr->view = W_CreateView(W_VIEW(parent));
60 if (!bPtr->view) {
61 wfree(bPtr);
62 return NULL;
64 bPtr->view->self = bPtr;
66 bPtr->view->delegate = &delegate;
68 WMCreateEventHandler(bPtr->view, StructureNotifyMask,
69 handleEvents, bPtr);
71 WMResizeWidget(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
73 bPtr->subviews = NULL;
74 bPtr->subviewCount = 0;
76 return bPtr;
80 static void
81 rearrange(WMBox *box)
83 int i;
84 int x, y;
85 int w = 1, h = 1;
86 int total;
87 int expands = 0;
89 x = box->borderWidth;
90 y = box->borderWidth;
91 if (box->horizontal) {
92 h = WMWidgetHeight(box) - 2 * box->borderWidth;
93 total = WMWidgetWidth(box) - 2 * box->borderWidth;
94 } else {
95 w = WMWidgetWidth(box) - 2 * box->borderWidth;
96 total = WMWidgetHeight(box) - 2 * box->borderWidth;
99 if (w <= 0 || h <= 0 || total <= 0) {
100 return;
103 for (i = 0; i < box->subviewCount; i++) {
104 total -= box->subviews[i].minSize;
105 total -= box->subviews[i].space;
106 if (box->subviews[i].expand) {
107 expands++;
111 for (i = 0; i < box->subviewCount; i++) {
112 if (box->horizontal) {
113 w = box->subviews[i].minSize;
114 if (box->subviews[i].expand)
115 w += total/expands;
116 } else {
117 h = box->subviews[i].minSize;
118 if (box->subviews[i].expand)
119 h += total/expands;
121 W_MoveView(box->subviews[i].view, x, y);
122 W_ResizeView(box->subviews[i].view, w, h);
123 if (box->horizontal) {
124 x += w + box->subviews[i].space;
125 } else {
126 y += h + box->subviews[i].space;
132 void
133 WMSetBoxBorderWidth(WMBox *box, unsigned width)
135 box->borderWidth = width;
137 rearrange(box);
141 void
142 WMAddBoxSubview(WMBox *bPtr, WMView *view, Bool expand, Bool fill,
143 int minSize, int maxSize, int space)
145 int i = bPtr->subviewCount;
147 bPtr->subviewCount++;
148 if (!bPtr->subviews)
149 bPtr->subviews = wmalloc(sizeof(SubviewItem));
150 else
151 bPtr->subviews = wrealloc(bPtr->subviews,
152 bPtr->subviewCount*sizeof(SubviewItem));
153 bPtr->subviews[i].view = view;
154 bPtr->subviews[i].minSize = minSize;
155 bPtr->subviews[i].maxSize = maxSize;
156 bPtr->subviews[i].expand = expand;
157 bPtr->subviews[i].fill = fill;
158 bPtr->subviews[i].space = space;
160 rearrange(bPtr);
164 void
165 WMSetBoxHorizontal(WMBox *box, Bool flag)
167 box->horizontal = flag;
168 rearrange(box);
172 static void
173 destroyBox(Box *bPtr)
175 wfree(bPtr);
179 static void
180 didResize(struct W_ViewDelegate *delegate, WMView *view)
182 rearrange(view->self);
185 static void
186 handleEvents(XEvent *event, void *data)
188 Box *bPtr = (Box*)data;
190 CHECK_CLASS(data, WC_Box);
192 switch (event->type) {
193 case DestroyNotify:
194 destroyBox(bPtr);
195 break;
197 case ConfigureNotify:
198 rearrange(bPtr);
199 break;