f3f490c3ba7ec22f7a92b6bd25ba335c35bf05e2
[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_accelgroup = struct _GtkAccelGroup;
7 using ui_adjustment = struct _GtkAdjustment;
8 using ui_alignment = struct _GtkAlignment;
9 using ui_box = struct _GtkBox;
10 using ui_button = struct _GtkButton;
11 using ui_checkbutton = struct _GtkCheckButton;
12 using ui_combobox = struct _GtkComboBox;
13 using ui_comboboxtext = struct _GtkComboBoxText;
14 using ui_cellrenderer = struct _GtkCellRenderer;
15 using ui_cellrenderertext = struct _GtkCellRendererText;
16 using ui_entry = struct _GtkEntry;
17 using ui_evkey = struct _GdkEventKey;
18 using ui_frame = struct _GtkFrame;
19 using ui_hbox = struct _GtkHBox;
20 using ui_hscale = struct _GtkHScale;
21 using ui_hpaned = struct _GtkHPaned;
22 using ui_image = struct _GtkImage;
23 using ui_label = struct _GtkLabel;
24 using ui_menu = struct _GtkMenu;
25 using ui_menuitem = struct _GtkMenuItem;
26 using ui_modal = struct ModalDialog;
27 using ui_object = struct _GtkObject;
28 using ui_paned = struct _GtkPaned;
29 using ui_scrolledwindow = struct _GtkScrolledWindow;
30 using ui_spinbutton = struct _GtkSpinButton;
31 using ui_table = struct _GtkTable;
32 using ui_textview = struct _GtkTextView;
33 using ui_treemodel = struct _GtkTreeModel;
34 using ui_treepath = struct _GtkTreePath;
35 using ui_treeview = struct _GtkTreeView;
36 using ui_treeviewcolumn = struct _GtkTreeViewColumn;
37 using ui_typeinst = struct _GTypeInstance;
38 using ui_vbox = struct _GtkVBox;
39 using ui_vpaned = struct _GtkVPaned;
40 using ui_widget = struct _GtkWidget;
41 using ui_window = struct _GtkWindow;
42
43 namespace ui {
44
45     void init(int argc, char *argv[]);
46
47     void main();
48
49     enum class alert_type {
50         OK,
51         OKCANCEL,
52         YESNO,
53         YESNOCANCEL,
54         NOYES,
55     };
56
57     enum class alert_icon {
58         Default,
59         Error,
60         Warning,
61         Question,
62         Asterisk,
63     };
64
65     enum class alert_response {
66         OK,
67         CANCEL,
68         YES,
69         NO,
70     };
71
72     enum class window_type {
73         TOP,
74         POPUP
75     };
76
77     template<class Self, class T, bool implicit = true>
78     struct Convertible;
79
80     template<class Self, class T>
81     struct Convertible<Self, T, true> {
82         operator T *() const
83         { return reinterpret_cast<T *>(static_cast<const Self *>(this)->_handle); }
84     };
85
86     template<class Self, class T>
87     struct Convertible<Self, T, false> {
88         explicit operator T *() const
89         { return reinterpret_cast<T *>(static_cast<const Self *>(this)->_handle); }
90     };
91
92     class Object : public Convertible<Object, ui_object, false> {
93     public:
94         using native = ui_object;
95         void *_handle;
96
97         Object(void *h) : _handle(h)
98         { }
99
100         explicit operator bool() const
101         { return _handle != nullptr; }
102
103         explicit operator ui_typeinst *() const
104         { return (ui_typeinst *) _handle; }
105
106         explicit operator void *() const
107         { return _handle; }
108     };
109
110     static_assert(sizeof(Object) == sizeof(ui_widget *), "object slicing");
111
112     class Widget : public Object, public Convertible<Widget, ui_widget> {
113     public:
114         using native = ui_widget;
115         explicit Widget(ui_widget *h = nullptr) : Object((void *) h)
116         { }
117
118         alert_response alert(std::string text, std::string title = "NetRadiant",
119                              alert_type type = alert_type::OK, alert_icon icon = alert_icon::Default);
120
121         const char *file_dialog(bool open, const char *title, const char *path = nullptr,
122                                 const char *pattern = nullptr, bool want_load = false, bool want_import = false,
123                                 bool want_save = false);
124     };
125
126     static_assert(sizeof(Widget) == sizeof(Object), "object slicing");
127
128     extern Widget root;
129
130 #define WRAP(name, super, impl, methods) \
131     class name : public super, public Convertible<name, impl> { \
132         public: \
133             using native = impl; \
134             explicit name(impl *h) : super(reinterpret_cast<super::native *>(h)) {} \
135         methods \
136     }; \
137     inline bool operator<(name self, name other) { return self._handle < other._handle; } \
138     static_assert(sizeof(name) == sizeof(super), "object slicing")
139
140     WRAP(AccelGroup, Object, ui_accelgroup,
141          AccelGroup();
142     );
143
144     WRAP(Adjustment, Widget, ui_adjustment,
145          Adjustment(double value,
146                     double lower, double upper,
147                     double step_increment, double page_increment,
148                     double page_size);
149     );
150
151     WRAP(Alignment, Widget, ui_alignment,
152          Alignment(float xalign, float yalign, float xscale, float yscale);
153     );
154
155     WRAP(Box, Widget, ui_box,);
156
157     WRAP(Button, Widget, ui_button,
158          Button();
159          Button(const char *label);
160     );
161
162     WRAP(CellRenderer, Object, ui_cellrenderer,);
163
164     WRAP(CellRendererText, CellRenderer, ui_cellrenderertext,
165          CellRendererText();
166     );
167
168     WRAP(CheckButton, Widget, ui_checkbutton,
169          CheckButton(const char *label);
170     );
171
172     WRAP(ComboBox, Widget, ui_combobox,);
173
174     WRAP(ComboBoxText, ComboBox, ui_comboboxtext,
175          ComboBoxText();
176     );
177
178     WRAP(Entry, Widget, ui_entry,
179          Entry();
180          Entry(std::size_t max_length);
181     );
182
183     WRAP(Frame, Widget, ui_frame,
184          Frame(const char *label = nullptr);
185     );
186
187     WRAP(HBox, Box, ui_hbox,
188          HBox(bool homogenous, int spacing);
189     );
190
191     WRAP(HScale, Widget, ui_hscale,
192          HScale(Adjustment adjustment);
193          HScale(double min, double max, double step);
194     );
195
196     WRAP(Image, Widget, ui_image,
197          Image();
198     );
199
200     WRAP(Label, Widget, ui_label,
201          Label(const char *label);
202     );
203
204     WRAP(Menu, Widget, ui_menu,
205          Menu();
206     );
207
208     WRAP(MenuItem, Widget, ui_menuitem,
209          MenuItem(const char *label, bool mnemonic = false);
210     );
211
212     WRAP(Paned, Widget, ui_paned,);
213
214         WRAP(HPaned, Paned, ui_hpaned,
215              HPaned();
216         );
217
218         WRAP(VPaned, Paned, ui_vpaned,
219              VPaned();
220         );
221
222     WRAP(ScrolledWindow, Widget, ui_scrolledwindow,
223          ScrolledWindow();
224     );
225
226     WRAP(SpinButton, Widget, ui_spinbutton,
227          SpinButton(Adjustment adjustment, double climb_rate, std::size_t digits);
228     );
229
230     WRAP(Table, Widget, ui_table,
231          Table(std::size_t rows, std::size_t columns, bool homogenous);
232     );
233
234     WRAP(TextView, Widget, ui_textview,
235          TextView();
236     );
237
238     WRAP(TreeModel, Widget, ui_treemodel,);
239
240     WRAP(TreePath, Object, ui_treepath,
241          TreePath();
242          TreePath(const char *path);
243     );
244
245     WRAP(TreeView, Widget, ui_treeview,
246          TreeView();
247          TreeView(TreeModel model);
248     );
249
250     struct TreeViewColumnAttribute {
251         const char *attribute;
252         int column;
253     };
254     WRAP(TreeViewColumn, Widget, ui_treeviewcolumn,
255          TreeViewColumn(const char *title, CellRenderer renderer, std::initializer_list<TreeViewColumnAttribute> attributes);
256     );
257
258     WRAP(VBox, Box, ui_vbox,
259          VBox(bool homogenous, int spacing);
260     );
261
262     WRAP(Window, Widget, ui_window,
263          Window() : Window(nullptr) {};
264          Window(window_type type);
265
266          Window create_dialog_window(const char *title, void func(), void *data, int default_w = -1,
267                                      int default_h = -1);
268
269          Window create_modal_dialog_window(const char *title, ui_modal &dialog, int default_w = -1,
270                                            int default_h = -1);
271
272          Window create_floating_window(const char *title);
273
274          std::uint64_t on_key_press(bool (*f)(Widget widget, ui_evkey *event, void *extra),
275                                     void *extra = nullptr);
276
277          void add_accel_group(AccelGroup group);
278     );
279
280 #undef WRAP
281
282 }
283
284 #endif