libui/haiku/box.cpp

152 lines
2.9 KiB
C++

// 18 november 2015
#include <vector>
#include "uipriv_haiku.hpp"
using namespace std;
struct boxchild {
uiControl *c;
BAlignment oldalign;
bool stretchy;
BLayoutItem *item;
};
struct uiBox {
uiHaikuControl c;
// layouts are not views; all layouts need an associated view
BView *view;
BGroupLayout *layout;
vector<struct boxchild> *controls;
int vertical;
int padded;
};
static void onDestroy(uiBox *b);
uiHaikuDefineControlWithOnDestroy(
uiBox, // type name
uiBoxType, // type function
view, // handle
onDestroy(hthis); // on destroy
)
static void onDestroy(uiBox *b)
{
struct boxchild bc;
while (b->controls->size() != 0) {
bc = b->controls->back();
uiControlSetParent(bc.c, NULL);
uiControlDestroy(bc.c);
b->controls->pop_back();
}
delete b->controls;
// TODO is the layout automatically deleted?
}
static void boxContainerUpdateState(uiControl *c)
{
uiBox *b = uiBox(c);
struct boxchild bc;
uintmax_t i;
for (i = 0; i < b->controls->size(); i++) {
bc = b->controls->at(i);
controlUpdateState(bc.c);
}
}
#define isStretchy(bc) bc.stretchy
void uiBoxAppend(uiBox *b, uiControl *c, int stretchy)
{
struct boxchild bc;
BView *view;
BAlignment alignment;
float weight;
bc.c = c;
view = (BView *) uiControlHandle(bc.c);
bc.oldalign = view->ExplicitAlignment();
bc.stretchy = stretchy != 0;
alignment.horizontal = B_ALIGN_USE_FULL_WIDTH;
alignment.vertical = B_ALIGN_USE_FULL_HEIGHT;
weight = 0.0;
if (isStretchy(bc))
weight = 1.0;
else {
if (b->vertical)
alignment.vertical = B_ALIGN_TOP;
else
alignment.horizontal = B_ALIGN_LEFT;
}
uiControlSetParent(bc.c, uiControl(b));
view->SetExplicitAlignment(alignment);
bc.item = b->layout->AddView(view, weight);
b->controls->push_back(bc);
}
void uiBoxDelete(uiBox *b, uintmax_t index)
{
struct boxchild bc;
BView *view;
bc = b->controls->back();
b->controls->pop_back();
b->layout->RemoveItem(bc.item);
delete bc.item;
view = (BView *) uiControlHandle(bc.c);
view->SetExplicitAlignment(bc.oldalign);
uiControlSetParent(bc.c, NULL);
}
int uiBoxPadded(uiBox *b)
{
return b->padded;
}
void uiBoxSetPadded(uiBox *b, int padded)
{
b->padded = padded;
if (b->padded)
b->layout->SetSpacing(B_USE_DEFAULT_SPACING);
else
b->layout->SetSpacing(0);
}
static uiBox *finishNewBox(orientation o)
{
uiBox *b;
b = (uiBox *) uiNewControl(uiBoxType());
b->layout = new BGroupLayout(o, 0);
b->view = new BView(NULL, B_SUPPORTS_LAYOUT, b->layout);
// TODO is this really necessary? is it correct?
b->view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
b->vertical = o == B_VERTICAL;
b->controls = new vector<struct boxchild>();
uiHaikuFinishNewControl(b, uiBox);
uiControl(b)->ContainerUpdateState = boxContainerUpdateState;
return b;
}
uiBox *uiNewHorizontalBox(void)
{
return finishNewBox(B_HORIZONTAL);
}
uiBox *uiNewVerticalBox(void)
{
return finishNewBox(B_VERTICAL);
}