2015-11-18 10:35:43 -06:00
|
|
|
// 18 november 2015
|
|
|
|
#include "uipriv_haiku.hpp"
|
|
|
|
|
|
|
|
class libuiBWindow : public BWindow {
|
|
|
|
public:
|
|
|
|
// C++11! Inherit constructors.
|
|
|
|
using BWindow::BWindow;
|
|
|
|
|
|
|
|
uiWindow *w;
|
|
|
|
virtual bool QuitRequested();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct uiWindow {
|
|
|
|
uiHaikuControl c;
|
|
|
|
|
|
|
|
libuiBWindow *window;
|
|
|
|
|
2015-11-18 14:47:15 -06:00
|
|
|
BGroupLayout *vbox;
|
|
|
|
|
2015-11-18 10:35:43 -06:00
|
|
|
struct child *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
|
|
|
|
)
|
|
|
|
|
|
|
|
// TODO is this correct?
|
|
|
|
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
|
|
|
|
//TODO if (w->child != NULL)
|
|
|
|
//TODO childDestroy(w->child);
|
|
|
|
// and finally destroy ourselves
|
|
|
|
// this is why we don't use the libui-provided CommitDestroy() implementation
|
2015-11-18 10:51:54 -06:00
|
|
|
// TODO check this for errors?
|
2015-11-18 10:35:43 -06:00
|
|
|
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)
|
|
|
|
{
|
|
|
|
/*TODO
|
|
|
|
uiWindow *w = uiWindow(c);
|
|
|
|
|
|
|
|
if (w->child != NULL)
|
|
|
|
childUpdateState(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;
|
|
|
|
}
|
|
|
|
|
|
|
|
void uiWindowSetChild(uiWindow *w, uiControl *child)
|
|
|
|
{
|
|
|
|
/*TODO
|
|
|
|
if (w->child != NULL)
|
|
|
|
childDestroy(w->child);
|
|
|
|
w->child = newChildWithBox(child, uiControl(w), w->vboxContainer, w->margined);
|
|
|
|
if (w->child != NULL) {
|
|
|
|
gtk_widget_set_hexpand(childBox(w->child), TRUE);
|
|
|
|
gtk_widget_set_halign(childBox(w->child), GTK_ALIGN_FILL);
|
|
|
|
gtk_widget_set_vexpand(childBox(w->child), TRUE);
|
|
|
|
gtk_widget_set_valign(childBox(w->child), GTK_ALIGN_FILL);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
int uiWindowMargined(uiWindow *w)
|
|
|
|
{
|
|
|
|
return w->margined;
|
|
|
|
}
|
|
|
|
|
|
|
|
void uiWindowSetMargined(uiWindow *w, int margined)
|
|
|
|
{
|
|
|
|
w->margined = margined;
|
|
|
|
//TODO if (w->child != NULL)
|
|
|
|
//TODO childSetMargined(w->child, w->margined);
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
B_ASYNCHRONOUS_CONTROLS);
|
2015-11-18 10:43:22 -06:00
|
|
|
w->window->w = w;
|
2015-11-18 10:35:43 -06:00
|
|
|
|
2015-11-18 14:47:15 -06:00
|
|
|
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));
|
|
|
|
|
2015-11-18 10:35:43 -06:00
|
|
|
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;
|
|
|
|
}
|