diff --git a/Makefile b/Makefile index cb82e15..c414815 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/bindgen.cc b/bindgen.cc index 52a14e1..0ec1ab8 100644 --- a/bindgen.cc +++ b/bindgen.cc @@ -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"; } diff --git a/include/MwCXX/Widget/ComboBox.h b/include/MwCXX/Widget/ComboBox.h index 5f58ef2..dd71b63 100644 --- a/include/MwCXX/Widget/ComboBox.h +++ b/include/MwCXX/Widget/ComboBox.h @@ -23,6 +23,8 @@ namespace MwCXX { virtual void OnComboBoxChanged(int value) {}; void (*ComboBoxChangedHandler)(MwCXX::ComboBox* widget, int value); + + void Add(); }; }; // namespace MwCXX diff --git a/include/MwCXX/Widget/Label.h b/include/MwCXX/Widget/Label.h index 716b8f9..6707b71 100644 --- a/include/MwCXX/Widget/Label.h +++ b/include/MwCXX/Widget/Label.h @@ -27,6 +27,8 @@ namespace MwCXX { void SetLength(int value); int GetLeftPadding(); void SetLeftPadding(int value); + + void SetSevenSegment(int index, int data); }; }; // namespace MwCXX diff --git a/include/MwCXX/Widget/ListBox.h b/include/MwCXX/Widget/ListBox.h index 1f02b7d..7088ec0 100644 --- a/include/MwCXX/Widget/ListBox.h +++ b/include/MwCXX/Widget/ListBox.h @@ -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 diff --git a/include/MwCXX/Widget/Menu.h b/include/MwCXX/Widget/Menu.h index ce3e08a..b5f1d82 100644 --- a/include/MwCXX/Widget/Menu.h +++ b/include/MwCXX/Widget/Menu.h @@ -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 diff --git a/include/MwCXX/Widget/OpenGL.h b/include/MwCXX/Widget/OpenGL.h index 75e2251..9eaf394 100644 --- a/include/MwCXX/Widget/OpenGL.h +++ b/include/MwCXX/Widget/OpenGL.h @@ -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 diff --git a/include/MwCXX/Widget/ScrollBar.h b/include/MwCXX/Widget/ScrollBar.h index f01af73..2fdd9e6 100644 --- a/include/MwCXX/Widget/ScrollBar.h +++ b/include/MwCXX/Widget/ScrollBar.h @@ -31,6 +31,8 @@ namespace MwCXX { virtual void OnChanged() {}; void (*ChangedHandler)(MwCXX::ScrollBar* widget); + + int GetVisibleLength(); }; }; // namespace MwCXX diff --git a/include/MwCXX/Widget/SubMenu.h b/include/MwCXX/Widget/SubMenu.h index 4c807b5..cb23ddc 100644 --- a/include/MwCXX/Widget/SubMenu.h +++ b/include/MwCXX/Widget/SubMenu.h @@ -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 diff --git a/include/MwCXX/Widget/TreeView.h b/include/MwCXX/Widget/TreeView.h index a2f4752..44bf04c 100644 --- a/include/MwCXX/Widget/TreeView.h +++ b/include/MwCXX/Widget/TreeView.h @@ -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 diff --git a/include/MwCXX/Widget/Viewport.h b/include/MwCXX/Widget/Viewport.h index 24fef87..794d964 100644 --- a/include/MwCXX/Widget/Viewport.h +++ b/include/MwCXX/Widget/Viewport.h @@ -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 diff --git a/include/MwCXX/Widget/Vulkan.h b/include/MwCXX/Widget/Vulkan.h index cf0bd2e..5f87621 100644 --- a/include/MwCXX/Widget/Vulkan.h +++ b/include/MwCXX/Widget/Vulkan.h @@ -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 diff --git a/include/MwCXX/Widget/Window.h b/include/MwCXX/Widget/Window.h index c31603b..c44b5b7 100644 --- a/include/MwCXX/Widget/Window.h +++ b/include/MwCXX/Widget/Window.h @@ -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 diff --git a/src/widget/combobox.cc b/src/widget/combobox.cc index 2d4986e..1203a2e 100644 --- a/src/widget/combobox.cc +++ b/src/widget/combobox.cc @@ -36,3 +36,7 @@ void MwCXX::ComboBox::RegisterHandlers() { this->ComboBoxChangedHandler = NULL; } + +void MwCXX::ComboBox::Add() { + MwVaWidgetExecute(this->widget, "mwComboBoxAdd", NULL); +} diff --git a/src/widget/label.cc b/src/widget/label.cc index 5128489..74c7b91 100644 --- a/src/widget/label.cc +++ b/src/widget/label.cc @@ -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); +} diff --git a/src/widget/listbox.cc b/src/widget/listbox.cc index b7283f9..bc014ee 100644 --- a/src/widget/listbox.cc +++ b/src/widget/listbox.cc @@ -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); +} diff --git a/src/widget/menu.cc b/src/widget/menu.cc index 169be72..91f2e9c 100644 --- a/src/widget/menu.cc +++ b/src/widget/menu.cc @@ -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; +} diff --git a/src/widget/opengl.cc b/src/widget/opengl.cc index b93feb1..3c52aee 100644 --- a/src/widget/opengl.cc +++ b/src/widget/opengl.cc @@ -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); +} diff --git a/src/widget/scrollbar.cc b/src/widget/scrollbar.cc index 34337cc..8b1adb0 100644 --- a/src/widget/scrollbar.cc +++ b/src/widget/scrollbar.cc @@ -68,3 +68,11 @@ void MwCXX::ScrollBar::RegisterHandlers() { this->ChangedHandler = NULL; } + +int MwCXX::ScrollBar::GetVisibleLength() { + int out; + + MwVaWidgetExecute(this->widget, "mwScrollBarGetVisibleLength", &out); + + return out; +} diff --git a/src/widget/submenu.cc b/src/widget/submenu.cc index 2c14776..191e574 100644 --- a/src/widget/submenu.cc +++ b/src/widget/submenu.cc @@ -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); +} diff --git a/src/widget/treeview.cc b/src/widget/treeview.cc index 5d4d8ec..2167f14 100644 --- a/src/widget/treeview.cc +++ b/src/widget/treeview.cc @@ -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); +} diff --git a/src/widget/viewport.cc b/src/widget/viewport.cc index 5842042..9036917 100644 --- a/src/widget/viewport.cc +++ b/src/widget/viewport.cc @@ -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); +} diff --git a/src/widget/vulkan.cc b/src/widget/vulkan.cc index abce262..71b73bc 100644 --- a/src/widget/vulkan.cc +++ b/src/widget/vulkan.cc @@ -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; +} diff --git a/src/widget/window.cc b/src/widget/window.cc index 80416a3..7bd97d6 100644 --- a/src/widget/window.cc +++ b/src/widget/window.cc @@ -93,3 +93,7 @@ void MwCXX::Window::RegisterHandlers() { this->DirectoryChosenHandler = NULL; this->CloseHandler = NULL; } + +void MwCXX::Window::MakeBorderless() { + MwVaWidgetExecute(this->widget, "mwWindowMakeBorderless", NULL); +} diff --git a/test.cc b/test.cc index aa33bb1..7b1f81b 100644 --- a/test.cc +++ b/test.cc @@ -1,12 +1,13 @@ #include #include #include +#include #include #include /* 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"); } };