17 typedef struct W_Box
{
21 SubviewItem
*subviews
;
26 unsigned horizontal
:1;
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
= {
53 WMCreateBox(WMWidget
*parent
)
57 bPtr
= wmalloc(sizeof(Box
));
58 memset(bPtr
, 0, sizeof(Box
));
60 bPtr
->widgetClass
= WC_Box
;
62 bPtr
->view
= W_CreateView(W_VIEW(parent
));
67 bPtr
->view
->self
= bPtr
;
69 bPtr
->view
->delegate
= &delegate
;
71 WMCreateEventHandler(bPtr
->view
, StructureNotifyMask
,
74 WMResizeWidget(bPtr
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
76 bPtr
->subviews
= NULL
;
77 bPtr
->subviewCount
= 0;
96 if (box
->horizontal
) {
97 ye
= box
->borderWidth
;
98 xe
= WMWidgetWidth(box
) - box
->borderWidth
;
99 h
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
100 total
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
102 xe
= box
->borderWidth
;
103 ye
= WMWidgetHeight(box
) - box
->borderWidth
;
104 w
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
105 total
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
108 if (w
<= 0 || h
<= 0 || total
<= 0) {
112 for (i
= 0; i
< box
->subviewCount
; i
++) {
113 total
-= box
->subviews
[i
].minSize
;
114 total
-= box
->subviews
[i
].space
;
115 if (box
->subviews
[i
].expand
) {
120 for (i
= 0; i
< box
->subviewCount
; i
++) {
121 if (box
->horizontal
) {
122 w
= box
->subviews
[i
].minSize
;
123 if (box
->subviews
[i
].expand
)
126 h
= box
->subviews
[i
].minSize
;
127 if (box
->subviews
[i
].expand
)
130 if (!box
->subviews
[i
].end
) {
131 W_MoveView(box
->subviews
[i
].view
, x
, y
);
133 W_ResizeView(box
->subviews
[i
].view
, w
, h
);
134 if (box
->horizontal
) {
135 if (box
->subviews
[i
].end
)
136 xe
-= w
+ box
->subviews
[i
].space
;
138 x
+= w
+ box
->subviews
[i
].space
;
140 if (box
->subviews
[i
].end
)
141 ye
-= h
+ box
->subviews
[i
].space
;
143 y
+= h
+ box
->subviews
[i
].space
;
145 if (box
->subviews
[i
].end
) {
146 W_MoveView(box
->subviews
[i
].view
, xe
, ye
);
153 WMSetBoxBorderWidth(WMBox
*box
, unsigned width
)
155 if (box
->borderWidth
!= width
) {
156 box
->borderWidth
= width
;
163 WMAddBoxSubview(WMBox
*bPtr
, WMView
*view
, Bool expand
, Bool fill
,
164 int minSize
, int maxSize
, int space
)
166 int i
= bPtr
->subviewCount
;
168 bPtr
->subviewCount
++;
170 bPtr
->subviews
= wmalloc(sizeof(SubviewItem
));
172 bPtr
->subviews
= wrealloc(bPtr
->subviews
,
173 bPtr
->subviewCount
*sizeof(SubviewItem
));
174 bPtr
->subviews
[i
].view
= view
;
175 bPtr
->subviews
[i
].minSize
= minSize
;
176 bPtr
->subviews
[i
].maxSize
= maxSize
;
177 bPtr
->subviews
[i
].expand
= expand
;
178 bPtr
->subviews
[i
].fill
= fill
;
179 bPtr
->subviews
[i
].space
= space
;
180 bPtr
->subviews
[i
].end
= 0;
188 WMAddBoxSubviewAtEnd(WMBox
*bPtr
, WMView
*view
, Bool expand
, Bool fill
,
189 int minSize
, int maxSize
, int space
)
191 int i
= bPtr
->subviewCount
;
193 bPtr
->subviewCount
++;
195 bPtr
->subviews
= wmalloc(sizeof(SubviewItem
));
197 bPtr
->subviews
= wrealloc(bPtr
->subviews
,
198 bPtr
->subviewCount
*sizeof(SubviewItem
));
199 bPtr
->subviews
[i
].view
= view
;
200 bPtr
->subviews
[i
].minSize
= minSize
;
201 bPtr
->subviews
[i
].maxSize
= maxSize
;
202 bPtr
->subviews
[i
].expand
= expand
;
203 bPtr
->subviews
[i
].fill
= fill
;
204 bPtr
->subviews
[i
].space
= space
;
205 bPtr
->subviews
[i
].end
= 1;
212 WMRemoveBoxSubview(WMBox
*bPtr
, WMView
*view
)
216 for (i
= 0; i
< bPtr
->subviewCount
; i
++) {
217 if (bPtr
->subviews
[i
].view
== view
) {
218 memmove(&bPtr
->subviews
[i
], &bPtr
->subviews
[i
+1],
219 (bPtr
->subviewCount
- i
- 1) * sizeof(void*));
220 bPtr
->subviewCount
--;
229 WMSetBoxHorizontal(WMBox
*box
, Bool flag
)
231 /* make sure flag is either 0 or 1 no matter what true value was passed */
232 flag
= ((flag
==0) ? 0 : 1);
233 if (box
->horizontal
!= flag
) {
234 box
->horizontal
= flag
;
241 destroyBox(Box
*bPtr
)
243 WMRemoveNotificationObserver(bPtr
);
249 didResize(struct W_ViewDelegate
*delegate
, WMView
*view
)
251 rearrange(view
->self
);
256 handleEvents(XEvent
*event
, void *data
)
258 Box
*bPtr
= (Box
*)data
;
260 CHECK_CLASS(data
, WC_Box
);
262 switch (event
->type
) {
267 case ConfigureNotify
: