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
));
47 memset(bPtr
, 0, sizeof(Box
));
49 bPtr
->widgetClass
= WC_Box
;
51 bPtr
->view
= W_CreateView(W_VIEW(parent
));
56 bPtr
->view
->self
= bPtr
;
58 bPtr
->view
->delegate
= &delegate
;
60 bPtr
->subviews
= WMCreateArrayWithDestructor(2, wfree
);
62 WMCreateEventHandler(bPtr
->view
, StructureNotifyMask
, handleEvents
, bPtr
);
64 WMResizeWidget(bPtr
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
78 static void computeExpansion(void *object
, void *cdata
)
80 SubviewItem
*item
= (SubviewItem
*) object
;
81 BoxData
*eData
= (BoxData
*) cdata
;
83 eData
->total
-= item
->minSize
;
84 eData
->total
-= item
->space
;
90 static void doRearrange(void *object
, void *cdata
)
92 SubviewItem
*item
= (SubviewItem
*) object
;
93 BoxData
*eData
= (BoxData
*) cdata
;
95 if (eData
->box
->horizontal
) {
96 eData
->w
= item
->minSize
;
98 eData
->w
+= eData
->total
/ eData
->expands
;
100 eData
->h
= item
->minSize
;
102 eData
->h
+= eData
->total
/ eData
->expands
;
105 W_MoveView(item
->view
, eData
->x
, eData
->y
);
107 W_ResizeView(item
->view
, eData
->w
, eData
->h
);
108 if (eData
->box
->horizontal
) {
110 eData
->xe
-= eData
->w
+ item
->space
;
112 eData
->x
+= eData
->w
+ item
->space
;
115 eData
->ye
-= eData
->h
+ item
->space
;
117 eData
->y
+= eData
->h
+ item
->space
;
120 W_MoveView(item
->view
, eData
->xe
, eData
->ye
);
124 static void rearrange(WMBox
* box
)
129 eData
.x
= eData
.y
= box
->borderWidth
;
130 eData
.w
= eData
.h
= 1;
133 if (box
->horizontal
) {
134 eData
.ye
= box
->borderWidth
;
135 eData
.xe
= WMWidgetWidth(box
) - box
->borderWidth
;
136 eData
.h
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
137 eData
.total
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
139 eData
.xe
= box
->borderWidth
;
140 eData
.ye
= WMWidgetHeight(box
) - box
->borderWidth
;
141 eData
.w
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
142 eData
.total
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
145 if (eData
.w
<= 0 || eData
.h
<= 0 || eData
.total
<= 0) {
149 WMMapArray(box
->subviews
, computeExpansion
, &eData
);
150 WMMapArray(box
->subviews
, doRearrange
, &eData
);
153 void WMSetBoxBorderWidth(WMBox
* box
, unsigned width
)
155 if (box
->borderWidth
!= width
) {
156 box
->borderWidth
= width
;
161 void WMAddBoxSubview(WMBox
* bPtr
, WMView
* view
, Bool expand
, Bool fill
, int minSize
, int maxSize
, int space
)
163 SubviewItem
*subView
;
165 subView
= wmalloc(sizeof(SubviewItem
));
166 subView
->view
= view
;
167 subView
->minSize
= minSize
;
168 subView
->maxSize
= maxSize
;
169 subView
->expand
= expand
;
170 subView
->fill
= fill
;
171 subView
->space
= space
;
174 WMAddToArray(bPtr
->subviews
, subView
);
179 void WMAddBoxSubviewAtEnd(WMBox
* bPtr
, WMView
* view
, Bool expand
, Bool fill
, int minSize
, int maxSize
, int space
)
181 SubviewItem
*subView
;
183 subView
= wmalloc(sizeof(SubviewItem
));
184 subView
->view
= view
;
185 subView
->minSize
= minSize
;
186 subView
->maxSize
= maxSize
;
187 subView
->expand
= expand
;
188 subView
->fill
= fill
;
189 subView
->space
= space
;
192 WMAddToArray(bPtr
->subviews
, subView
);
197 static int matchView(void *item
, void *cdata
)
199 return (((SubviewItem
*) item
)->view
== (WMView
*) cdata
);
202 void WMRemoveBoxSubview(WMBox
* bPtr
, WMView
* view
)
204 if (WMRemoveFromArrayMatching(bPtr
->subviews
, matchView
, view
)) {
209 void WMSetBoxHorizontal(WMBox
* box
, Bool flag
)
211 /* make sure flag is either 0 or 1 no matter what true value was passed */
212 flag
= ((flag
== 0) ? 0 : 1);
213 if (box
->horizontal
!= flag
) {
214 box
->horizontal
= flag
;
219 static void destroyBox(Box
* bPtr
)
221 WMFreeArray(bPtr
->subviews
);
225 static void didResize(struct W_ViewDelegate
*delegate
, WMView
* view
)
227 rearrange(view
->self
);
230 static void handleEvents(XEvent
* event
, void *data
)
232 Box
*bPtr
= (Box
*) data
;
234 CHECK_CLASS(data
, WC_Box
);
236 switch (event
->type
) {
241 case ConfigureNotify
: