]> git.xonotic.org Git - xonotic/netradiant.git/blob - libs/uilib/uilib.h
17a764108bd48d142899dd1fc715207712a3a2ad
[xonotic/netradiant.git] / libs / uilib / uilib.h
1 #ifndef INCLUDED_UILIB_H
2 #define INCLUDED_UILIB_H
3
4 #include <string>
5
6 using ui_alignment = struct _GtkAlignment;
7 using ui_button = struct _GtkButton;
8 using ui_evkey = struct _GdkEventKey;
9 using ui_label = struct _GtkLabel;
10 using ui_menuitem = struct _GtkMenuItem;
11 using ui_modal = struct ModalDialog;
12 using ui_typeinst = struct _GTypeInstance;
13 using ui_widget = struct _GtkWidget;
14 using ui_window = struct _GtkWindow;
15
16 namespace ui {
17
18     void init(int argc, char *argv[]);
19
20     void main();
21
22     enum class alert_type {
23         OK,
24         OKCANCEL,
25         YESNO,
26         YESNOCANCEL,
27         NOYES,
28     };
29
30     enum class alert_icon {
31         DEFAULT,
32         ERROR,
33         WARNING,
34         QUESTION,
35         ASTERISK,
36     };
37
38     enum class alert_response {
39         OK,
40         CANCEL,
41         YES,
42         NO,
43     };
44
45     template<class Self, class T>
46     class Convertible {
47     public:
48         T *handle() const
49         { return (T *) static_cast<const Self *>(this)->_handle; }
50
51         operator T *() const
52         { return handle(); }
53     };
54
55     class Base {
56     public:
57         void *_handle;
58
59         Base(void *h) : _handle(h)
60         { }
61
62         explicit operator bool() const
63         { return _handle != nullptr; }
64
65         explicit operator ui_typeinst *() const
66         { return (ui_typeinst *) _handle; }
67
68         explicit operator void *() const
69         { return _handle; }
70     };
71
72     static_assert(sizeof(Base) == sizeof(ui_widget *), "object slicing");
73
74     class Widget : public Base, public Convertible<Widget, ui_widget> {
75     public:
76         explicit Widget(ui_widget *h = nullptr) : Base((void *) h)
77         { }
78
79         alert_response alert(std::string text, std::string title = "NetRadiant",
80                              alert_type type = alert_type::OK, alert_icon icon = alert_icon::DEFAULT);
81
82         const char *file_dialog(bool open, const char *title, const char *path = nullptr,
83                                 const char *pattern = nullptr, bool want_load = false, bool want_import = false,
84                                 bool want_save = false);
85     };
86
87     static_assert(sizeof(Widget) == sizeof(Base), "object slicing");
88
89     extern Widget root;
90
91 #define WIDGET(name, impl, methods) \
92     class name : public Widget, public Convertible<name, impl> { \
93         public: \
94             explicit name(impl *h = nullptr) : Widget(reinterpret_cast<ui_widget *>(h)) {} \
95         methods \
96     }; \
97     static_assert(sizeof(name) == sizeof(Widget), "object slicing")
98
99     WIDGET(Window, ui_window,
100            Window create_dialog_window(const char *title, void func(), void *data, int default_w = -1,
101                                        int default_h = -1);
102
103                    Window create_modal_dialog_window(const char *title, ui_modal &dialog, int default_w = -1,
104                                                      int default_h = -1);
105
106                    Window create_floating_window(const char *title);
107
108                    std::uint64_t on_key_press(bool (*f)(Widget widget, ui_evkey *event, void *extra),
109                                               void *extra = nullptr);
110     );
111
112     WIDGET(Button, ui_button,
113            Button(const char *label);
114     );
115
116     WIDGET(CheckButton, ui_widget,);
117
118     WIDGET(SpinButton, ui_widget,);
119
120     WIDGET(MenuItem, ui_menuitem,);
121
122     WIDGET(Label, ui_label,
123            Label(const char *label);
124     );
125
126     WIDGET(Alignment, ui_alignment,
127            Alignment(float xalign, float yalign, float xscale, float yscale);
128     );
129
130 }
131
132 #endif