17 typedef struct W_Box
{
21 SubviewItem
*subviews
;
31 unsigned horizontal
:1;
35 #define DEFAULT_WIDTH 40
36 #define DEFAULT_HEIGHT 40
40 static void destroyBox(Box
*bPtr
);
42 static void handleEvents(XEvent
*event
, void *data
);
44 static void didResize(struct W_ViewDelegate
*, WMView
*);
46 static W_ViewDelegate delegate
= {
57 static void resizedParent(void *self
, WMNotification
*notif
)
59 WMView
*view
= (WMView
*)WMGetNotificationObject(notif
);
60 WMSize size
= WMGetViewSize(view
);
61 WMBox
*box
= (WMBox
*)self
;
63 WMMoveWidget(box
, box
->leftOffs
, box
->topOffs
);
64 WMResizeWidget(box
, size
.width
- (box
->leftOffs
+ box
->rightOffs
),
65 size
.height
- (box
->topOffs
+ box
->bottomOffs
));
70 WMCreateBox(WMWidget
*parent
)
74 bPtr
= wmalloc(sizeof(Box
));
75 memset(bPtr
, 0, sizeof(Box
));
77 bPtr
->widgetClass
= WC_Box
;
79 bPtr
->view
= W_CreateView(W_VIEW(parent
));
84 bPtr
->view
->self
= bPtr
;
86 bPtr
->view
->delegate
= &delegate
;
88 WMCreateEventHandler(bPtr
->view
, StructureNotifyMask
,
91 WMResizeWidget(bPtr
, DEFAULT_WIDTH
, DEFAULT_HEIGHT
);
93 bPtr
->subviews
= NULL
;
94 bPtr
->subviewCount
= 0;
101 rearrange(WMBox
*box
)
110 x
= box
->borderWidth
;
111 y
= box
->borderWidth
;
113 if (box
->horizontal
) {
114 ye
= box
->borderWidth
;
115 xe
= WMWidgetWidth(box
) - box
->borderWidth
;
116 h
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
117 total
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
119 xe
= box
->borderWidth
;
120 ye
= WMWidgetHeight(box
) - box
->borderWidth
;
121 w
= WMWidgetWidth(box
) - 2 * box
->borderWidth
;
122 total
= WMWidgetHeight(box
) - 2 * box
->borderWidth
;
125 if (w
<= 0 || h
<= 0 || total
<= 0) {
129 for (i
= 0; i
< box
->subviewCount
; i
++) {
130 total
-= box
->subviews
[i
].minSize
;
131 total
-= box
->subviews
[i
].space
;
132 if (box
->subviews
[i
].expand
) {
137 for (i
= 0; i
< box
->subviewCount
; i
++) {
138 if (box
->horizontal
) {
139 w
= box
->subviews
[i
].minSize
;
140 if (box
->subviews
[i
].expand
)
143 h
= box
->subviews
[i
].minSize
;
144 if (box
->subviews
[i
].expand
)
147 if (!box
->subviews
[i
].end
) {
148 W_MoveView(box
->subviews
[i
].view
, x
, y
);
150 W_ResizeView(box
->subviews
[i
].view
, w
, h
);
151 if (box
->horizontal
) {
152 if (box
->subviews
[i
].end
)
153 xe
-= w
+ box
->subviews
[i
].space
;
155 x
+= w
+ box
->subviews
[i
].space
;
157 if (box
->subviews
[i
].end
)
158 ye
-= h
+ box
->subviews
[i
].space
;
160 y
+= h
+ box
->subviews
[i
].space
;
162 if (box
->subviews
[i
].end
) {
163 W_MoveView(box
->subviews
[i
].view
, xe
, ye
);
170 WMSetBoxBorderWidth(WMBox
*box
, unsigned width
)
172 box
->borderWidth
= width
;
179 WMAddBoxSubview(WMBox
*bPtr
, WMView
*view
, Bool expand
, Bool fill
,
180 int minSize
, int maxSize
, int space
)
182 int i
= bPtr
->subviewCount
;
184 bPtr
->subviewCount
++;
186 bPtr
->subviews
= wmalloc(sizeof(SubviewItem
));
188 bPtr
->subviews
= wrealloc(bPtr
->subviews
,
189 bPtr
->subviewCount
*sizeof(SubviewItem
));
190 bPtr
->subviews
[i
].view
= view
;
191 bPtr
->subviews
[i
].minSize
= minSize
;
192 bPtr
->subviews
[i
].maxSize
= maxSize
;
193 bPtr
->subviews
[i
].expand
= expand
;
194 bPtr
->subviews
[i
].fill
= fill
;
195 bPtr
->subviews
[i
].space
= space
;
196 bPtr
->subviews
[i
].end
= 0;
204 WMAddBoxSubviewAtEnd(WMBox
*bPtr
, WMView
*view
, Bool expand
, Bool fill
,
205 int minSize
, int maxSize
, int space
)
207 int i
= bPtr
->subviewCount
;
209 bPtr
->subviewCount
++;
211 bPtr
->subviews
= wmalloc(sizeof(SubviewItem
));
213 bPtr
->subviews
= wrealloc(bPtr
->subviews
,
214 bPtr
->subviewCount
*sizeof(SubviewItem
));
215 bPtr
->subviews
[i
].view
= view
;
216 bPtr
->subviews
[i
].minSize
= minSize
;
217 bPtr
->subviews
[i
].maxSize
= maxSize
;
218 bPtr
->subviews
[i
].expand
= expand
;
219 bPtr
->subviews
[i
].fill
= fill
;
220 bPtr
->subviews
[i
].space
= space
;
221 bPtr
->subviews
[i
].end
= 1;
228 WMRemoveBoxSubview(WMBox
*bPtr
, WMView
*view
)
232 for (i
= 0; i
< bPtr
->subviewCount
; i
++) {
233 if (bPtr
->subviews
[i
].view
== view
) {
234 memmove(&bPtr
->subviews
[i
], &bPtr
->subviews
[i
+1],
235 (bPtr
->subviewCount
- i
- 1) * sizeof(void*));
236 bPtr
->subviewCount
--;
245 WMSetBoxHorizontal(WMBox
*box
, Bool flag
)
247 box
->horizontal
= flag
;
253 WMSetBoxExpandsToParent(WMBox
*box
, int topOffs
, int bottomOffs
,
254 int leftOffs
, int rightOffs
)
256 WMSize size
= W_VIEW(box
)->parent
->size
;
258 box
->topOffs
= topOffs
;
259 box
->bottomOffs
= bottomOffs
;
260 box
->leftOffs
= leftOffs
;
261 box
->rightOffs
= rightOffs
;
263 WMAddNotificationObserver(resizedParent
, box
,
264 WMViewSizeDidChangeNotification
,
265 W_VIEW(box
)->parent
);
266 WMSetViewNotifySizeChanges(W_VIEW(box
)->parent
, True
);
268 WMMoveWidget(box
, leftOffs
, topOffs
);
269 WMResizeWidget(box
, size
.width
- (leftOffs
+ rightOffs
),
270 size
.height
- (topOffs
+ bottomOffs
));
275 destroyBox(Box
*bPtr
)
277 WMRemoveNotificationObserver(bPtr
);
283 didResize(struct W_ViewDelegate
*delegate
, WMView
*view
)
285 rearrange(view
->self
);
290 handleEvents(XEvent
*event
, void *data
)
292 Box
*bPtr
= (Box
*)data
;
294 CHECK_CLASS(data
, WC_Box
);
296 switch (event
->type
) {
301 case ConfigureNotify
: