Files
wmaker/WINGs/wbox.c
T

248 lines
4.9 KiB
C
Raw Normal View History

2000-11-09 05:01:58 +00:00
#include "WINGsP.h"
typedef struct {
2009-08-20 00:59:40 +02:00
WMView *view;
int minSize;
int maxSize;
int space;
unsigned expand:1;
unsigned fill:1;
unsigned end:1;
2000-11-09 05:01:58 +00:00
} SubviewItem;
typedef struct W_Box {
2009-08-20 00:59:40 +02:00
W_Class widgetClass;
W_View *view;
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
WMArray *subviews;
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
short borderWidth;
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
unsigned horizontal:1;
2000-11-09 05:01:58 +00:00
} Box;
#define DEFAULT_WIDTH 40
#define DEFAULT_HEIGHT 40
2009-08-20 00:59:40 +02:00
static void destroyBox(Box * bPtr);
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
static void handleEvents(XEvent * event, void *data);
2001-01-11 16:31:23 +00:00
2009-08-20 00:59:40 +02:00
static void didResize(struct W_ViewDelegate *, WMView *);
2000-11-09 05:01:58 +00:00
static W_ViewDelegate delegate = {
2009-08-20 00:59:40 +02:00
NULL,
NULL,
didResize,
NULL,
NULL
2000-11-09 05:01:58 +00:00
};
2009-08-20 00:59:40 +02:00
WMBox *WMCreateBox(WMWidget * parent)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
Box *bPtr;
2009-08-20 00:59:40 +02:00
bPtr = wmalloc(sizeof(Box));
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
bPtr->widgetClass = WC_Box;
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
bPtr->view = W_CreateView(W_VIEW(parent));
if (!bPtr->view) {
wfree(bPtr);
return NULL;
}
bPtr->view->self = bPtr;
2009-08-20 00:59:40 +02:00
bPtr->view->delegate = &delegate;
2009-08-20 00:59:40 +02:00
bPtr->subviews = WMCreateArrayWithDestructor(2, wfree);
2009-08-20 00:59:40 +02:00
WMCreateEventHandler(bPtr->view, StructureNotifyMask, handleEvents, bPtr);
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
WMResizeWidget(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
2009-08-20 00:59:40 +02:00
return bPtr;
2000-11-09 05:01:58 +00:00
}
typedef struct {
2009-08-20 00:59:40 +02:00
WMBox *box;
int total;
int expands;
int x, y;
int xe, ye;
int w, h;
} BoxData;
2009-08-20 00:59:40 +02:00
static void computeExpansion(void *object, void *cdata)
{
2009-08-20 00:59:40 +02:00
SubviewItem *item = (SubviewItem *) object;
BoxData *eData = (BoxData *) cdata;
eData->total -= item->minSize;
eData->total -= item->space;
if (item->expand) {
eData->expands++;
}
}
2009-08-20 00:59:40 +02:00
static void doRearrange(void *object, void *cdata)
{
2009-08-20 00:59:40 +02:00
SubviewItem *item = (SubviewItem *) object;
BoxData *eData = (BoxData *) cdata;
if (eData->box->horizontal) {
eData->w = item->minSize;
if (item->expand)
eData->w += eData->total / eData->expands;
} else {
eData->h = item->minSize;
if (item->expand)
eData->h += eData->total / eData->expands;
}
if (!item->end) {
W_MoveView(item->view, eData->x, eData->y);
}
W_ResizeView(item->view, eData->w, eData->h);
if (eData->box->horizontal) {
if (item->end)
eData->xe -= eData->w + item->space;
else
eData->x += eData->w + item->space;
} else {
if (item->end)
eData->ye -= eData->h + item->space;
else
eData->y += eData->h + item->space;
}
if (item->end) {
W_MoveView(item->view, eData->xe, eData->ye);
}
}
2009-08-20 00:59:40 +02:00
static void rearrange(WMBox * box)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
BoxData eData;
eData.box = box;
eData.x = eData.y = box->borderWidth;
eData.w = eData.h = 1;
eData.expands = 0;
if (box->horizontal) {
eData.ye = box->borderWidth;
eData.xe = WMWidgetWidth(box) - box->borderWidth;
eData.h = WMWidgetHeight(box) - 2 * box->borderWidth;
eData.total = WMWidgetWidth(box) - 2 * box->borderWidth;
} else {
eData.xe = box->borderWidth;
eData.ye = WMWidgetHeight(box) - box->borderWidth;
eData.w = WMWidgetWidth(box) - 2 * box->borderWidth;
eData.total = WMWidgetHeight(box) - 2 * box->borderWidth;
}
if (eData.w <= 0 || eData.h <= 0 || eData.total <= 0) {
return;
}
WMMapArray(box->subviews, computeExpansion, &eData);
WMMapArray(box->subviews, doRearrange, &eData);
2000-11-09 05:01:58 +00:00
}
2009-08-20 00:59:40 +02:00
void WMSetBoxBorderWidth(WMBox * box, unsigned width)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
if (box->borderWidth != width) {
box->borderWidth = width;
rearrange(box);
}
2000-11-09 05:01:58 +00:00
}
2009-08-20 00:59:40 +02:00
void WMAddBoxSubview(WMBox * bPtr, WMView * view, Bool expand, Bool fill, int minSize, int maxSize, int space)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
SubviewItem *subView;
2009-08-20 00:59:40 +02:00
subView = wmalloc(sizeof(SubviewItem));
subView->view = view;
subView->minSize = minSize;
subView->maxSize = maxSize;
subView->expand = expand;
subView->fill = fill;
subView->space = space;
subView->end = 0;
2009-08-20 00:59:40 +02:00
WMAddToArray(bPtr->subviews, subView);
2001-01-11 16:31:23 +00:00
2009-08-20 00:59:40 +02:00
rearrange(bPtr);
2001-01-02 14:17:26 +00:00
}
2009-08-20 00:59:40 +02:00
void WMAddBoxSubviewAtEnd(WMBox * bPtr, WMView * view, Bool expand, Bool fill, int minSize, int maxSize, int space)
2001-01-02 14:17:26 +00:00
{
2009-08-20 00:59:40 +02:00
SubviewItem *subView;
2009-08-20 00:59:40 +02:00
subView = wmalloc(sizeof(SubviewItem));
subView->view = view;
subView->minSize = minSize;
subView->maxSize = maxSize;
subView->expand = expand;
subView->fill = fill;
subView->space = space;
subView->end = 1;
2009-08-20 00:59:40 +02:00
WMAddToArray(bPtr->subviews, subView);
2001-01-11 16:31:23 +00:00
2009-08-20 00:59:40 +02:00
rearrange(bPtr);
2000-11-09 05:01:58 +00:00
}
2010-03-16 19:01:01 +01:00
static int matchView(const void *item, const void *cdata)
{
2009-08-20 00:59:40 +02:00
return (((SubviewItem *) item)->view == (WMView *) cdata);
}
2009-08-20 00:59:40 +02:00
void WMRemoveBoxSubview(WMBox * bPtr, WMView * view)
2001-01-11 16:31:23 +00:00
{
2009-08-20 00:59:40 +02:00
if (WMRemoveFromArrayMatching(bPtr->subviews, matchView, view)) {
rearrange(bPtr);
}
2001-01-11 16:31:23 +00:00
}
2009-08-20 00:59:40 +02:00
void WMSetBoxHorizontal(WMBox * box, Bool flag)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
/* make sure flag is either 0 or 1 no matter what true value was passed */
flag = ((flag == 0) ? 0 : 1);
if (box->horizontal != flag) {
box->horizontal = flag;
rearrange(box);
}
2000-11-09 05:01:58 +00:00
}
2009-08-20 00:59:40 +02:00
static void destroyBox(Box * bPtr)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
WMFreeArray(bPtr->subviews);
wfree(bPtr);
2000-11-09 05:01:58 +00:00
}
2009-08-20 00:59:40 +02:00
static void didResize(struct W_ViewDelegate *delegate, WMView * view)
2000-11-09 05:01:58 +00:00
{
/* Parameter not used, but tell the compiler that it is ok */
(void) delegate;
2009-08-20 00:59:40 +02:00
rearrange(view->self);
2000-11-09 05:01:58 +00:00
}
2009-08-20 00:59:40 +02:00
static void handleEvents(XEvent * event, void *data)
2000-11-09 05:01:58 +00:00
{
2009-08-20 00:59:40 +02:00
Box *bPtr = (Box *) data;
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
CHECK_CLASS(data, WC_Box);
2000-11-09 05:01:58 +00:00
2009-08-20 00:59:40 +02:00
switch (event->type) {
case DestroyNotify:
destroyBox(bPtr);
break;
2004-10-12 21:28:27 +00:00
2009-08-20 00:59:40 +02:00
case ConfigureNotify:
rearrange(bPtr);
break;
}
2000-11-09 05:01:58 +00:00
}