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