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