Discontinued the Haiku port for now.
This commit is contained in:
parent
46391367fe
commit
6f46bea054
|
@ -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)
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
151
haiku/box.cpp
151
haiku/box.cpp
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
407
haiku/draw.cpp
407
haiku/draw.cpp
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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...?
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
|
@ -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();
|
||||
}
|
210
haiku/window.cpp
210
haiku/window.cpp
|
@ -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;
|
||||
}
|
Binary file not shown.
60
ui_haiku.hpp
60
ui_haiku.hpp
|
@ -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
|
Loading…
Reference in New Issue