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