17 typedef struct W_Box
{
25 unsigned horizontal
:1;
29 #define DEFAULT_WIDTH 40
30 #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
= {
52 WMCreateBox(WMWidget
*parent
)
56 bPtr
= wmalloc(sizeof(Box
));
57 memset(bPtr
, 0, sizeof(Box
));
59 bPtr
->widgetClass
= WC_Box
;
61 bPtr
->view
= W_CreateView(W_VIEW(parent
));
66 bPtr
->view
->self
= bPtr
;
68 bPtr
->view
->delegate
= &delegate
;
70 bPtr
->subviews
= WMCreateArrayWithDestructor(2, wfree
);
72 WMCreateEventHandler(bPtr
->view
, StructureNotifyMask
,
75 WMResizeWidget(bPtr
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
92 computeExpansion(void *object
, void *cdata
)
94 SubviewItem
*item
= (SubviewItem
*)object
;
95 BoxData
*eData
= (BoxData
*)cdata
;
97 eData
->total
-= item
->minSize
;
98 eData
->total
-= item
->space
;
106 doRearrange(void *object
, void *cdata
)
108 SubviewItem
*item
= (SubviewItem
*)object
;
109 BoxData
*eData
= (BoxData
*)cdata
;
111 if (eData
->box
->horizontal
) {
112 eData
->w
= item
->minSize
;
114 eData
->w
+= eData
->total
/eData
->expands
;
116 eData
->h
= item
->minSize
;
118 eData
->h
+= eData
->total
/eData
->expands
;
121 W_MoveView(item
->view
, eData
->x
, eData
->y
);
123 W_ResizeView(item
->view
, eData
->w
, eData
->h
);
124 if (eData
->box
->horizontal
) {
126 eData
->xe
-= eData
->w
+ item
->space
;
128 eData
->x
+= eData
->w
+ item
->space
;
131 eData
->ye
-= eData
->h
+ item
->space
;
133 eData
->y
+= eData
->h
+ item
->space
;
136 W_MoveView(item
->view
, eData
->xe
, eData
->ye
);
142 rearrange(WMBox
*box
)
147 eData
.x
= eData
.y
= box
->borderWidth
;
148 eData
.w
= eData
.h
= 1;
151 if (box
->horizontal
) {
152 eData
.ye
= box
->borderWidth
;
153 eData
.xe
= WMWidgetWidth(box
) - box
->borderWidth
;
154 eData
.h
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
155 eData
.total
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
157 eData
.xe
= box
->borderWidth
;
158 eData
.ye
= WMWidgetHeight(box
) - box
->borderWidth
;
159 eData
.w
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
160 eData
.total
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
163 if (eData
.w
<= 0 || eData
.h
<= 0 || eData
.total
<= 0) {
167 WMMapArray(box
->subviews
, computeExpansion
, &eData
);
168 WMMapArray(box
->subviews
, doRearrange
, &eData
);
173 WMSetBoxBorderWidth(WMBox
*box
, unsigned width
)
175 if (box
->borderWidth
!= width
) {
176 box
->borderWidth
= width
;
183 WMAddBoxSubview(WMBox
*bPtr
, WMView
*view
, Bool expand
, Bool fill
,
184 int minSize
, int maxSize
, int space
)
186 SubviewItem
*subView
;
188 subView
= wmalloc(sizeof(SubviewItem
));
189 subView
->view
= view
;
190 subView
->minSize
= minSize
;
191 subView
->maxSize
= maxSize
;
192 subView
->expand
= expand
;
193 subView
->fill
= fill
;
194 subView
->space
= space
;
197 WMAddToArray(bPtr
->subviews
, subView
);
205 WMAddBoxSubviewAtEnd(WMBox
*bPtr
, WMView
*view
, Bool expand
, Bool fill
,
206 int minSize
, int maxSize
, int space
)
208 SubviewItem
*subView
;
210 subView
= wmalloc(sizeof(SubviewItem
));
211 subView
->view
= view
;
212 subView
->minSize
= minSize
;
213 subView
->maxSize
= maxSize
;
214 subView
->expand
= expand
;
215 subView
->fill
= fill
;
216 subView
->space
= space
;
219 WMAddToArray(bPtr
->subviews
, subView
);
226 matchView(void *item
, void *cdata
)
228 return (((SubviewItem
*)item
)->view
== (WMView
*)cdata
);
233 WMRemoveBoxSubview(WMBox
*bPtr
, WMView
*view
)
235 if (WMRemoveFromArrayMatching(bPtr
->subviews
, matchView
, view
)) {
242 WMSetBoxHorizontal(WMBox
*box
, Bool flag
)
244 /* make sure flag is either 0 or 1 no matter what true value was passed */
245 flag
= ((flag
==0) ? 0 : 1);
246 if (box
->horizontal
!= flag
) {
247 box
->horizontal
= flag
;
254 destroyBox(Box
*bPtr
)
256 WMFreeArray(bPtr
->subviews
);
262 didResize(struct W_ViewDelegate
*delegate
, WMView
*view
)
264 rearrange(view
->self
);
269 handleEvents(XEvent
*event
, void *data
)
271 Box
*bPtr
= (Box
*)data
;
273 CHECK_CLASS(data
, WC_Box
);
275 switch (event
->type
) {
280 case ConfigureNotify
: