diff --git a/haiku/GNUmakeinc.mk b/haiku/GNUmakeinc.mk index 26d2ac19..5ce1001e 100644 --- a/haiku/GNUmakeinc.mk +++ b/haiku/GNUmakeinc.mk @@ -18,6 +18,7 @@ CXXFILES += \ haiku/progressbar.cpp \ haiku/radiobuttons.cpp \ haiku/separator.cpp \ + haiku/singlechild.cpp \ haiku/slider.cpp \ haiku/spinbox.cpp \ haiku/stddialogs.cpp \ diff --git a/haiku/singlechild.cpp b/haiku/singlechild.cpp new file mode 100644 index 00000000..c77e8650 --- /dev/null +++ b/haiku/singlechild.cpp @@ -0,0 +1,79 @@ +// 19 november 2015 +#include "uipriv_haiku.hpp" + +// singlechild.cpp is like child.c/child.m in the other ports, except it only handles single children with an optional margin. + +struct singleChild { + uiControl *c; + BView *view; + BGroupLayout *box; + BLayoutItem *item; + BAlignment oldalign; +}; + +struct singleChild *newSingleChild(uiControl *c, uiControl *parent, void (*attach)(void *, BLayoutItem *), void *attachTo) +{ + struct singleChild *s; + + if (c == NULL) + return NULL; + + s = uiNew(struct singleChild); + s->c = c; + s->view = (BView *) uiControlHandle(s->c); + s->oldalign = s->view->ExplicitAlignment(); + + uiControlSetParent(s->c, parent); + + s->box = new BGroupLayout(B_HORIZONTAL, 0); + // TODO TODO TODO TODO + // currently BLayout won't let you add a view to a layout that isn't attached to a view + // that is, if you want to add a view to a layout, there must already be a parent view + // request this behavior to be changed + (*attach)(attachTo, s->box); + + s->view->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); + s->item = s->box->AddView(s->view, 1.0); + + // and set it on the box as well + // this way it fills the entire space + s->box->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); + + return s; +} + +void singleChildRemove(struct singleChild *s) +{ + s->box->RemoveItem(s->item); + delete s->item; + delete s->box; + uiControlSetParent(s->c, NULL); + s->view->SetExplicitAlignment(s->oldalign); + uiFree(s); +} + +void singleChildDestroy(struct singleChild *s) +{ + uiControl *child; + + child = s->c; + singleChildRemove(s); + uiControlDestroy(child); +} + +// this is of the box itself, not of the child +// it is used to add the child to the parent layout +BLayoutItem *singleChildLayoutItem(struct singleChild *s) +{ + return s->box; +} + +void singleChildUpdateState(struct singleChild *s) +{ + controlUpdateState(s->c); +} + +void singleChildSetMargined(struct singleChild *s, float inset) +{ + s->box->SetInsets(inset, inset, inset, inset); +} diff --git a/haiku/tab.cpp b/haiku/tab.cpp index f02ff8b9..8933dac5 100644 --- a/haiku/tab.cpp +++ b/haiku/tab.cpp @@ -3,13 +3,13 @@ struct uiTab { uiHaikuControl c; - BStringView *dummy; + BTabView *tabview; }; uiHaikuDefineControl( uiTab, // type name uiTabType, // type function - dummy // handle + tabview // handle ) void uiTabAppend(uiTab *t, const char *name, uiControl *c) @@ -50,8 +50,7 @@ uiTab *uiNewTab(void) t = (uiTab *) uiNewControl(uiTabType()); - t->dummy = new BStringView(BRect(0, 0, 1, 1), NULL, - "TODO uiTab not implemented"); + t->tabview = new BTabView(BRect(0, 0, 1, 1), NULL); uiHaikuFinishNewControl(t, uiTab); diff --git a/haiku/uipriv_haiku.hpp b/haiku/uipriv_haiku.hpp index 57e0f60a..9b6c3466 100644 --- a/haiku/uipriv_haiku.hpp +++ b/haiku/uipriv_haiku.hpp @@ -7,6 +7,14 @@ #include "../ui_haiku.hpp" #include "../common/uipriv.h" -// alloc.c +// alloc.cpp extern void initAlloc(void); extern void uninitAlloc(void); + +// singlechild.cpp +extern struct singleChild *newSingleChild(uiControl *c, uiControl *parent, void (*attach)(void *, BLayoutItem *), void *attachTo); +extern void singleChildRemove(struct singleChild *s); +extern void singleChildDestroy(struct singleChild *s); +extern BLayoutItem *singleChildLayoutItem(struct singleChild *s); +extern void singleChildUpdateState(struct singleChild *s); +extern void singleChildSetMargined(struct singleChild *s, float inset); diff --git a/haiku/window.cpp b/haiku/window.cpp index b9bf5fa6..5bdf220d 100644 --- a/haiku/window.cpp +++ b/haiku/window.cpp @@ -17,9 +17,7 @@ struct uiWindow { BGroupLayout *vbox; - uiControl *child; - BGroupLayout *childBox; - BLayoutItem *childItem; + struct singleChild *child; int margined; int (*onClosing)(uiWindow *, void *); @@ -55,12 +53,8 @@ static void windowCommitDestroy(uiControl *c) // first hide ourselves w->window->Hide(); // now destroy the child - if (w->child != NULL) { - w->childBox->RemoveItem(w->childItem); - delete w->childItem; - uiControlSetParent(w->child, NULL); - uiControlDestroy(w->child); - } + if (w->child != NULL) + singleChildDestroy(w->child); // and finally destroy ourselves // this is why we don't use the libui-provided CommitDestroy() implementation // TODO check this for errors? @@ -87,12 +81,10 @@ static void windowCommitHide(uiControl *c) static void windowContainerUpdateState(uiControl *c) { -/*TODO uiWindow *w = uiWindow(c); if (w->child != NULL) - childUpdateState(w->child); -*/ + singleChildUpdateState(w->child); } char *uiWindowTitle(uiWindow *w) @@ -112,17 +104,23 @@ void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data) w->onClosingData = data; } -// TODO save and restore old alignment +// see singlechild.cpp +static void attach(void *attachTo, BLayoutItem *what) +{ + BGroupLayout *vbox = (BGroupLayout *) attachTo; + + vbox->AddItem(what); +} + void uiWindowSetChild(uiWindow *w, uiControl *child) { if (w->child != NULL) { - w->childBox->RemoveItem(w->childItem); - delete w->childItem; - uiControlSetParent(w->child, NULL); + w->vbox->RemoveItem(singleChildLayoutItem(w->child)); + singleChildRemove(w->child); } - w->child = child; + w->child = newSingleChild(child, uiControl(w), attach, w->vbox); if (w->child != NULL) - w->childItem = w->childBox->AddView((BView *) uiControlHandle(w->child)); + uiWindowSetMargined(w, w->margined); } int uiWindowMargined(uiWindow *w) @@ -133,13 +131,11 @@ int uiWindowMargined(uiWindow *w) void uiWindowSetMargined(uiWindow *w, int margined) { w->margined = margined; - if (w->margined) - w->childBox->SetInsets(B_USE_WINDOW_SPACING, - B_USE_WINDOW_SPACING, - B_USE_WINDOW_SPACING, - B_USE_WINDOW_SPACING); - else - w->childBox->SetInsets(0, 0, 0, 0); + if (w->child != NULL) + if (w->margined) + singleChildSetMargined(w->child, B_USE_WINDOW_SPACING); + else + singleChildSetMargined(w->child, 0); } uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) @@ -162,11 +158,6 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) // Haiku itself does this, with a TODO w->vbox->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - w->childBox = new BGroupLayout(B_HORIZONTAL, 0); - w->childBox->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT)); - w->childBox->SetInsets(0, 0, 0, 0); - w->vbox->AddItem(w->childBox, 1.0); - uiWindowOnClosing(w, defaultOnClosing, NULL); uiHaikuFinishNewControl(w, uiWindow);