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