c
This commit is contained in:
parent
76a33f9395
commit
5d9bed0aa1
4 changed files with 456 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -3,3 +3,4 @@
|
||||||
/*.exe
|
/*.exe
|
||||||
/*.so
|
/*.so
|
||||||
/*.dll
|
/*.dll
|
||||||
|
compile_flags.txt
|
||||||
|
|
|
||||||
BIN
examples/a.out
Executable file
BIN
examples/a.out
Executable file
Binary file not shown.
105
examples/example.cpp
Normal file
105
examples/example.cpp
Normal 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
350
include/mwcxx/widget.hpp
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue