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