Wrote up the event handling code for Haiku.

This commit is contained in:
Pietro Gagliardi 2015-11-20 11:45:04 -05:00
parent 48d014e762
commit 1a70407be2
5 changed files with 60 additions and 1 deletions

View File

@ -16,6 +16,17 @@ uiHaikuDefineControl(
#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
@ -40,10 +51,15 @@ void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *b, void *data), void *da
uiButton *uiNewButton(const char *text)
{
uiButton *b;
BMessage *msg;
b = (uiButton *) uiNewControl(uiButtonType());
b->button = new BButton(text, new BMessage(mButtonClicked));
uiHaikuRegisterEventHandler(mButtonClicked, onClicked);
msg = new BMessage(mButtonClicked);
msg->AddPointer(mControlField, b);
b->button = new BButton(text, msg);
// TODO hook up events
uiButtonOnClicked(b, defaultOnClicked, NULL);

View File

@ -11,6 +11,7 @@ const char *uiInit(uiInitOptions *o)
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;

View File

@ -18,3 +18,7 @@ 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?

View File

@ -1,11 +1,15 @@
// 18 november 2015
#include <map>
#include "uipriv_haiku.hpp"
using namespace std;
class libuiBWindow : public BWindow {
public:
// C++11! Inherit constructors.
using BWindow::BWindow;
virtual void MessageReceived(BMessage *);
uiWindow *w;
virtual bool QuitRequested();
};
@ -31,6 +35,37 @@ uiHaikuDefineControlWithOnDestroy(
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

View File

@ -57,6 +57,9 @@ _UI_EXTERN uintmax_t uiHaikuControlType(void);
// 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 *);