Discontinued the Haiku port for now.

This commit is contained in:
Pietro Gagliardi 2016-04-24 14:18:56 -04:00
parent 46391367fe
commit 6f46bea054
32 changed files with 0 additions and 2167 deletions

View File

@ -1,51 +0,0 @@
# 22 april 2015
CXXFILES += \
haiku/alloc.cpp \
haiku/area.cpp \
haiku/box.cpp \
haiku/button.cpp \
haiku/checkbox.cpp \
haiku/combobox.cpp \
haiku/control.cpp \
haiku/datetimepicker.cpp \
haiku/draw.cpp \
haiku/entry.cpp \
haiku/group.cpp \
haiku/label.cpp \
haiku/main.cpp \
haiku/menu.cpp \
haiku/multilineentry.cpp \
haiku/progressbar.cpp \
haiku/radiobuttons.cpp \
haiku/separator.cpp \
haiku/singlechild.cpp \
haiku/slider.cpp \
haiku/spinbox.cpp \
haiku/stddialogs.cpp \
haiku/tab.cpp \
haiku/text.cpp \
haiku/util.cpp \
haiku/window.cpp
HFILES += \
haiku/uipriv_haiku.hpp
# TODO split into a separate file or put in GNUmakefile.libui somehow?
# flags for the Haiku API
LDFLAGS += \
-lbe
# flags for building a shared library
LDFLAGS += \
-shared
# flags for warning on undefined symbols
LDFLAGS += \
-Wl,--no-undefined -Wl,--no-allow-shlib-undefined
# flags for setting soname
# TODO is this correct for Haiku?
LDFLAGS += \
-Wl,-soname,$(NAME)$(SUFFIX).$(SOVERSION)

View File

@ -1,17 +0,0 @@
# 16 october 2015
EXESUFFIX =
LIBSUFFIX = .so
OSHSUFFIX = .hpp
TOOLCHAIN = gcc
# TODO
USESSONAME = 0
# Force GCC 4; GCC 2 is not supported.
gccver = $(shell $(CC) --version | sed 's/-.*//g')
ifeq ($(gccver),2.95.3)
# TODO warn?
CC = gcc-x86
CXX = g++-x86
endif

View File

@ -1,82 +0,0 @@
// 4 december 2014
#include <set>
#include <cstdio>
#include <cstdlib>
#include "uipriv_haiku.hpp"
using namespace std;
static set<void *> allocations;
void initAlloc(void)
{
}
#define UINT8(p) ((uint8_t *) (p))
#define PVOID(p) ((void *) (p))
#define EXTRA (sizeof (size_t) + sizeof (const char **))
#define DATA(p) PVOID(UINT8(p) + EXTRA)
#define BASE(p) PVOID(UINT8(p) - EXTRA)
#define SIZE(p) ((size_t *) (p))
#define CCHAR(p) ((const char **) (p))
#define TYPE(p) CCHAR(UINT8(p) + sizeof (size_t))
void uninitAlloc(void)
{
set<void *>::const_iterator i;
if (allocations.size() == 0)
return;
fprintf(stderr, "[libui] leaked allocations:\n");
for (i = allocations.begin(); i != allocations.end(); i++)
fprintf(stderr, "[libui] %p %s\n", *i, *TYPE(*i));
complain("either you left something around or there's a bug in libui");
}
void *uiAlloc(size_t size, const char *type)
{
void *out;
out = malloc(EXTRA + size);
if (out == NULL) {
fprintf(stderr, "memory exhausted in uiAlloc()\n");
abort();
}
memset(DATA(out), 0, size);
*SIZE(out) = size;
*TYPE(out) = type;
allocations.insert(out);
return DATA(out);
}
void *uiRealloc(void *p, size_t xnew, const char *type)
{
void *out;
size_t *s;
if (p == NULL)
return uiAlloc(xnew, type);
p = BASE(p);
out = realloc(p, EXTRA + xnew);
if (out == NULL) {
fprintf(stderr, "memory exhausted in uiRealloc()\n");
abort();
}
s = SIZE(out);
if (xnew <= *s)
memset(((uint8_t *) DATA(out)) + *s, 0, xnew - *s);
*s = xnew;
// TODO check this
allocations.erase(p);
allocations.insert(out);
return DATA(out);
}
void uiFree(void *p)
{
if (p == NULL)
complain("attempt to uiFree(NULL); there's a bug somewhere");
p = BASE(p);
free(p);
// TODO check this
allocations.erase(p);
}

View File

@ -1,90 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
// TODO scrollbars
class areaView : public BView {
public:
// C++11! Inherit constructors.
using BView::BView;
uiArea *a;
virtual void Draw(BRect updateRect);
};
struct uiArea {
uiHaikuControl c;
areaView *area;
uiAreaHandler *ah;
};
uiHaikuDefineControl(
uiArea, // type name
uiAreaType, // type function
area // handle
)
void areaView::Draw(BRect updateRect)
{
uiAreaHandler *ah = this->a->ah;
uiAreaDrawParams dp;
BRect bounds;
dp.Context = newContext(this);
bounds = this->Bounds();
dp.ClientWidth = bounds.right - bounds.left;
dp.ClientHeight = bounds.bottom - bounds.top;
dp.ClipX = updateRect.left;
dp.ClipY = updateRect.top;
dp.ClipWidth = updateRect.right - updateRect.left;
dp.ClipHeight = updateRect.bottom - updateRect.top;
// TODO scroll positions
(*(ah->Draw))(ah, this->a, &dp);
freeContext(dp.Context);
}
void uiAreaUpdateScroll(uiArea *a)
{
// TODO
}
void uiAreaQueueRedrawAll(uiArea *a)
{
// TODO does this really /queue/ a redraw? or does it redraw right away, regardless of the drawing machinery?
a->area->Invalidate();
}
uiArea *uiNewArea(uiAreaHandler *ah)
{
uiArea *a;
a = (uiArea *) uiNewControl(uiAreaType());
a->ah = ah;
// TODO:
// - B_FULL_UPDATE_ON_RESIZE?
// - B_FRAME_EVENTS?
// - B_NAVIGABLE?
// - B_SUBPIXEL_PRECISE?
// - B_INVALIDATE_AFTER_LAYOUT?
a->area = new areaView(NULL,
B_WILL_DRAW | B_SUPPORTS_LAYOUT,
NULL);
a->area->a = a;
// TODO background color
// this is needed for alpha transparency (thanks mmu_man in irc.freenode.net/#haiku)
// unfortunately TODO it kills the other compositing modes
// (remember that if we ever drop Windows 7 we can use those)
a->area->SetDrawingMode(B_OP_ALPHA);
uiHaikuFinishNewControl(a, uiArea);
return a;
}

View File

@ -1,151 +0,0 @@
// 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);
}

View File

@ -1,69 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiButton {
uiHaikuControl c;
BButton *button;
void (*onClicked)(uiButton *, void *);
void *onClickedData;
};
uiHaikuDefineControl(
uiButton, // type name
uiButtonType, // type function
button // handle
)
#define mButtonClicked 0x4E754E75
static void onClicked(BMessage *msg)
{
void *bb;
uiButton *b;
// TODO error check
msg->FindPointer(mControlField, &bb);
b = uiButton(bb);
(*(b->onClicked))(b, b->onClickedData);
}
static void defaultOnClicked(uiButton *b, void *data)
{
// do nothing
}
char *uiButtonText(uiButton *b)
{
return uiHaikuStrdupText(b->button->Label());
}
void uiButtonSetText(uiButton *b, const char *text)
{
b->button->SetLabel(text);
}
void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *b, void *data), void *data)
{
b->onClicked = f;
b->onClickedData = data;
}
uiButton *uiNewButton(const char *text)
{
uiButton *b;
BMessage *msg;
b = (uiButton *) uiNewControl(uiButtonType());
uiHaikuRegisterEventHandler(mButtonClicked, onClicked);
msg = new BMessage(mButtonClicked);
msg->AddPointer(mControlField, b);
b->button = new BButton(text, msg);
uiButtonOnClicked(b, defaultOnClicked, NULL);
uiHaikuFinishNewControl(b, uiButton);
return b;
}

View File

@ -1,74 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
// TODOs
// - checkbox text isn't aligned with the checkbox
struct uiCheckbox {
uiHaikuControl c;
BCheckBox *checkbox;
void (*onToggled)(uiCheckbox *, void *);
void *onToggledData;
};
uiHaikuDefineControl(
uiCheckbox, // type name
uiCheckboxType, // type function
checkbox // handle
)
#define mCheckboxToggled 0x4E714E71
static void defaultOnToggled(uiCheckbox *c, void *data)
{
// do nothing
}
char *uiCheckboxText(uiCheckbox *c)
{
// TODO not on api.haiku-os.org? or is this not right?
return uiHaikuStrdupText(c->checkbox->Label());
}
void uiCheckboxSetText(uiCheckbox *c, const char *text)
{
// TODO not on api.haiku-os.org? or is this not right?
c->checkbox->SetLabel(text);
}
void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *c, void *data), void *data)
{
c->onToggled = f;
c->onToggledData = data;
}
int uiCheckboxChecked(uiCheckbox *c)
{
return c->checkbox->Value() != B_CONTROL_OFF;
}
void uiCheckboxSetChecked(uiCheckbox *c, int checked)
{
int32 value;
value = B_CONTROL_OFF;
if (checked)
value = B_CONTROL_ON;
// TODO does this trigger an event?
c->checkbox->SetValue(value);
}
uiCheckbox *uiNewCheckbox(const char *text)
{
uiCheckbox *c;
c = (uiCheckbox *) uiNewControl(uiCheckboxType());
c->checkbox = new BCheckBox(text, new BMessage(mCheckboxToggled));
uiCheckboxOnToggled(c, defaultOnToggled, NULL);
uiHaikuFinishNewControl(c, uiCheckbox);
return c;
}

View File

@ -1,58 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiCombobox {
uiHaikuControl c;
BStringView *dummy;
};
uiHaikuDefineControl(
uiCombobox, // type name
uiComboboxType, // type function
dummy // handle
)
void uiComboboxAppend(uiCombobox *c, const char *text)
{
// TODO
}
intmax_t uiComboboxSelected(uiCombobox *c)
{
// TODO
// return 0 so the area test can work
return 0;
}
void uiComboboxSetSelected(uiCombobox *c, intmax_t n)
{
// TODO
}
void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data)
{
// TODO
}
static uiCombobox *finishNewCombobox(void)
{
uiCombobox *c;
c = (uiCombobox *) uiNewControl(uiComboboxType());
c->dummy = new BStringView(NULL, "TODO uiCombobox not implemented");
uiHaikuFinishNewControl(c, uiCombobox);
return c;
}
uiCombobox *uiNewCombobox(void)
{
return finishNewCombobox();
}
uiCombobox *uiNewEditableCombobox(void)
{
return finishNewCombobox();
}

View File

@ -1,43 +0,0 @@
// 16 august 2015
#include "uipriv_haiku.hpp"
static uintmax_t type_uiHaikuControl = 0;
uintmax_t uiHaikuControlType(void)
{
if (type_uiHaikuControl == 0)
type_uiHaikuControl = uiRegisterType("uiHaikuControl", uiControlType(), sizeof (uiHaikuControl));
return type_uiHaikuControl;
}
static void defaultCommitShow(uiControl *c)
{
BView *view;
view = (BView *) uiControlHandle(c);
view->Show();
}
static void defaultCommitHide(uiControl *c)
{
BView *view;
view = (BView *) uiControlHandle(c);
view->Hide();
}
void osCommitEnable(uiControl *c)
{
// TODO this might need to be per-widget
}
void osCommitDisable(uiControl *c)
{
// TODO this might need to be per-widget
}
void uiHaikuFinishControl(uiControl *c)
{
c->CommitShow = defaultCommitShow;
c->CommitHide = defaultCommitHide;
}

View File

@ -1,41 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiDateTimePicker {
uiHaikuControl c;
BStringView *dummy;
};
uiHaikuDefineControl(
uiDateTimePicker, // type name
uiDateTimePickerType, // type function
dummy // handle
)
static uiDateTimePicker *finishNewDateTimePicker(void)
{
uiDateTimePicker *d;
d = (uiDateTimePicker *) uiNewControl(uiDateTimePickerType());
d->dummy = new BStringView(NULL, "TODO uiDateTimePicker not implemented");
uiHaikuFinishNewControl(d, uiDateTimePicker);
return d;
}
uiDateTimePicker *uiNewDateTimePicker(void)
{
return finishNewDateTimePicker();
}
uiDateTimePicker *uiNewDatePicker(void)
{
return finishNewDateTimePicker();
}
uiDateTimePicker *uiNewTimePicker(void)
{
return finishNewDateTimePicker();
}

View File

@ -1,407 +0,0 @@
// 19 november 2015
#include <cmath>
#include "uipriv_haiku.hpp"
using namespace std;
struct uiDrawPath {
BShape *shape;
uiDrawFillMode fillMode;
bool ended;
};
uiDrawPath *uiDrawNewPath(uiDrawFillMode fillMode)
{
uiDrawPath *p;
p = uiNew(uiDrawPath);
p->shape = new BShape();
p->fillMode = fillMode;
return p;
}
void uiDrawFreePath(uiDrawPath *p)
{
delete p->shape;
uiFree(p);
}
// TODO add ended checks
// TODO add error checks
void uiDrawPathNewFigure(uiDrawPath *p, double x, double y)
{
p->shape->MoveTo(BPoint(x, y));
}
// Even though BView::FillArc()/StrokeArc() existed and used the sane arc drawing model, Haiku decided to use the Direct2D arc drawing model when it added BShape::ArcTo().
// So refer to windows/draw.c for details.
// This is slightly better as it uses center points and sweep amounts instead of endpoints, but *still*.
// TODO split into common/d2darc.c
struct arc {
double xCenter;
double yCenter;
double radius;
double startAngle;
double sweep;
int negative;
};
// this is used for the comparison below
// if it falls apart it can be changed later
#define aerMax 6 * DBL_EPSILON
static void drawArc(uiDrawPath *p, struct arc *a, void (*startFunction)(uiDrawPath *, double, double))
{
double sinx, cosx;
double startX, startY;
double endX, endY;
bool largeArc;
bool counterclockwise;
bool fullCircle;
double absSweep;
// TODO is this relevaith Haiku?
// as above, we can't do a full circle with one arc
// simulate it with two half-circles
// of course, we have a dragon: equality on floating-point values!
// I've chosen to do the AlmostEqualRelative() technique in https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
fullCircle = false;
// use the absolute value to tackle both ≥2π and ≤-2π at the same time
absSweep = fabs(a->sweep);
if (absSweep > (2 * M_PI)) // this part is easy
fullCircle = true;
else {
double aerDiff;
aerDiff = fabs(absSweep - (2 * M_PI));
// if we got here then we know a->sweep is larger (or the same!)
fullCircle = aerDiff <= absSweep * aerMax;
}
// TODO make sure this works right for the negative direction
if (fullCircle) {
a->sweep = M_PI;
drawArc(p, a, startFunction);
a->startAngle += M_PI;
drawArc(p, a, NULL);
return;
}
// first, figure out the arc's endpoints
sinx = sin(a->startAngle);
cosx = cos(a->startAngle);
startX = a->xCenter + a->radius * cosx;
startY = a->yCenter + a->radius * sinx;
sinx = sin(a->startAngle + a->sweep);
cosx = cos(a->startAngle + a->sweep);
endX = a->xCenter + a->radius * cosx;
endY = a->yCenter + a->radius * sinx;
// now do the initial step to get the current point to be the start point
// this is either creating a new figure, drawing a line, or (in the case of our full circle code above) doing nothing
if (startFunction != NULL)
(*startFunction)(p, startX, startY);
// now we can draw the arc
if (a->negative)
counterclockwise = true;
else
counterclockwise = false;
// TODO explain the outer if
if (!a->negative)
if (a->sweep > M_PI)
largeArc = true;
else
largeArc = false;
else
// TODO especially this part
if (a->sweep > M_PI)
largeArc = false;
else
largeArc = true;
p->shape->ArcTo(a->radius, a->radius,
// TODO should this be sweep amount?
a->startAngle, // TODO convert to degrees
largeArc, counterclockwise,
BPoint(a->xCenter, a->yCenter));
}
void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
{
struct arc a;
a.xCenter = xCenter;
a.yCenter = yCenter;
a.radius = radius;
a.startAngle = startAngle;
a.sweep = sweep;
a.negative = negative;
drawArc(p, &a, uiDrawPathNewFigure);
}
void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
{
p->shape->LineTo(BPoint(x, y));
}
void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
{
struct arc a;
a.xCenter = xCenter;
a.yCenter = yCenter;
a.radius = radius;
a.startAngle = startAngle;
a.sweep = sweep;
a.negative = negative;
drawArc(p, &a, uiDrawPathLineTo);
}
void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY)
{
p->shape->BezierTo(BPoint(c1x, c1y),
BPoint(c2x, c2y),
BPoint(endX, endY));
}
void uiDrawPathCloseFigure(uiDrawPath *p)
{
p->shape->Close();
}
void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height)
{
// this is the same algorithm used by cairo and Core Graphics, according to their documentations
uiDrawPathNewFigure(p, x, y);
uiDrawPathLineTo(p, x + width, y);
uiDrawPathLineTo(p, x + width, y + height);
uiDrawPathLineTo(p, x, y + height);
uiDrawPathCloseFigure(p);
}
void uiDrawPathEnd(uiDrawPath *p)
{
p->ended = true;
}
struct uiDrawContext {
BView *view;
};
uiDrawContext *newContext(BView *view)
{
uiDrawContext *c;
c = uiNew(uiDrawContext);
c->view = view;
return c;
}
void freeContext(uiDrawContext *c)
{
uiFree(c);
}
// TODO verify this
static void setHighColor(BView *view, uiDrawBrush *b)
{
view->SetHighColor(b->R * 255,
b->G * 255,
b->B * 255,
b->A * 255);
}
// TODO path ended checks; error checks
void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p)
{
cap_mode cap;
join_mode join;
switch (p->Cap) {
case uiDrawLineCapFlat:
cap = B_BUTT_CAP;
break;
case uiDrawLineCapRound:
cap = B_ROUND_CAP;
break;
case uiDrawLineCapSquare:
cap = B_SQUARE_CAP;
break;
}
switch (p->Join) {
case uiDrawLineJoinMiter:
join = B_MITER_JOIN;
break;
case uiDrawLineJoinRound:
join = B_ROUND_JOIN;
break;
case uiDrawLineJoinBevel:
join = B_BEVEL_JOIN;
break;
}
c->view->SetLineMode(cap, join, p->MiterLimit);
c->view->SetPenSize(p->Thickness);
// TODO line dashes
switch (b->Type) {
case uiDrawBrushTypeSolid:
setHighColor(c->view, b);
c->view->StrokeShape(path->shape);
break;
case uiDrawBrushTypeLinearGradient:
// TODO
case uiDrawBrushTypeRadialGradient:
// TODO
break;
// case uiDrawBrushTypeImage:
}
}
void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b)
{
// TODO not documented on api.haiku-os.org
switch (path->fillMode) {
case uiDrawFillModeWinding:
c->view->SetFillRule(B_NONZERO);
break;
case uiDrawFillModeAlternate:
c->view->SetFillRule(B_EVEN_ODD);
break;
}
switch (b->Type) {
case uiDrawBrushTypeSolid:
setHighColor(c->view, b);
c->view->FillShape(path->shape);
break;
case uiDrawBrushTypeLinearGradient:
// TODO
case uiDrawBrushTypeRadialGradient:
// TODO
break;
// case uiDrawBrushTypeImage:
}
}
// TODO none of this is documented on api.haiku-os.org
static void m2a(uiDrawMatrix *m, BAffineTransform *a)
{
a->sx = m->M11;
a->shy = m->M12;
a->shx = m->M21;
a->sy = m->M22;
a->tx = m->M31;
a->ty = m->M32;
}
static void a2m(BAffineTransform *a, uiDrawMatrix *m)
{
m->M11 = a->sx;
m->M12 = a->shy;
m->M21 = a->shx;
m->M22 = a->sy;
m->M31 = a->tx;
m->M32 = a->ty;
}
void uiDrawMatrixSetIdentity(uiDrawMatrix *m)
{
setIdentity(m);
}
void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y)
{
BAffineTransform a;
m2a(m, &a);
a.TranslateBy(x, y);
a2m(&a, m);
}
void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y)
{
BAffineTransform a;
m2a(m, &a);
a.ScaleBy(BPoint(xCenter, yCenter), BPoint(x, y));
a2m(&a, m);
}
void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount)
{
BAffineTransform a;
m2a(m, &a);
// TODO degrees or radians?
a.RotateBy(BPoint(x, y), amount);
a2m(&a, m);
}
void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount)
{
BAffineTransform a;
m2a(m, &a);
// TODO degrees or radians?
a.ShearBy(BPoint(x, y), BPoint(xamount, yamount));
a2m(&a, m);
}
void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src)
{
BAffineTransform c;
BAffineTransform d;
m2a(dest, &c);
m2a(src, &d);
c.Multiply(d);
a2m(&c, dest);
}
int uiDrawMatrixInvertible(uiDrawMatrix *m)
{
// TODO
return 0;
}
int uiDrawMatrixInvert(uiDrawMatrix *m)
{
// TODO
return 0;
}
void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y)
{
// TODO
}
void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y)
{
// TODO
}
void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m)
{
BAffineTransform a;
m2a(m, &a);
// see windows/draw.c
a.Multiply(c->view->Transform());
c->view->SetTransform(a);
}
// TODO not documented on api.haiku-os.org
void uiDrawClip(uiDrawContext *c, uiDrawPath *path)
{
c->view->ClipToShape(path->shape);
}
void uiDrawSave(uiDrawContext *c)
{
c->view->PushState();
}
void uiDrawRestore(uiDrawContext *c)
{
c->view->PopState();
}

View File

@ -1,65 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiEntry {
uiHaikuControl c;
BTextControl *tc;
void (*onChanged)(uiEntry *, void *);
void *onChangedData;
};
uiHaikuDefineControl(
uiEntry, // type name
uiEntryType, // type function
tc // handle
)
#define mEntryChanged 0x60FE60FE
static void defaultOnChanged(uiEntry *e, void *data)
{
// do nothing
}
char *uiEntryText(uiEntry *e)
{
return uiHaikuStrdupText(e->tc->Text());
}
void uiEntrySetText(uiEntry *e, const char *text)
{
// TODO does this send a message?
e->tc->SetText(text);
}
void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *e, void *data), void *data)
{
e->onChanged = f;
e->onChangedData = data;
}
int uiEntryReadOnly(uiEntry *e)
{
// TODO
return 0;
}
void uiEntrySetReadOnly(uiEntry *e, int readonly)
{
// TODO
}
uiEntry *uiNewEntry(void)
{
uiEntry *e;
e = (uiEntry *) uiNewControl(uiEntryType());
e->tc = new BTextControl(NULL, "", new BMessage(mEntryChanged));
uiEntryOnChanged(e, defaultOnChanged, NULL);
uiHaikuFinishNewControl(e, uiEntry);
return e;
}

View File

@ -1,53 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiGroup {
uiHaikuControl c;
BStringView *dummy;
};
uiHaikuDefineControl(
uiGroup, // type name
uiGroupType, // type function
dummy // handle
)
char *uiGroupTitle(uiGroup *g)
{
// TODO
return NULL;
}
void uiGroupSetTitle(uiGroup *g, const char *title)
{
// TODO
}
void uiGroupSetChild(uiGroup *g, uiControl *c)
{
// TODO
}
int uiGroupMargined(uiGroup *g)
{
// TODO
return 0;
}
void uiGroupSetMargined(uiGroup *g, int margined)
{
// TODO
}
uiGroup *uiNewGroup(const char *title)
{
uiGroup *g;
g = (uiGroup *) uiNewControl(uiGroupType());
g->dummy = new BStringView(NULL, "TODO uiGroup not implemented");
uiHaikuFinishNewControl(g, uiGroup);
return g;
}

View File

@ -1,38 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
// TODO forcibly aligned to the bottom of the allocation
struct uiLabel {
uiHaikuControl c;
BStringView *label;
};
uiHaikuDefineControl(
uiLabel, // type name
uiLabelType, // type function
label // handle
)
char *uiLabelText(uiLabel *l)
{
return uiHaikuStrdupText(l->label->Text());
}
void uiLabelSetText(uiLabel *l, const char *text)
{
l->label->SetText(text);
}
uiLabel *uiNewLabel(const char *text)
{
uiLabel *l;
l = (uiLabel *) uiNewControl(uiLabelType());
l->label = new BStringView(NULL, text);
uiHaikuFinishNewControl(l, uiLabel);
return l;
}

View File

@ -1,51 +0,0 @@
// 17 november 2015
#include "uipriv_haiku.hpp"
static BApplication *app;
uiInitOptions options;
const char *uiInit(uiInitOptions *o)
{
status_t err;
options = *o;
// TODO properly set the MIME type
// TODO andlabs-libui?
app = new BApplication("application/x-vnd.andlabs.libui", &err);
if (err != B_NO_ERROR) {
delete app;
// TODO
return "fail";
}
initAlloc();
return NULL;
}
void uiUninit(void)
{
delete app;
uninitAlloc();
}
void uiFreeInitError(const char *err)
{
// TODO
}
void uiMain(void)
{
app->Run();
}
void uiQuit(void)
{
// TODO app->PostMessage(B_QUIT_REQUESTED);?
// TODO see window.cpp for why that alone won't work
app->Quit();
}
void uiQueueMain(void (*f)(void *data), void *data)
{
// TODO
}

View File

@ -1,69 +0,0 @@
// 19 november 2015
#include "uipriv_haiku.hpp"
void uiMenuItemEnable(uiMenuItem *m)
{
// TODO
}
void uiMenuItemDisable(uiMenuItem *m)
{
// TODO
}
void uiMenuItemOnClicked(uiMenuItem *m, void (*f)(uiMenuItem *sender, uiWindow *window, void *data), void *data)
{
// TODO
}
int uiMenuItemChecked(uiMenuItem *m)
{
// TODO
return 0;
}
void uiMenuItemSetChecked(uiMenuItem *m, int checked)
{
// TODO
}
uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
{
// TODO
return NULL;
}
uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name)
{
// TODO
return NULL;
}
uiMenuItem *uiMenuAppendQuitItem(uiMenu *m)
{
// TODO
return NULL;
}
uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m)
{
// TODO
return NULL;
}
uiMenuItem *uiMenuAppendAboutItem(uiMenu *m)
{
// TODO
return NULL;
}
void uiMenuAppendSeparator(uiMenu *m)
{
// TODO
}
uiMenu *uiNewMenu(const char *name)
{
// TODO
return NULL;
}

View File

@ -1,66 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiMultilineEntry {
uiHaikuControl c;
BStringView *dummy;
void (*onChanged)(uiMultilineEntry *, void *);
void *onChangedData;
};
uiHaikuDefineControl(
uiMultilineEntry, // type name
uiMultilineEntryType, // type function
dummy // handle
)
static void defaultOnChanged(uiMultilineEntry *e, void *data)
{
// do nothing
}
char *uiMultilineEntryText(uiMultilineEntry *e)
{
// TODO
return NULL;
}
void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text)
{
// TODO
}
void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text)
{
// TODO
}
void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *e, void *data), void *data)
{
e->onChanged = f;
e->onChangedData = data;
}
int uiMultilineEntryReadOnly(uiMultilineEntry *e)
{
// TODO
return 0;
}
void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly)
{
// TODO
}
uiMultilineEntry *uiNewMultilineEntry(void)
{
uiMultilineEntry *e;
e = (uiMultilineEntry *) uiNewControl(uiMultilineEntry());
e->dummy = new BStringView(NULL, "TODO uiMultilineEntry not implemented");
uiHaikuFinishNewControl(e, uiMultilineEntry);
return e;
}

View File

@ -1,6 +0,0 @@
https://www.haiku-os.org/blog/pulkomandy/2015-10-03_haiku_monthly_activity_report_092015
currently no way to automatically track UI color changes
new APIs will allow this seamlessly; investigate (after R1 alpha 5? since api.haiku-os.org isn't updated yet)
https://www.haiku-os.org/blog/pulkomandy/2015-08-29_haiku_monthly_activity_report_082015
do we actually need to set UI colors manually...?

View File

@ -1,33 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiProgressBar {
uiHaikuControl c;
BStatusBar *pbar;
};
uiHaikuDefineControl(
uiProgressBar, // type name
uiProgressBarType, // type function
pbar // handle
)
void uiProgressBarSetValue(uiProgressBar *p, int n)
{
// not on api.haiku-os.org
p->pbar->SetTo(n);
}
uiProgressBar *uiNewProgressBar(void)
{
uiProgressBar *p;
p = (uiProgressBar *) uiNewControl(uiProgressBarType());
// layout constructor; not on api.haiku-os.org
p->pbar = new BStatusBar(NULL, NULL, NULL);
uiHaikuFinishNewControl(p, uiProgressBar);
return p;
}

View File

@ -1,31 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiRadioButtons {
uiHaikuControl c;
BStringView *dummy;
};
uiHaikuDefineControl(
uiRadioButtons, // type name
uiRadioButtonsType, // type function
dummy // handle
)
void uiRadioButtonsAppend(uiRadioButtons *r, const char *text)
{
// TODO
}
uiRadioButtons *uiNewRadioButtons(void)
{
uiRadioButtons *r;
r = (uiRadioButtons *) uiNewControl(uiRadioButtonsType());
r->dummy = new BStringView(NULL, "TODO uiRadioButtons not implemented");
uiHaikuFinishNewControl(r, uiRadioButtons);
return r;
}

View File

@ -1,26 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiSeparator {
uiHaikuControl c;
BStringView *dummy;
};
uiHaikuDefineControl(
uiSeparator, // type name
uiSeparatorType, // type function
dummy // handle
)
uiSeparator *uiNewHorizontalSeparator(void)
{
uiSeparator *s;
s = (uiSeparator *) uiNewControl(uiSeparatorType());
s->dummy = new BStringView(NULL, "TODO uiSeparator not implemented");
uiHaikuFinishNewControl(s, uiSeparator);
return s;
}

View File

@ -1,77 +0,0 @@
// 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);
// A BLayout cannot add BViews unless it itself is in a BView for app_server-related reasons (thanks Skipp_OSX in irc.freenode.net/#haiku)
// TODO make this hook cleaner
(*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);
}

View File

@ -1,74 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
// TODO any of this on api.haiku-os.org?
// TODO tracking events?
struct uiSlider {
uiHaikuControl c;
BSlider *slider;
void (*onChanged)(uiSlider *, void *);
void *onChangedData;
};
uiHaikuDefineControl(
uiSlider, // type name
uiSliderType, // type function
slider // handle
)
#define mSliderChanged 0x6060FEFE
static void onChanged(BMessage *msg)
{
void *ss;
uiSlider *s;
// TODO error check
msg->FindPointer(mControlField, &ss);
s = uiSlider(ss);
(*(s->onChanged))(s, s->onChangedData);
}
static void defaultOnChanged(uiSlider *s, void *data)
{
// do nothing
}
intmax_t uiSliderValue(uiSlider *s)
{
return s->slider->Value();
}
void uiSliderSetValue(uiSlider *s, intmax_t value)
{
// TODO does this trigger an event?
s->slider->SetValue(value);
}
void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *s, void *data), void *data)
{
s->onChanged = f;
s->onChangedData = data;
}
uiSlider *uiNewSlider(intmax_t min, intmax_t max)
{
uiSlider *s;
BMessage *msg;
s = (uiSlider *) uiNewControl(uiSliderType());
uiHaikuRegisterEventHandler(mSliderChanged, onChanged);
msg = new BMessage(mSliderChanged);
msg->AddPointer(mControlField, s);
s->slider = new BSlider(NULL, NULL, msg,
min, max, B_HORIZONTAL);
uiSliderOnChanged(s, defaultOnChanged, NULL);
uiHaikuFinishNewControl(s, uiSlider);
return s;
}

View File

@ -1,42 +0,0 @@
// 18 november 2015
#include "uipriv_haiku.hpp"
struct uiSpinbox {
uiHaikuControl c;
BStringView *dummy;
};
uiHaikuDefineControl(
uiSpinbox, // type name
uiSpinboxType, // type function
dummy // handle
)
intmax_t uiSpinboxValue(uiSpinbox *s)
{
// TODO
return 0;
}
void uiSpinboxSetValue(uiSpinbox *s, intmax_t value)
{
// TODO
}
void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *s, void *data), void *data)
{
// TODO
}
uiSpinbox *uiNewSpinbox(intmax_t min, intmax_t max)
{
uiSpinbox *s;
s = (uiSpinbox *) uiNewControl(uiSpinboxType());
s->dummy = new BStringView(NULL, "TODO uiSpinbox not implemented");
uiHaikuFinishNewControl(s, uiSpinbox);
return s;
}

View File

@ -1,24 +0,0 @@
// 26 june 2015
#include "uipriv_haiku.hpp"
char *uiOpenFile(uiWindow *parent)
{
// TODO
return NULL;
}
char *uiSaveFile(uiWindow *parent)
{
// TODO
return NULL;
}
void uiMsgBox(uiWindow *parent, const char *title, const char *description)
{
// TODO
}
void uiMsgBoxError(uiWindow *parent, const char *title, const char *description)
{
// TODO
}

View File

@ -1,99 +0,0 @@
// 18 november 2015
#include <vector>
#include "uipriv_haiku.hpp"
using namespace std;
struct tabPage {
BTab *tab;
BView *view;
struct singleChild *child;
};
struct uiTab {
uiHaikuControl c;
BTabView *tabview;
vector<struct tabPage> *pages;
};
static void onDestroy(uiTab *);
uiHaikuDefineControlWithOnDestroy(
uiTab, // type name
uiTabType, // type function
tabview, // handle
onDestroy(hthis); // on destroy
)
static void onDestroy(uiTab *t)
{
// TODO
}
void uiTabAppend(uiTab *t, const char *name, uiControl *c)
{
uiTabInsertAt(t, name, t->pages->size(), c);
}
// see singlechild.cpp
static void attach(void *attachTo, BLayoutItem *what)
{
BView *view = (BView *) attachTo;
// TODO refine the interface around this
view->SetLayout((BLayout *) what);
}
void uiTabInsertAt(uiTab *t, const char *name, uintmax_t before, uiControl *c)
{
struct tabPage p;
p.view = new BView(NULL, B_SUPPORTS_LAYOUT);
// TODO needed?
p.view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
p.tab = new BTab(p.view);
p.child = newSingleChild(c, uiControl(t), attach, p.view);
p.tab->SetLabel(name);
// TODO insert in the correct place
t->tabview->AddTab(p.view, p.tab);
t->pages->push_back(p);
}
void uiTabDelete(uiTab *t, uintmax_t index)
{
// TODO
}
uintmax_t uiTabNumPages(uiTab *t)
{
// TODO
return 0;
}
int uiTabMargined(uiTab *t, uintmax_t page)
{
// TODO
return 0;
}
void uiTabSetMargined(uiTab *t, uintmax_t page, int margined)
{
// TODO
}
uiTab *uiNewTab(void)
{
uiTab *t;
t = (uiTab *) uiNewControl(uiTabType());
t->tabview = new BTabView(NULL, B_WIDTH_FROM_LABEL);
// TODO scrollable
t->pages = new vector<struct tabPage>();
uiHaikuFinishNewControl(t, uiTab);
return t;
}

View File

@ -1,15 +0,0 @@
// 9 april 2015
#include <cstdlib>
#include <cstring>
#include "uipriv_haiku.hpp"
using namespace std;
char *uiHaikuStrdupText(const char *t)
{
return strdup(t);
}
void uiFreeText(char *t)
{
free(t);
}

View File

@ -1,28 +0,0 @@
// 17 november 2015
// TODO versioning macros?
#include <AppKit.h>
#include <InterfaceKit.h>
#include <GroupLayout.h>
#include "../ui.h"
#include "../ui_haiku.hpp"
#include "../common/uipriv.h"
// 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);
// TODO make this public?
#define mControlField "libui_uiControl"
// TODO write helper functions?
// draw.cpp
extern uiDrawContext *newContext(BView *view);
extern void freeContext(uiDrawContext *c);

View File

@ -1,17 +0,0 @@
// 7 april 2015
#include <cstdio>
#include <cstdlib>
#include "uipriv_haiku.hpp"
using namespace std;
void complain(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "[libui] ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
abort();
}

View File

@ -1,210 +0,0 @@
// 18 november 2015
#include <map>
#include "uipriv_haiku.hpp"
using namespace std;
// TODOs:
// - Command+Q invariably quits; override that by catching the B_QUIT_REQUESTED in main.cpp
// - other global shortcuts that need to be handled by overriding DispatchMessage() (NOT MessageReceived()) when adding uiArea event handling
class libuiBWindow : public BWindow {
public:
// C++11! Inherit constructors.
using BWindow::BWindow;
virtual void MessageReceived(BMessage *);
uiWindow *w;
virtual bool QuitRequested();
};
struct uiWindow {
uiHaikuControl c;
libuiBWindow *window;
BGroupLayout *vbox;
struct singleChild *child;
int margined;
int (*onClosing)(uiWindow *, void *);
void *onClosingData;
};
uiHaikuDefineControlWithOnDestroy(
uiWindow, // type name
uiWindowType, // type function
window, // handle
complain("attempt to use default CommitDestroy() code for uiWindow on Haiku"); // on destroy
)
static map<uint32, void (*)(BMessage *)> eventHandlers;
typedef map<uint32, void (*)(BMessage *)>::const_iterator eventHandlerIter;
void uiHaikuRegisterEventHandler(uint32 what, void (*handler)(BMessage *))
{
eventHandlerIter iter;
// TODO decide a convention for libui internal messages
iter = eventHandlers.find(what);
if (iter == eventHandlers.end()) { // new entry
eventHandlers[what] = handler;
return;
}
if (iter->second != handler) // mismatch
complain("attempt to clobber BMessage::what 0x%08X in uiHaikuRegisterEventHandler()", what);
}
void libuiBWindow::MessageReceived(BMessage *msg)
{
eventHandlerIter iter;
// handle registered events
iter = eventHandlers.find(msg->what);
if (iter != eventHandlers.end()) {
(*(iter->second))(msg);
return;
}
// no event found; defer to BWindow
this->BWindow::MessageReceived(msg);
}
bool libuiBWindow::QuitRequested()
{
// manually destroy the window ourselves; don't let the default BWindow code do it directly
if ((*(this->w->onClosing))(this->w, this->w->onClosingData))
uiControlDestroy(uiControl(this->w));
// don't continue to the default BWindow code; we destroyed the window by now
return false;
}
static int defaultOnClosing(uiWindow *w, void *data)
{
return 0;
}
static void windowCommitDestroy(uiControl *c)
{
uiWindow *w = uiWindow(c);
// first hide ourselves
w->window->Hide();
// now destroy the 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? or use B_QUIT_REQUESTED?
w->window->Lock();
w->window->Quit();
// w->window is now destroyed for us
}
// The default implementations assume a BView, which a uiWindow is not.
static void windowCommitShow(uiControl *c)
{
uiWindow *w = uiWindow(c);
// This is documented as behaving how we want with regards to presentation.
w->window->Show();
}
static void windowCommitHide(uiControl *c)
{
uiWindow *w = uiWindow(c);
w->window->Hide();
}
static void windowContainerUpdateState(uiControl *c)
{
uiWindow *w = uiWindow(c);
if (w->child != NULL)
singleChildUpdateState(w->child);
}
char *uiWindowTitle(uiWindow *w)
{
return uiHaikuStrdupText(w->window->Title());
}
void uiWindowSetTitle(uiWindow *w, const char *title)
{
w->window->SetTitle(title);
// don't queue resize; the caption isn't part of what affects layout and sizing of the client area (it'll be ellipsized if too long)
}
void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
{
w->onClosing = f;
w->onClosingData = data;
}
// 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->vbox->RemoveItem(singleChildLayoutItem(w->child));
singleChildRemove(w->child);
}
w->child = newSingleChild(child, uiControl(w), attach, w->vbox);
if (w->child != NULL)
uiWindowSetMargined(w, w->margined);
}
int uiWindowMargined(uiWindow *w)
{
return w->margined;
}
void uiWindowSetMargined(uiWindow *w, int margined)
{
w->margined = margined;
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)
{
uiWindow *w;
w = (uiWindow *) uiNewControl(uiWindowType());
// TODO find out how to make it ignore position
// The given rect is the size of the inside of the window, just as we want.
w->window = new libuiBWindow(
BRect(100, 100, width, height),
title,
B_TITLED_WINDOW,
// TODO B_AUTO_UPDATE_SIZE_LIMITS?
// TODO if we do this we need to set the maximum size to arbitrary (TODO always? check GTK+ and OS X)
B_ASYNCHRONOUS_CONTROLS);
w->window->w = w;
w->vbox = new BGroupLayout(B_VERTICAL, 0);
w->window->SetLayout(w->vbox);
// Haiku itself does this, with a TODO
w->vbox->Owner()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
uiWindowOnClosing(w, defaultOnClosing, NULL);
uiHaikuFinishNewControl(w, uiWindow);
uiControl(w)->CommitDestroy = windowCommitDestroy;
uiControl(w)->CommitShow = windowCommitShow;
uiControl(w)->CommitHide = windowCommitHide;
uiControl(w)->ContainerUpdateState = windowContainerUpdateState;
return w;
}

BIN
oldhaiku.tgz Normal file

Binary file not shown.

View File

@ -1,60 +0,0 @@
// 17 november 2015
/*
This file assumes that you have included the various Haiku header files and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls in Haiku.
*/
#ifndef __LIBUI_UI_HAIKU_HPP__
#define __LIBUI_UI_WAIKU_HPP__
#ifndef __cplusplus
#error Sorry; ui_haiku.hpp can currently only be used from C++ code.
#endif
extern "C" {
typedef struct uiHaikuControl uiHaikuControl;
struct uiHaikuControl {
uiControl c;
};
#define uiHaikuControl(this) ((uiHaikuControl *) (this))
// TODO document
#define uiHaikuDefineControlWithOnDestroy(type, handlefield, onDestroy) \
static void _ ## type ## CommitDestroy(uiControl *c) \
{ \
type *hthis = type(c); \
onDestroy; \
delete hthis->handlefield; \
} \
static uintptr_t _ ## type ## Handle(uiControl *c) \
{ \
return (uintptr_t) (type(c)->handlefield); \
} \
static void _ ## type ## ContainerUpdateState(uiControl *c) \
{ \
/* do nothing */ \
}
#define uiHaikuDefineControl(type, handlefield) \
uiHaikuDefineControlWithOnDestroy(type, handlefield, (void) hthis;)
#define uiHaikuFinishNewControl(variable, type) \
uiControl(variable)->CommitDestroy = _ ## type ## CommitDestroy; \
uiControl(variable)->Handle = _ ## type ## Handle; \
uiControl(variable)->ContainerUpdateState = _ ## type ## ContainerUpdateState; \
uiHaikuFinishControl(uiControl(variable));
// This is a function used to set up a control.
// Don't call it directly; use uiHaikuFinishNewControl() instead.
_UI_EXTERN void uiHaikuFinishControl(uiControl *c);
// TODO document this
_UI_EXTERN void uiHaikuRegisterEventHandler(uint32 what, void (*handler)(BMessage *));
// uiHaikuStrdupText() takes the given string and produces a copy of it suitable for being freed by uiFreeText().
_UI_EXTERN char *uiHaikuStrdupText(const char *);
}
#endif