This commit is contained in:
IoI_xD 2026-04-16 11:15:06 -07:00
commit 5d9bed0aa1
4 changed files with 456 additions and 0 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
/*.exe
/*.so
/*.dll
compile_flags.txt

BIN
examples/a.out Executable file

Binary file not shown.

105
examples/example.cpp Normal file
View file

@ -0,0 +1,105 @@
// g++ example.cpp -I ../include/ -lMw
#include <Mw/StringDefs.h>
#include <mwcxx/widget.hpp>
mw::Widget *window, *button, *button2, *button3, *button4, *button5, *button6;
void handler(MwWidget handle, void *user_data, void *call_data) {
(void)handle;
(void)user_data;
(void)call_data;
printf("hello world!\n");
}
void handler_theme(MwWidget handle, void *user_data, void *call_data) {
(void)handle;
(void)user_data;
(void)call_data;
window->apply(MwNdarkTheme, window->get_integer(MwNdarkTheme) == 0 ? 1 : 0,
NULL);
}
void handler_look(MwWidget handle, void *user_data, void *call_data) {
(void)handle;
(void)user_data;
(void)call_data;
window->apply(MwNmodernLook, window->get_integer(MwNmodernLook) == 0 ? 1 : 0,
NULL);
}
void handler_font(MwWidget handle, void *user_data, void *call_data) {
(void)handle;
(void)user_data;
(void)call_data;
window->apply(MwNbitmapFont, window->get_integer(MwNbitmapFont) == 0 ? 1 : 0,
NULL);
}
void resize(MwWidget handle, void *user_data, void *call_data) {
unsigned int w, h, mh;
(void)user_data;
(void)call_data;
w = MwGetInteger(handle, MwNwidth);
h = MwGetInteger(handle, MwNheight);
button->apply(MwNy, 50 + mh, MwNwidth, (w - 50 * 2) / 3, MwNheight,
h - 125 - 50 * 3);
button2->apply(MwNx, 50 + (w - 50 * 2) / 3, MwNy, 50 + mh, MwNwidth,
(w - 50 * 2) / 3, MwNheight, h - 125 - 50 * 3);
button3->apply(MwNx, 50 + (w - 50 * 2) / 3 * 2, MwNy, 50 + mh, MwNwidth,
(w - 50 * 2) / 3, MwNheight, h - 125 - 50 * 3);
button4->apply(MwNx, 50 + (w - 50 * 2) / 3 * 0, MwNy, h - 50 - 125 + mh,
MwNwidth, (w - 50 * 2) / 3);
button5->apply(MwNx, 50 + (w - 50 * 2) / 3 * 1, MwNy, h - 50 - 125 + mh,
MwNwidth, (w - 50 * 2) / 3);
button6->apply(MwNx, 50 + (w - 50 * 2) / 3 * 2, MwNy, h - 50 - 125 + mh,
MwNwidth, (w - 50 * 2) / 3);
}
int main() {
MwMenu m, m2;
MwLibraryInit();
window = new mw::Window("main", NULL, MwDEFAULT, MwDEFAULT, 400, 400,
MwNtitle, "hello world");
// menu = new mw::Menu("menu", window, 0, 0, 0, 0);
button = new mw::Button("button", window, 50, 50, 100, 125, MwNtext, "theme");
button2 =
new mw::Button("button", window, 150, 50, 100, 125, MwNtext, "look");
button3 =
new mw::Button("button", window, 250, 50, 100, 125, MwNtext, "font");
button4 = new mw::Button("button", window, 50, 225, 100, 125, MwNtext,
"lorem ipsum", MwNbackground, "#f66", MwNforeground,
"#000");
button5 = new mw::Button("button", window, 150, 225, 100, 125, MwNtext,
"lorem ipsum", MwNbackground, "#6f6", MwNforeground,
"#000");
button6 = new mw::Button("button", window, 250, 225, 100, 125, MwNtext,
"lorem ipsum", MwNbackground, "#66f", MwNforeground,
"#000");
window->add_user_handler(MwNresizeHandler, resize, NULL);
button->add_user_handler(MwNactivateHandler, handler_theme, NULL);
button2->add_user_handler(MwNactivateHandler, handler_look, NULL);
button3->add_user_handler(MwNactivateHandler, handler_font, NULL);
button4->add_user_handler(MwNactivateHandler, handler, NULL);
button5->add_user_handler(MwNactivateHandler, handler, NULL);
button6->add_user_handler(MwNactivateHandler, handler, NULL);
// resize(window, NULL, NULL);
window->loop();
}

350
include/mwcxx/widget.hpp Normal file
View file

@ -0,0 +1,350 @@
#include <Mw/BaseTypes.h>
#include <Mw/Core.h>
#include <Mw/Milsko.h>
#include <Mw/Widget/OpenGL.h>
#include <Mw/Widget/Vulkan.h>
#include <Mw/Widget/Window.h>
#include <cstdarg>
#include <cstddef>
#include <string>
namespace mw {
struct va_separator {}; // Empty; ABI may elide allocation.
class Widget {
protected:
::MwWidget mWidget = NULL;
Widget() : mWidget(nullptr) {};
Widget(::MwWidget w) : mWidget(w) {};
template <typename... Args>
void create(std::string name, Widget *parent, int x, int y,
unsigned int width, unsigned int height, Args &&...args) {
mWidget = ::MwVaCreateWidget(this->get_class(), name.c_str(),
parent ? parent->mWidget : nullptr, x, y,
width, height, std::forward<Args>(args)...);
};
public:
virtual ~Widget() {
if (mWidget)
::MwDestroyWidget(mWidget);
}
/*!
* @brief Executes a method specific to the widget (varadic version).
* @warning Prefer using corresponding functions for better code clarity
* and type safety.
* @param func_name Function name
* @param ... Widget function arguments.
*/
template <typename... Args>
void execute(std::string func_name, void *out, Args &&...a) {
::MwVaListWidgetExecute(this->mWidget, func_name.c_str(), out, a..., NULL);
};
/*!
* @brief Runs the main loop
*/
void loop() { ::MwLoop(mWidget); }
/*!
* @brief Runs the single step
* @return `0` if successful
*/
int step() { return ::MwStep(mWidget); };
/*!
* @brief Check if any event is pending
* @return `1` if any event is pending
*/
int pending() { return ::MwPending(mWidget); };
/*!
* @brief Sets an integer property
* @param key Key
* @param n Value
*/
void set_integer(std::string key, int n) {
::MwSetInteger(mWidget, key.c_str(), n);
};
/*!
* @brief Sets a text property
* @param key Key
* @param value Value
*/
void set_text(std::string key, std::string value) {
::MwSetText(mWidget, key.c_str(), value.c_str());
};
/*!
* @brief Sets a void pointer property
* @param key Key
* @param value Value
*/
void set_void(std::string key, void *value) {
::MwSetVoid(mWidget, key.c_str(), value);
};
/*!
* @brief Gets the integer property
* @param key Key
* @return Value
*/
int get_integer(std::string key) {
return ::MwGetInteger(mWidget, key.c_str());
};
/*!
* @brief Gets the text property
* @param key Key
* @return Value
*/
std::string get_text(std::string key) {
return std::string(::MwGetText(mWidget, key.c_str()));
};
/*!
* @brief Gets the void pointer property
* @param key Key
* @return Value
*/
void *get_void(std::string key) { return ::MwGetVoid(mWidget, key.c_str()); };
/*!
* @brief Sets the default property
* @warning This is called when widget is created
*/
void set_default() { ::MwSetDefault(mWidget); };
/*!
* @brief Sets the properties
* @param ... Properties
*/
template <typename... Args> void apply(Args &&...a) {
::MwVaApply(mWidget, a..., NULL);
};
/*!
* @brief Sets a user handler
* @param key Key
* @param handler Handler
* @param user_data User data passed to handler
*/
void add_user_handler(const char *key, MwUserHandler handler,
void *user_data) {
::MwAddUserHandler(mWidget, key, handler, user_data);
};
/*!
* @brief Dispatches the user handler
* @param key Key
* @param handler_data Handler data passed to handler
*/
void dispatch_user_handler(std::string key, void *handler_data) {
::MwDispatchUserHandler(mWidget, key.c_str(), handler_data);
};
/*!
* @brief Gets the before_step of widget
* @param jmpbuf jmp_buf
*/
void get_before_step(jmp_buf *jmpbuf) { ::MwGetBeforeStep(mWidget, jmpbuf); };
/*!
* @brief Forcefully makes widget render
*/
void force_render() { ::MwForceRender(mWidget); };
/*!
* @brief Adds an widget to tick handler list
*/
void add_tick_list() { ::MwAddTickList(mWidget); };
/*!
* @brief Focus the widget
*/
void focus() { ::MwFocus(mWidget); };
/*!
* @brief Grabs the pointer
* @param toggle Toggle
*/
void grab_pointer(int toggle) { ::MwGrabPointer(mWidget, toggle); };
/*!
* @brief Hides the cursor
*/
void hide_cursor() { ::MwHideCursor(mWidget); };
/*!
* @brief Toggles the dark theme
* @param toggle Toggle
* @deprecated Use NdarkTheme instead
*/
void set_dark_theme(bool toggle) { ::MwSetDarkTheme(mWidget, toggle); };
/*!
* @brief Gets the parent widget
* @return Parent widget
*/
/*class WidgetHandle get_parent() {
return WidgetHandle(::MwGetParent(mWidget))
};*/
/*!
* @brief Show widget
* @param toggle Toggle
*/
void show(bool toggle) { ::MwShow(mWidget, toggle); };
/*!
* @brief Reparents widget
* @param new_parent New parent
*/
void reparent(Widget *new_parent) {
::MwReparent(mWidget, new_parent->mWidget);
};
/*!
* @brief Gets class of widget
* @return Class
*/
virtual ::MwClass get_class() = 0;
/*!
* @brief Gets name of widget
* @return Name
*/
std::string get_name() { return ::MwGetName(mWidget); };
// /*!
// * @brief Gets children of widget
// * @return Children (NULL-terminated array)
// */
// std::vector<Widget> get_children();
/*!
* @brief Gets the cursor coordinate
* @param point Point
*/
::MwPoint get_cursor_coord() {
::MwPoint p;
::MwGetCursorCoord(mWidget, &p);
return p;
};
/*!
* @brief Gets the screen size
* @return rect Rectangle
*/
::MwRect get_screen_size() {
::MwRect r;
::MwGetScreenSize(mWidget, &r);
return r;
};
/*!
* @brief Reports whether a widget reports global or local coordinates upon
* GetXY/SetXY. Anything with a parent reports local, and most backends report
* global coordinates being supported for top level windows, but some
* (Wayland) do not.
*/
int get_coordinate_type() { return ::MwGetCoordinateType(mWidget); };
/*!
* @brief Queue to get clipboard content.
* @param clipboard_type The Clipboard Type to get. See ClipboardType. This is
* ignored on backends that aren't X11/Wayland, so if you're unsure, just use
* ClipboardMain
*/
void get_clipboard(int clipboard_type) {
return ::MwGetClipboard(mWidget, clipboard_type);
};
};
#define WCLASS(a) \
::MwClass get_class() override { return Mw##a##Class; }; \
\
public: \
template <typename... Args> \
a(std::string name, Widget *parent, int x, int y, unsigned int width, \
unsigned int height, Args... args) { \
printf("%d\n", width); \
this->create(name, parent, x, y, width, height, \
std::forward<Args>(args)..., NULL); \
assert(mWidget); \
}
class WidgetHandle : public Widget {
public:
::MwClass get_class() override { return ::MwGetClass(mWidget); };
};
class Box : public Widget {
WCLASS(Box)
};
class Button : public Widget {
WCLASS(Button)
};
class CheckBox : public Widget {
WCLASS(CheckBox)
};
class ComboBox : public Widget {
WCLASS(ComboBox)
};
class Entry : public Widget {
WCLASS(Entry)
};
class Frame : public Widget {
WCLASS(Frame)
};
class Image : public Widget {
WCLASS(Image)
};
class Label : public Widget {
WCLASS(Label)
};
class ListBox : public Widget {
WCLASS(ListBox)
};
class Menu : public Widget {
WCLASS(Menu)
};
class NumberEntry : public Widget {
WCLASS(NumberEntry)
};
class OpenGL : public Widget {
WCLASS(OpenGL)
};
class ProgressBar : public Widget {
WCLASS(ProgressBar)
};
class RadioBox : public Widget {
WCLASS(RadioBox)
};
class ScrollBar : public Widget {
WCLASS(ScrollBar)
};
class Separator : public Widget {
WCLASS(Separator)
};
class SubMenu : public Widget {
WCLASS(SubMenu)
};
class TreeView : public Widget {
WCLASS(TreeView)
};
class Viewport : public Widget {
WCLASS(Viewport)
};
class Vulkan : public Widget {
WCLASS(Vulkan)
};
class Window : public Widget {
WCLASS(Window)
};
} // namespace mw