should work now

This commit is contained in:
Nishi 2026-04-20 05:29:42 +09:00
commit 2514a1b2fc
Signed by: nishi
GPG key ID: 27EF69B208EB9343
25 changed files with 325 additions and 6 deletions

View file

@ -19,7 +19,7 @@ format:
OBJS = src/core.o src/widget/base.o
include objs.mk
test$(EXEC): test.o
test$(EXEC): test.o libMwCXX$(SO)
$(CXX) -L. -Wl,-R$(MILSKO)/src -Wl,-R$(MILSKO)/lib -Wl,-R. -o $@ test.o -lMwCXX
bindgen$(EXEC): bindgen.o

View file

@ -268,15 +268,124 @@ static std::string scan_widget_handler_source(xl_node_t* node, std::string widge
return widget_handler_source(widget, xl_get_attribute(node, "name"));
}
static std::string widget_function_header(xl_node_t* node, std::string indent, std::string prefix = "", int func = 1, xl_node_t** pret = NULL, xl_node_t** pargs = NULL) {
std::stringstream strm;
xl_node_t* child;
xl_node_t* ret = NULL;
xl_node_t* args = NULL;
int c = 0;
if(node->type != XL_NODE_NODE) return "";
for(child = node->first_child; child != NULL; child = child->next) {
if(child->type != XL_NODE_NODE) continue;
if(strcmp(child->name, "return") == 0) {
for(ret = child->first_child; ret != NULL; ret = ret->next) {
if(ret->type == XL_NODE_NODE) break;
}
} else if(strcmp(child->name, "arguments") == 0) {
args = child->first_child;
}
}
if(pret != NULL) *pret = ret;
if(pargs != NULL) *pargs = args;
strm << indent;
if(ret == NULL) {
strm << "void ";
} else {
strm << get_ctype(xml_to_type(ret)) + " ";
}
strm << prefix + std::string(xl_get_attribute(node, "name")) + "(";
c = 0;
for(child = args; child != NULL; child = child->next) {
if(child->type != XL_NODE_NODE) continue;
if(c > 0) strm << ", ";
strm << get_ctype(xml_to_type(child));
c++;
}
strm << ")";
if(func) strm << ";";
strm << std::endl;
return strm.str();
}
static std::string widget_function_source(xl_node_t* node, std::string widget) {
std::stringstream strm;
xl_node_t* child;
std::string rettype = "";
xl_node_t* ret = NULL;
xl_node_t* args = NULL;
typeinfo retti;
strm << widget_function_header(node, "", "MwCXX::" + widget + "::", 0, &ret, &args) + " {" << std::endl;
if(ret != NULL) {
retti = xml_to_type(ret);
rettype = get_ctype(retti, 0, 0);
if(rettype == "MwCXX::String") rettype = "char*";
if(retti.pointer) rettype += "*";
}
if(rettype != "") {
strm << " " + rettype + " out;" << std::endl;
strm << std::endl;
}
strm << " MwVaWidgetExecute(this->widget, \"mw" + widget + std::string(xl_get_attribute(node, "name")) + "\", ";
if(rettype == "") {
strm << "NULL";
} else {
strm << "&out";
}
for(child = args; child != NULL; child = child->next) {
typeinfo ti = xml_to_type(child);
if(ti.type == "string") {
strm << "," << std::endl;
strm << "#ifdef MWCXX_USE_C_STRING" << std::endl;
strm << " " + ti.name << std::endl;
strm << "#else" << std::endl;
strm << " " + ti.name + ".c_str()" << std::endl;
strm << "#endif" << std::endl;
} else {
strm << ", " + ti.name;
}
}
strm << " );" << std::endl;
if(rettype != "") {
strm << std::endl;
if(retti.type == "string") {
strm << "#ifdef MWCXX_USE_C_STRING" << std::endl;
strm << " return out;" << std::endl;
strm << "#else" << std::endl;
strm << " return MwCXX::String(out);" << std::endl;
strm << "#endif" << std::endl;
} else {
strm << " return out;" << std::endl;
}
}
strm << "}" << std::endl;
strm << std::endl;
return strm.str();
}
static void scan_widget(xl_node_t* node) {
std::string name;
xl_node_t** p_nodes;
xl_node_t** h_nodes;
xl_node_t** f_nodes;
if(node->type != XL_NODE_NODE) return;
p_nodes = xl_get_path(node, "properties");
h_nodes = xl_get_path(node, "handlers");
f_nodes = xl_get_path(node, "functions");
name = xl_get_attribute(node, "name");
@ -343,6 +452,21 @@ static void scan_widget(xl_node_t* node) {
<< r;
}
if(f_nodes != NULL) {
std::string r;
r = "";
for(int i = 0; f_nodes[i] != NULL; i++) {
for(xl_node_t* child = f_nodes[i]->first_child; child != NULL; child = child->next) {
if(child->type != XL_NODE_NODE) continue;
r += widget_function_header(child, "\t\t");
}
}
if(r != "") OFS << std::endl
<< r;
}
OFS << " };" << std::endl;
OFS << "}; // namespace MwCXX" << std::endl;
@ -423,11 +547,23 @@ static void scan_widget(xl_node_t* node) {
}
}
OFS << "}" << std::endl;
OFS << std::endl;
if(f_nodes != NULL) {
for(int i = 0; f_nodes[i] != NULL; i++) {
for(xl_node_t* child = f_nodes[i]->first_child; child != NULL; child = child->next) {
if(child->type != XL_NODE_NODE) continue;
OFS << widget_function_source(child, name);
}
}
}
#undef OFS
if(p_nodes != NULL) free(p_nodes);
if(h_nodes != NULL) free(h_nodes);
if(f_nodes != NULL) free(f_nodes);
files["objs"] << " src/widget/" + lowercase(name) + ".o";
}

View file

@ -23,6 +23,8 @@ namespace MwCXX {
virtual void OnComboBoxChanged(int value) {};
void (*ComboBoxChangedHandler)(MwCXX::ComboBox* widget, int value);
void Add();
};
}; // namespace MwCXX

View file

@ -27,6 +27,8 @@ namespace MwCXX {
void SetLength(int value);
int GetLeftPadding();
void SetLeftPadding(int value);
void SetSevenSegment(int index, int data);
};
}; // namespace MwCXX

View file

@ -25,6 +25,13 @@ namespace MwCXX {
virtual void OnListBoxActivate(int value) {};
void (*ListBoxActivateHandler)(MwCXX::ListBox* widget, int value);
int Set(int row, int col, MwCXX::String text);
void SetIcon(int index, MwLLPixmap icon);
void Delete(int index);
MwCXX::String Get(int index);
void SetWidth(int index, int width);
void Reset();
};
}; // namespace MwCXX

View file

@ -18,6 +18,8 @@ namespace MwCXX {
virtual void OnMenu(void* value) {};
void (*MenuHandler)(MwCXX::Menu* widget, void* value);
void* Add(void* menu, MwCXX::String name);
};
}; // namespace MwCXX

View file

@ -14,6 +14,10 @@ namespace MwCXX {
public:
OpenGL(MwWidget widget, MwCXX::Base* parent = NULL);
OpenGL(MwCXX::String name, MwCXX::Base* parent, int x, int y, unsigned int width, unsigned int height);
void MakeCurrent();
void* GetProcAddress(MwCXX::String name);
void SwapBuffer();
};
}; // namespace MwCXX

View file

@ -31,6 +31,8 @@ namespace MwCXX {
virtual void OnChanged() {};
void (*ChangedHandler)(MwCXX::ScrollBar* widget);
int GetVisibleLength();
};
}; // namespace MwCXX

View file

@ -17,6 +17,9 @@ namespace MwCXX {
int GetLeftPadding();
void SetLeftPadding(int value);
void Appear(void* menu, MwPoint* point, int diff_calc);
void GetSize(void* menu, MwRect* rect);
};
}; // namespace MwCXX

View file

@ -23,6 +23,10 @@ namespace MwCXX {
virtual void OnTreeViewActivate(void* value) {};
void (*TreeViewActivateHandler)(MwCXX::TreeView* widget, void* value);
void Add(void* parent, MwLLPixmap pixmap, MwCXX::String item);
void Delete(void* item);
void Reset();
};
}; // namespace MwCXX

View file

@ -14,6 +14,9 @@ namespace MwCXX {
public:
Viewport(MwWidget widget, MwCXX::Base* parent = NULL);
Viewport(MwCXX::String name, MwCXX::Base* parent, int x, int y, unsigned int width, unsigned int height);
MwCXX::Base* GetViewport();
void SetSize(int w, int h);
};
}; // namespace MwCXX

View file

@ -14,6 +14,8 @@ namespace MwCXX {
public:
Vulkan(MwWidget widget, MwCXX::Base* parent = NULL);
Vulkan(MwCXX::String name, MwCXX::Base* parent, int x, int y, unsigned int width, unsigned int height);
void* GetField(int field, int* output);
};
}; // namespace MwCXX

View file

@ -37,6 +37,8 @@ namespace MwCXX {
void (*FileChosenHandler)(MwCXX::Window* widget, MwCXX::String value);
void (*DirectoryChosenHandler)(MwCXX::Window* widget, MwCXX::String value);
void (*CloseHandler)(MwCXX::Window* widget);
void MakeBorderless();
};
}; // namespace MwCXX

View file

@ -36,3 +36,7 @@ void MwCXX::ComboBox::RegisterHandlers() {
this->ComboBoxChangedHandler = NULL;
}
void MwCXX::ComboBox::Add() {
MwVaWidgetExecute(this->widget, "mwComboBoxAdd", NULL);
}

View file

@ -64,3 +64,7 @@ void MwCXX::Label::SetLeftPadding(int value) {
void MwCXX::Label::RegisterHandlers() {
}
void MwCXX::Label::SetSevenSegment(int index, int data) {
MwVaWidgetExecute(this->widget, "mwLabelSetSevenSegment", NULL, index, data);
}

View file

@ -44,3 +44,45 @@ void MwCXX::ListBox::RegisterHandlers() {
this->ListBoxActivateHandler = NULL;
}
int MwCXX::ListBox::Set(int row, int col, MwCXX::String text) {
int out;
MwVaWidgetExecute(this->widget, "mwListBoxSet", &out, row, col,
#ifdef MWCXX_USE_C_STRING
text
#else
text.c_str()
#endif
);
return out;
}
void MwCXX::ListBox::SetIcon(int index, MwLLPixmap icon) {
MwVaWidgetExecute(this->widget, "mwListBoxSetIcon", NULL, index, icon);
}
void MwCXX::ListBox::Delete(int index) {
MwVaWidgetExecute(this->widget, "mwListBoxDelete", NULL, index);
}
MwCXX::String MwCXX::ListBox::Get(int index) {
char* out;
MwVaWidgetExecute(this->widget, "mwListBoxGet", &out, index);
#ifdef MWCXX_USE_C_STRING
return out;
#else
return MwCXX::String(out);
#endif
}
void MwCXX::ListBox::SetWidth(int index, int width) {
MwVaWidgetExecute(this->widget, "mwListBoxSetWidth", NULL, index, width);
}
void MwCXX::ListBox::Reset() {
MwVaWidgetExecute(this->widget, "mwListBoxReset", NULL);
}

View file

@ -20,3 +20,17 @@ void MwCXX::Menu::RegisterHandlers() {
this->MenuHandler = NULL;
}
void* MwCXX::Menu::Add(void* menu, MwCXX::String name) {
void* out;
MwVaWidgetExecute(this->widget, "mwMenuAdd", &out, menu,
#ifdef MWCXX_USE_C_STRING
name
#else
name.c_str()
#endif
);
return out;
}

View file

@ -13,3 +13,25 @@ MwCXX::OpenGL::OpenGL(MwCXX::String name, MwCXX::Base* parent, int x, int y, uns
void MwCXX::OpenGL::RegisterHandlers() {
}
void MwCXX::OpenGL::MakeCurrent() {
MwVaWidgetExecute(this->widget, "mwOpenGLMakeCurrent", NULL);
}
void* MwCXX::OpenGL::GetProcAddress(MwCXX::String name) {
void* out;
MwVaWidgetExecute(this->widget, "mwOpenGLGetProcAddress", &out,
#ifdef MWCXX_USE_C_STRING
name
#else
name.c_str()
#endif
);
return out;
}
void MwCXX::OpenGL::SwapBuffer() {
MwVaWidgetExecute(this->widget, "mwOpenGLSwapBuffer", NULL);
}

View file

@ -68,3 +68,11 @@ void MwCXX::ScrollBar::RegisterHandlers() {
this->ChangedHandler = NULL;
}
int MwCXX::ScrollBar::GetVisibleLength() {
int out;
MwVaWidgetExecute(this->widget, "mwScrollBarGetVisibleLength", &out);
return out;
}

View file

@ -20,3 +20,11 @@ void MwCXX::SubMenu::SetLeftPadding(int value) {
void MwCXX::SubMenu::RegisterHandlers() {
}
void MwCXX::SubMenu::Appear(void* menu, MwPoint* point, int diff_calc) {
MwVaWidgetExecute(this->widget, "mwSubMenuAppear", NULL, menu, point, diff_calc);
}
void MwCXX::SubMenu::GetSize(void* menu, MwRect* rect) {
MwVaWidgetExecute(this->widget, "mwSubMenuGetSize", NULL, menu, rect);
}

View file

@ -36,3 +36,21 @@ void MwCXX::TreeView::RegisterHandlers() {
this->TreeViewActivateHandler = NULL;
}
void MwCXX::TreeView::Add(void* parent, MwLLPixmap pixmap, MwCXX::String item) {
MwVaWidgetExecute(this->widget, "mwTreeViewAdd", NULL, parent, pixmap,
#ifdef MWCXX_USE_C_STRING
item
#else
item.c_str()
#endif
);
}
void MwCXX::TreeView::Delete(void* item) {
MwVaWidgetExecute(this->widget, "mwTreeViewDelete", NULL, item);
}
void MwCXX::TreeView::Reset() {
MwVaWidgetExecute(this->widget, "mwTreeViewReset", NULL);
}

View file

@ -12,3 +12,15 @@ MwCXX::Viewport::Viewport(MwCXX::String name, MwCXX::Base* parent, int x, int y,
void MwCXX::Viewport::RegisterHandlers() {
}
MwCXX::Base* MwCXX::Viewport::GetViewport() {
MwCXX::Base* out;
MwVaWidgetExecute(this->widget, "mwViewportGetViewport", &out);
return out;
}
void MwCXX::Viewport::SetSize(int w, int h) {
MwVaWidgetExecute(this->widget, "mwViewportSetSize", NULL, w, h);
}

View file

@ -13,3 +13,11 @@ MwCXX::Vulkan::Vulkan(MwCXX::String name, MwCXX::Base* parent, int x, int y, uns
void MwCXX::Vulkan::RegisterHandlers() {
}
void* MwCXX::Vulkan::GetField(int field, int* output) {
void* out;
MwVaWidgetExecute(this->widget, "mwVulkanGetField", &out, field, output);
return out;
}

View file

@ -93,3 +93,7 @@ void MwCXX::Window::RegisterHandlers() {
this->DirectoryChosenHandler = NULL;
this->CloseHandler = NULL;
}
void MwCXX::Window::MakeBorderless() {
MwVaWidgetExecute(this->widget, "mwWindowMakeBorderless", NULL);
}

16
test.cc
View file

@ -1,12 +1,13 @@
#include <MwCXX/Core.h>
#include <MwCXX/Widget/Window.h>
#include <MwCXX/Widget/Button.h>
#include <MwCXX/Widget/ListBox.h>
#include <MwCXX/Dialog/MessageBox.h>
#include <iostream>
/* Note: Since C++ binding does not know when dialog gets freed - you should listen to CloseHandler for dialogs, and destroy widget */
static void close_msg(MwCXX::Window* window){
static void close_msg(MwCXX::Window* window) {
delete window;
}
@ -21,7 +22,7 @@ class MyButton : public MwCXX::Button {
msg = MwCXX::MessageBox(this->GetParent(), "Hello", "Hello world", MwMB_BUTTONOK | MwMB_ICONNEWS);
msg->CloseHandler = close_msg;
msg->CloseHandler = close_msg;
MwCXX::MessageBoxGetChild(msg, MwMB_BUTTONOK)->ActivateHandler = close_msg;
}
@ -33,10 +34,12 @@ class MyButton : public MwCXX::Button {
class MyWindow : public MwCXX::Window {
private:
MyButton* epic;
MyButton* epic;
MwCXX::ListBox* epic2;
protected:
void OnResize() {
void
OnResize() {
MwRect rc = this->GetArea();
this->epic->Resize(rc.width - 20, rc.height - 20);
@ -44,7 +47,10 @@ class MyWindow : public MwCXX::Window {
public:
MWCXX_CONSTRUCTOR(MyWindow, MwCXX::Window) {
this->epic = new MyButton("epic app", this, 10, 10, 640 - 10 * 2, 480 - 10 * 2);
this->epic = new MyButton("epic app", this, 10, 10, 640 - 10 * 2, 240 - 10);
this->epic2 = new MwCXX::ListBox("epic app", this, 10, 10 + 240 - 10, 640 - 10 * 2, 240 - 10);
this->epic2->Set(-1, 0, "Test");
}
};