14 typedef struct W_Box
{
22 unsigned horizontal
:1;
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
= {
42 WMBox
*WMCreateBox(WMWidget
* parent
)
46 bPtr
= wmalloc(sizeof(Box
));
48 bPtr
->widgetClass
= WC_Box
;
50 bPtr
->view
= W_CreateView(W_VIEW(parent
));
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
);
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
;
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
;
97 eData
->w
+= eData
->total
/ eData
->expands
;
99 eData
->h
= item
->minSize
;
101 eData
->h
+= eData
->total
/ eData
->expands
;
104 W_MoveView(item
->view
, eData
->x
, eData
->y
);
106 W_ResizeView(item
->view
, eData
->w
, eData
->h
);
107 if (eData
->box
->horizontal
) {
109 eData
->xe
-= eData
->w
+ item
->space
;
111 eData
->x
+= eData
->w
+ item
->space
;
114 eData
->ye
-= eData
->h
+ item
->space
;
116 eData
->y
+= eData
->h
+ item
->space
;
119 W_MoveView(item
->view
, eData
->xe
, eData
->ye
);
123 static void rearrange(WMBox
* box
)
128 eData
.x
= eData
.y
= box
->borderWidth
;
129 eData
.w
= eData
.h
= 1;
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
;
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) {
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
;
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
;
173 WMAddToArray(bPtr
->subviews
, subView
);
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
;
191 WMAddToArray(bPtr
->subviews
, subView
);
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
)) {
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
;
218 static void destroyBox(Box
* bPtr
)
220 WMFreeArray(bPtr
->subviews
);
224 static void didResize(struct W_ViewDelegate
*delegate
, WMView
* view
)
226 /* Parameter not used, but tell the compiler that it is ok */
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
) {
243 case ConfigureNotify
: