]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/uilib/uilib.h
Remove <gtk/gtk.h> from gtkutil/window.h
[xonotic/netradiant.git] / libs / uilib / uilib.h
1 #ifndef INCLUDED_UILIB_H
2 #define INCLUDED_UILIB_H
3
4 #include <string>
5
6 struct _GdkEventKey;
7 struct _GtkAccelGroup;
8 struct _GtkAdjustment;
9 struct _GtkAlignment;
10 struct _GtkBin;
11 struct _GtkBox;
12 struct _GtkButton;
13 struct _GtkCellEditable;
14 struct _GtkCellRenderer;
15 struct _GtkCellRendererText;
16 struct _GtkCheckButton;
17 struct _GtkCheckMenuItem;
18 struct _GtkComboBox;
19 struct _GtkComboBoxText;
20 struct _GtkContainer;
21 struct _GtkDialog;
22 struct _GtkEditable;
23 struct _GtkEntry;
24 struct _GtkEntryCompletion;
25 struct _GtkFrame;
26 struct _GtkHBox;
27 struct _GtkHPaned;
28 struct _GtkHScale;
29 struct _GtkImage;
30 struct _GtkItem;
31 struct _GtkLabel;
32 struct _GtkListStore;
33 struct _GtkMenu;
34 struct _GtkMenuBar;
35 struct _GtkMenuItem;
36 struct _GtkMenuShell;
37 struct _GtkMisc;
38 struct _GtkObject;
39 struct _GtkPaned;
40 struct _GtkRadioButton;
41 struct _GtkRadioMenuItem;
42 struct _GtkRadioToolButton;
43 struct _GtkRange;
44 struct _GtkScale;
45 struct _GtkScrolledWindow;
46 struct _GtkSpinButton;
47 struct _GtkTable;
48 struct _GtkTearoffMenuItem;
49 struct _GtkTextView;
50 struct _GtkToggleButton;
51 struct _GtkToggleToolButton;
52 struct _GtkToolbar;
53 struct _GtkToolButton;
54 struct _GtkToolItem;
55 struct _GtkTreeModel;
56 struct _GtkTreePath;
57 struct _GtkTreeView;
58 struct _GtkTreeViewColumn;
59 struct _GtkVBox;
60 struct _GtkVPaned;
61 struct _GtkWidget;
62 struct _GtkWindow;
63 struct _GTypeInstance;
64
65 struct ModalDialog;
66
67 namespace ui {
68
69     void init(int argc, char *argv[]);
70
71     void main();
72
73     void process();
74
75     extern class Widget root;
76
77     enum class alert_type {
78         OK,
79         OKCANCEL,
80         YESNO,
81         YESNOCANCEL,
82         NOYES,
83     };
84
85     enum class alert_icon {
86         Default,
87         Error,
88         Warning,
89         Question,
90         Asterisk,
91     };
92
93     enum class alert_response {
94         OK,
95         CANCEL,
96         YES,
97         NO,
98     };
99
100     enum class window_type {
101         TOP,
102         POPUP
103     };
104
105     enum class Shadow {
106         NONE,
107         IN,
108         OUT,
109         ETCHED_IN,
110         ETCHED_OUT
111     };
112
113     enum class Policy {
114         ALWAYS,
115         AUTOMATIC,
116         NEVER
117     };
118
119     namespace details {
120
121         enum class Convert {
122             Implicit, Explicit
123         };
124
125         template<class Self, class T, Convert mode>
126         struct Convertible;
127
128         template<class Self, class T>
129         struct Convertible<Self, T, Convert::Implicit> {
130             operator T() const
131             { return reinterpret_cast<T>(static_cast<Self const *>(this)->_handle); }
132         };
133
134         template<class Self, class T>
135         struct Convertible<Self, T, Convert::Explicit> {
136             explicit operator T() const
137             { return reinterpret_cast<T>(static_cast<Self const *>(this)->_handle); }
138         };
139
140         template<class Self, class... T>
141         struct All : T ... {
142             All()
143             {};
144         };
145
146         template<class Self, class Interfaces>
147         struct Mixin;
148         template<class Self>
149         struct Mixin<Self, void()> {
150             using type = All<Self>;
151         };
152         template<class Self, class... Interfaces>
153         struct Mixin<Self, void(Interfaces...)> {
154             using type = All<Self, Interfaces...>;
155         };
156     }
157
158     extern struct Null {} null;
159
160     class Object :
161             public details::Convertible<Object, _GtkObject *, details::Convert::Explicit>,
162             public details::Convertible<Object, _GTypeInstance *, details::Convert::Explicit> {
163     public:
164         using native = _GtkObject *;
165         native _handle;
166
167         Object(native h) : _handle(h)
168         {}
169
170         explicit operator bool() const
171         { return _handle != nullptr; }
172
173         explicit operator void *() const
174         { return _handle; }
175     };
176     static_assert(sizeof(Object) == sizeof(Object::native), "object slicing");
177
178 #define WRAP(name, super, T, interfaces, ctors, methods) \
179     class name; \
180     class I##name : public details::Convertible<name, T *, details::Convert::Implicit> { \
181     public: \
182         using self = name *; \
183         methods \
184     }; \
185     class name : public super, public I##name, public details::Mixin<name, void interfaces>::type { \
186     public: \
187         using self = name *; \
188         using native = T *; \
189         explicit name(native h) : super(reinterpret_cast<super::native>(h)) {} \
190         explicit name(Null n) : name((native) nullptr) {} \
191         ctors \
192     }; \
193     inline bool operator<(name self, name other) { return self._handle < other._handle; } \
194     static_assert(sizeof(name) == sizeof(super), "object slicing")
195
196     // https://developer.gnome.org/gtk2/stable/ch01.html
197
198     // GInterface
199
200     WRAP(CellEditable, Object, _GtkCellEditable, (),
201     ,
202     );
203
204     WRAP(Editable, Object, _GtkEditable, (),
205          Editable();
206     ,
207          void editable(bool value);
208     );
209
210     WRAP(TreeModel, Object, _GtkTreeModel, (),
211     ,
212     );
213
214     // GObject
215
216     WRAP(Widget, Object, _GtkWidget, (),
217          Widget();
218     ,
219          alert_response alert(
220                  std::string text,
221                  std::string title = "NetRadiant",
222                  alert_type type = alert_type::OK,
223                  alert_icon icon = alert_icon::Default
224          );
225          const char *file_dialog(
226                  bool open,
227                  const char *title,
228                  const char *path = nullptr,
229                  const char *pattern = nullptr,
230                  bool want_load = false,
231                  bool want_import = false,
232                  bool want_save = false
233          );
234          void show();
235     );
236
237     WRAP(Container, Widget, _GtkContainer, (),
238     ,
239          void add(Widget widget);
240
241          void remove(Widget widget);
242
243          template<class Lambda>
244          void foreach(Lambda &&lambda);
245     );
246
247     WRAP(Bin, Container, _GtkBin, (),
248     ,
249     );
250
251     class AccelGroup;
252     WRAP(Window, Bin, _GtkWindow, (),
253          Window(window_type type);
254     ,
255          Window create_dialog_window(
256                  const char *title,
257                  void func(),
258                  void *data,
259                  int default_w = -1,
260                  int default_h = -1
261          );
262
263          Window create_modal_dialog_window(
264                  const char *title,
265                  ModalDialog &dialog,
266                  int default_w = -1,
267                  int default_h = -1
268          );
269
270          Window create_floating_window(const char *title);
271
272          std::uint64_t on_key_press(
273                  bool (*f)(Widget widget, _GdkEventKey *event, void *extra),
274                  void *extra = nullptr
275          );
276
277          void add_accel_group(AccelGroup group);
278     );
279
280     WRAP(Dialog, Window, _GtkDialog, (),
281     ,
282     );
283
284     WRAP(Alignment, Bin, _GtkAlignment, (),
285          Alignment(float xalign, float yalign, float xscale, float yscale);
286     ,
287     );
288
289     WRAP(Frame, Bin, _GtkFrame, (),
290          Frame(const char *label = nullptr);
291     ,
292     );
293
294     WRAP(Button, Bin, _GtkButton, (),
295          Button();
296          Button(const char *label);
297     ,
298     );
299
300     WRAP(ToggleButton, Button, _GtkToggleButton, (),
301     ,
302          bool active();
303     );
304
305     WRAP(CheckButton, ToggleButton, _GtkCheckButton, (),
306          CheckButton(const char *label);
307     ,
308     );
309
310     WRAP(RadioButton, CheckButton, _GtkRadioButton, (),
311     ,
312     );
313
314     WRAP(Item, Bin, _GtkItem, (),
315     ,
316     );
317
318     WRAP(MenuItem, Item, _GtkMenuItem, (),
319          MenuItem();
320          MenuItem(const char *label, bool mnemonic = false);
321     ,
322     );
323
324     WRAP(CheckMenuItem, MenuItem, _GtkCheckMenuItem, (),
325     ,
326     );
327
328     WRAP(RadioMenuItem, CheckMenuItem, _GtkRadioMenuItem, (),
329     ,
330     );
331
332     WRAP(TearoffMenuItem, MenuItem, _GtkTearoffMenuItem, (),
333          TearoffMenuItem();
334     ,
335     );
336
337     WRAP(ComboBox, Bin, _GtkComboBox, (),
338     ,
339     );
340
341     WRAP(ComboBoxText, ComboBox, _GtkComboBoxText, (),
342          ComboBoxText();
343     ,
344     );
345
346     WRAP(ToolItem, Bin, _GtkToolItem, (),
347     ,
348     );
349
350     WRAP(ToolButton, ToolItem, _GtkToolButton, (),
351     ,
352     );
353
354     WRAP(ToggleToolButton, ToolButton, _GtkToggleToolButton, (),
355     ,
356     );
357
358     WRAP(RadioToolButton, ToggleToolButton, _GtkRadioToolButton, (),
359     ,
360     );
361
362     WRAP(ScrolledWindow, Bin, _GtkScrolledWindow, (),
363          ScrolledWindow();
364     ,
365     );
366
367     WRAP(Box, Container, _GtkBox, (),
368     ,
369     );
370
371     WRAP(VBox, Box, _GtkVBox, (),
372          VBox(bool homogenous, int spacing);
373     ,
374     );
375
376     WRAP(HBox, Box, _GtkHBox, (),
377          HBox(bool homogenous, int spacing);
378     ,
379     );
380
381     WRAP(Paned, Container, _GtkPaned, (),
382     ,
383     );
384
385     WRAP(HPaned, Paned, _GtkHPaned, (),
386          HPaned();
387     ,
388     );
389
390     WRAP(VPaned, Paned, _GtkVPaned, (),
391          VPaned();
392     ,
393     );
394
395     WRAP(MenuShell, Container, _GtkMenuShell, (),
396     ,
397     );
398
399     WRAP(MenuBar, MenuShell, _GtkMenuBar, (),
400     ,
401     );
402
403     WRAP(Menu, MenuShell, _GtkMenu, (),
404          Menu();
405     ,
406     );
407
408     WRAP(Table, Container, _GtkTable, (),
409          Table(std::size_t rows, std::size_t columns, bool homogenous);
410     ,
411     );
412
413     WRAP(TextView, Container, _GtkTextView, (),
414          TextView();
415     ,
416     );
417
418     WRAP(Toolbar, Container, _GtkToolbar, (),
419     ,
420     );
421
422     class TreeModel;
423     WRAP(TreeView, Widget, _GtkTreeView, (),
424          TreeView();
425          TreeView(TreeModel model);
426     ,
427     );
428
429     WRAP(Misc, Widget, _GtkMisc, (),
430     ,
431     );
432
433     WRAP(Label, Widget, _GtkLabel, (),
434          Label(const char *label);
435     ,
436     );
437
438     WRAP(Image, Widget, _GtkImage, (),
439          Image();
440     ,
441     );
442
443     WRAP(Entry, Widget, _GtkEntry, (IEditable, ICellEditable),
444          Entry();
445          Entry(std::size_t max_length);
446     ,
447     );
448
449     class Adjustment;
450     WRAP(SpinButton, Entry, _GtkSpinButton, (),
451          SpinButton(Adjustment adjustment, double climb_rate, std::size_t digits);
452     ,
453     );
454
455     WRAP(Range, Widget, _GtkRange, (),
456     ,
457     );
458
459     WRAP(Scale, Range, _GtkScale, (),
460     ,
461     );
462
463     WRAP(HScale, Scale, _GtkHScale, (),
464          HScale(Adjustment adjustment);
465          HScale(double min, double max, double step);
466     ,
467     );
468
469     WRAP(Adjustment, Object, _GtkAdjustment, (),
470          Adjustment(double value,
471                     double lower, double upper,
472                     double step_increment, double page_increment,
473                     double page_size);
474     ,
475     );
476
477     WRAP(CellRenderer, Object, _GtkCellRenderer, (),
478     ,
479     );
480
481     WRAP(CellRendererText, CellRenderer, _GtkCellRendererText, (),
482          CellRendererText();
483     ,
484     );
485
486     struct TreeViewColumnAttribute {
487         const char *attribute;
488         int column;
489     };
490     WRAP(TreeViewColumn, Object, _GtkTreeViewColumn, (),
491          TreeViewColumn(const char *title, CellRenderer renderer, std::initializer_list<TreeViewColumnAttribute> attributes);
492     ,
493     );
494
495     WRAP(AccelGroup, Object, _GtkAccelGroup, (),
496          AccelGroup();
497     ,
498     );
499
500     WRAP(EntryCompletion, Object, _GtkEntryCompletion, (),
501     ,
502     );
503
504     WRAP(ListStore, Object, _GtkListStore, (ITreeModel),
505     ,
506          void clear();
507     );
508
509     // GBoxed
510
511     WRAP(TreePath, Object, _GtkTreePath, (),
512          TreePath();
513          TreePath(const char *path);
514     ,
515     );
516
517 #undef WRAP
518
519     // callbacks
520
521     namespace {
522         using GtkCallback = void (*)(_GtkWidget *, void *);
523         extern "C" {
524         void gtk_container_foreach(_GtkContainer *, GtkCallback, void *);
525         }
526     }
527
528 #define this (*static_cast<self>(this))
529
530     template<class Lambda>
531     void IContainer::foreach(Lambda &&lambda)
532     {
533         GtkCallback cb = [](_GtkWidget *widget, void *data) -> void {
534             using Function = typename std::decay<Lambda>::type;
535             Function *f = static_cast<Function *>(data);
536             (*f)(Widget(widget));
537         };
538         gtk_container_foreach(this, cb, &lambda);
539     }
540
541 #undef this
542
543 }
544
545 #endif