Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Portions of this file are copyright Rebirth contributors and licensed as
3
 * described in COPYING.txt.
4
 * Portions of this file are copyright Parallax Software and licensed
5
 * according to the Parallax license below.
6
 * See COPYING.txt for license details.
7
 
8
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
9
SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
10
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
11
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
12
IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
13
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
14
FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
15
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
16
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
17
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
18
*/
19
 
20
/*
21
 *
22
 * Header file for user interface
23
 *
24
 */
25
 
26
#pragma once
27
 
28
#include <type_traits>
29
#include "dxxsconf.h"
30
#include "dsx-ns.h"
31
#include "fwd-event.h"
32
#include "fmtcheck.h"
33
#include "u_mem.h"
34
 
35
#ifdef __cplusplus
36
#include <cstdint>
37
#include <string>
38
#include "fwd-gr.h"
39
#include "varutil.h"
40
#include "window.h"
41
#include "ntstring.h"
42
#include <array>
43
#include <memory>
44
 
45
namespace dcx {
46
 
47
struct UI_KEYPAD {
48
        using buttontext_element_t = std::array<char, 100>;
49
        using buttontext_t = std::array<buttontext_element_t, 17>;
50
        UI_KEYPAD();
51
        unsigned numkeys;
52
        ntstring<99> description;
53
        std::array<short, 100> keycode;
54
        std::array<int, 100> function_number;
55
        buttontext_t buttontext;
56
};
57
 
58
struct UI_EVENT
59
{
60
        unsigned int frame;
61
        int type;
62
        int data;
63
};
64
 
65
struct UI_GADGET
66
{
67
        uint8_t           kind;
68
        short           x1,y1,x2,y2;
69
        int             hotkey;
70
        struct UI_GADGET  * prev;     \
71
        struct UI_GADGET  * next;     \
72
        struct UI_GADGET  * when_tab;  \
73
        struct UI_GADGET  * when_btab; \
74
        struct UI_GADGET  * when_up;    \
75
        struct UI_GADGET  * when_down;   \
76
        struct UI_GADGET  * when_left;   \
77
        struct UI_GADGET  * when_right;  \
78
        struct UI_GADGET  * parent;    \
79
        int             status;     \
80
        int             oldstatus;  \
81
        grs_subcanvas_ptr canvas;     \
82
protected:
83
        ~UI_GADGET() = default;
84
};
85
 
86
struct UI_GADGET_USERBOX : UI_GADGET
87
{
88
        static constexpr auto s_kind = std::integral_constant<uint8_t, 7>{};
89
        short           width, height;
90
        short           b1_held_down;
91
        short           b1_clicked;
92
        short           b1_double_clicked;
93
        short           b1_dragging;
94
        short           b1_drag_x1, b1_drag_y1;
95
        short           b1_drag_x2, b1_drag_y2;
96
        short           b1_done_dragging;
97
        short           mouse_onme;
98
        short           mouse_x, mouse_y;
99
        int             keypress;
100
        grs_bitmap *    bitmap;
101
};
102
 
103
struct UI_GADGET_BUTTON : UI_GADGET
104
{
105
        static constexpr auto s_kind = std::integral_constant<uint8_t, 1>{};
106
        std::string  text;
107
        short           width, height;
108
        short           position;
109
        short           oldposition;
110
        short           pressed;
111
        uint8_t dim_if_no_function;
112
        int                              hotkey1;
113
        int              (*user_function)(void);
114
        int              (*user_function1)(void);
115
};
116
 
117
struct UI_GADGET_INPUTBOX : UI_GADGET
118
{
119
        static constexpr auto s_kind = std::integral_constant<uint8_t, 6>{};
120
        RAIIdmem<char[]>  text;
121
        short           width, height;
122
        short           length;
123
        short           slength;
124
        short           position;
125
        short           oldposition;
126
        short           pressed;
127
        short           first_time;
128
};
129
 
130
struct UI_GADGET_RADIO : UI_GADGET
131
{
132
        static constexpr auto s_kind = std::integral_constant<uint8_t, 4>{};
133
        RAIIdmem<char[]>  text;
134
        short           width, height;
135
        short           position;
136
        short           oldposition;
137
        short           pressed;
138
        short           group;
139
        short           flag;
140
};
141
 
142
struct UI_GADGET_ICON : UI_GADGET
143
{
144
        static constexpr auto s_kind = std::integral_constant<uint8_t, 9>{};
145
        RAIIdmem<char[]>  text;
146
        short               width, height;
147
        sbyte           flag;
148
        sbyte           pressed;
149
        sbyte           position;
150
        sbyte           oldposition;
151
        int             trap_key;
152
        int             (*user_function)(void);
153
};
154
 
155
struct UI_GADGET_CHECKBOX : UI_GADGET
156
{
157
        static constexpr auto s_kind = std::integral_constant<uint8_t, 5>{};
158
        RAIIdmem<char[]>  text;
159
        short           width, height;
160
        short           position;
161
        short           oldposition;
162
        short           pressed;
163
        short           group;
164
        short           flag;
165
};
166
 
167
struct UI_GADGET_SCROLLBAR : UI_GADGET
168
{
169
        static constexpr auto s_kind = std::integral_constant<uint8_t, 3>{};
170
        short           horz;
171
        short           width, height;
172
        int             start;
173
        int             stop;
174
        int             position;
175
        int             window_size;
176
        int             fake_length;
177
        int             fake_position;
178
        int             fake_size;
179
        std::unique_ptr<UI_GADGET_BUTTON> up_button, down_button;
180
        fix64           last_scrolled;
181
        short           drag_x, drag_y;
182
        int             drag_starting;
183
        int             dragging;
184
        int             moved;
185
};
186
 
187
struct UI_GADGET_LISTBOX : UI_GADGET
188
{
189
        static constexpr auto s_kind = std::integral_constant<uint8_t, 2>{};
190
        const char            *const *list;
191
        short           width, height;
192
        int             num_items;
193
        int             num_items_displayed;
194
        int             first_item;
195
        int             old_first_item;
196
        int             current_item;
197
        int             selected_item;
198
        int             old_current_item;
199
        int             dragging;
200
        int             textheight;
201
        int             moved;
202
        std::unique_ptr<UI_GADGET_SCROLLBAR> scrollbar;
203
        fix64           last_scrolled;
204
};
205
 
206
enum dialog_flags
207
{
208
        DF_BORDER  = 1,
209
        DF_FILLED = 2,
210
        DF_SAVE_BG = 4,
211
        DF_DIALOG = (4+2+1),
212
        DF_MODAL = 8            // modal = accept all user input exclusively
213
};
214
 
215
template <typename T>
216
using ui_subfunction_t = window_event_result (*)(struct UI_DIALOG *,const d_event &, T *);
217
 
218
template <typename T>
219
using ui_subclass_subfunction_t = window_event_result (*)(T *,const d_event &, void *);
220
 
221
struct UI_DIALOG : embed_window_pointer_t
222
{
223
        // TODO: Make these private
224
        ui_subfunction_t<void>  d_callback;
225
        UI_GADGET *     gadget;
226
        UI_GADGET *     keyboard_focus_gadget;
227
        void                    *d_userdata;
228
        short           d_x, d_y;
229
        short           d_width, d_height;
230
        short           d_text_x, d_text_y;
231
        enum dialog_flags d_flags;
232
 
233
public:
234
        // For creating the dialog, there are two ways - using the (older) ui_create_dialog function
235
        // or using the constructor, passing an event handler that takes a subclass of UI_DIALOG.
236
        explicit UI_DIALOG(short x, short y, short w, short h, enum dialog_flags flags, ui_subfunction_t<void> callback, void *userdata, const void *createdata);
237
 
238
        template <typename T>
239
        UI_DIALOG(short x, short y, short w, short h, enum dialog_flags flags, ui_subclass_subfunction_t<T> callback) :
240
        UI_DIALOG(x, y, w, h, flags, reinterpret_cast<ui_subclass_subfunction_t<UI_DIALOG>>(callback), nullptr, nullptr) {}
241
 
242
        ~UI_DIALOG();
243
};
244
 
245
#define B1_JUST_PRESSED     (event.type == EVENT_MOUSE_BUTTON_DOWN && event_mouse_get_button(event) == 0)
246
#define B1_JUST_RELEASED    (event.type == EVENT_MOUSE_BUTTON_UP && event_mouse_get_button(event) == 0)
247
#define B1_DOUBLE_CLICKED   (event.type == EVENT_MOUSE_DOUBLE_CLICKED && event_mouse_get_button(event) == 0)
248
 
249
extern grs_font_ptr ui_small_font;
250
 
251
extern unsigned char CBLACK,CGREY,CWHITE,CBRIGHT,CRED;
252
extern UI_GADGET * selected_gadget;
253
 
254
#define Hline(C,x1,x2,y,c)      Hline(C,x1,y,x2,c)
255
#define Vline(C,y1,y2,x,c)      Vline(C,x,y1,y2,c)
256
void Hline(grs_canvas &, fix x1, fix x2, fix y, color_palette_index color);
257
void Vline(grs_canvas &, fix y1, fix y2, fix x, color_palette_index color);
258
void ui_string_centered(grs_canvas &, unsigned x, unsigned y, const char *s);
259
void ui_draw_box_out(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
260
void ui_draw_box_in(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
261
void ui_draw_frame(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
262
void ui_draw_shad(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2, color_palette_index c1, color_palette_index c2);
263
 
264
int ui_init();
265
void ui_close();
266
 
267
typedef cstring_tie<10> ui_messagebox_tie;
268
int ui_messagebox( short xc, short yc, const char * text, const ui_messagebox_tie &Button );
269
#define ui_messagebox(X,Y,N,T,...)      ((ui_messagebox)((X),(Y),(T), ui_messagebox_tie(__VA_ARGS__)))
270
 
271
class unused_ui_userdata_t;
272
constexpr unused_ui_userdata_t *unused_ui_userdata = nullptr;
273
 
274
template <typename T1, typename T2 = const void>
275
UI_DIALOG * ui_create_dialog(const short x, const short y, const short w, const short h, const enum dialog_flags flags, const ui_subfunction_t<T1> callback, T1 *const userdata, T2 *const createdata = nullptr)
276
{
277
        return new UI_DIALOG(x, y, w, h, flags, reinterpret_cast<ui_subfunction_t<void>>(callback), static_cast<void *>(userdata), static_cast<const void *>(createdata));
278
}
279
 
280
template <typename T1, typename T2 = const void>
281
UI_DIALOG *ui_create_dialog(const short x, const short y, const short w, const short h, const enum dialog_flags flags, const ui_subfunction_t<T1> callback, std::unique_ptr<T1> userdata, T2 *const createdata = nullptr)
282
{
283
        auto r = ui_create_dialog(x, y, w, h, flags, callback, userdata.get(), createdata);
284
        userdata.release();
285
        return r;
286
}
287
 
288
extern class window *ui_dialog_get_window(UI_DIALOG *dlg);
289
extern void ui_dialog_set_current_canvas(UI_DIALOG *dlg);
290
extern void ui_close_dialog( UI_DIALOG * dlg );
291
 
292
#define GADGET_PRESSED(g) (event.type == EVENT_UI_GADGET_PRESSED && ui_event_get_gadget(event) == g)
293
 
294
void ui_gadget_add(UI_DIALOG *dlg, short x1, short y1, short x2, short y2, UI_GADGET *);
295
template <typename T>
296
__attribute_warn_unused_result
297
static std::unique_ptr<T> ui_gadget_add(UI_DIALOG *dlg, short x1, short y1, short x2, short y2)
298
{
299
        auto t = std::make_unique<T>();
300
        t->kind = T::s_kind;
301
        ui_gadget_add(dlg, x1, y1, x2, y2, t.get());
302
        return t;
303
}
304
__attribute_warn_unused_result
305
std::unique_ptr<UI_GADGET_BUTTON> ui_add_gadget_button(UI_DIALOG * dlg, short x, short y, short w, short h, const char * text, int (*function_to_call)());
306
window_event_result ui_gadget_send_event(UI_DIALOG *dlg, enum event_type type, UI_GADGET *gadget);
307
extern UI_GADGET *ui_event_get_gadget(const d_event &event);
308
window_event_result ui_dialog_do_gadgets( UI_DIALOG * dlg, const d_event &event );
309
extern void ui_draw_button( UI_DIALOG *dlg, UI_GADGET_BUTTON * button );
310
 
311
extern int ui_mouse_on_gadget( UI_GADGET * gadget );
312
 
313
window_event_result ui_button_do( UI_DIALOG *dlg, UI_GADGET_BUTTON * button, const d_event &event );
314
 
315
window_event_result ui_listbox_do( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox, const d_event &event );
316
extern void ui_draw_listbox( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox );
317
std::unique_ptr<UI_GADGET_LISTBOX> ui_add_gadget_listbox(UI_DIALOG *dlg, short x, short y, short w, short h, short numitems, char **list);
318
 
319
extern void ui_mega_process();
320
 
321
void ui_get_button_size(const grs_font &, const char *text, int &width, int &height);
322
 
323
__attribute_warn_unused_result
324
std::unique_ptr<UI_GADGET_SCROLLBAR> ui_add_gadget_scrollbar(UI_DIALOG * dlg, short x, short y, short w, short h, int start, int stop, int position, int window_size);
325
window_event_result ui_scrollbar_do( UI_DIALOG *dlg, UI_GADGET_SCROLLBAR * scrollbar, const d_event &event );
326
extern void ui_draw_scrollbar( UI_DIALOG *dlg, UI_GADGET_SCROLLBAR * scrollbar );
327
 
328
 
329
void ui_dputs_at( UI_DIALOG * dlg, short x, short y, const char * str );
330
extern void ui_dprintf_at( UI_DIALOG * dlg, short x, short y, const char * format, ... ) __attribute_format_printf(4, 5);
331
#define ui_dprintf_at(A1,A2,A3,F,...)   dxx_call_printf_checked(ui_dprintf_at,ui_dputs_at,(A1,A2,A3),(F),##__VA_ARGS__)
332
 
333
extern void ui_draw_radio( UI_DIALOG *dlg, UI_GADGET_RADIO * radio );
334
__attribute_warn_unused_result
335
std::unique_ptr<UI_GADGET_RADIO> ui_add_gadget_radio(UI_DIALOG * dlg, short x, short y, short w, short h, short group, const char * text);
336
window_event_result ui_radio_do( UI_DIALOG *dlg, UI_GADGET_RADIO * radio, const d_event &event );
337
extern void ui_radio_set_value(UI_GADGET_RADIO *radio, int value);
338
 
339
extern void ui_draw_checkbox( UI_DIALOG *dlg, UI_GADGET_CHECKBOX * checkbox );
340
__attribute_warn_unused_result
341
std::unique_ptr<UI_GADGET_CHECKBOX> ui_add_gadget_checkbox(UI_DIALOG * dlg, short x, short y, short w, short h, short group, const char * text);
342
window_event_result ui_checkbox_do( UI_DIALOG *dlg, UI_GADGET_CHECKBOX * checkbox, const d_event &event );
343
extern void ui_checkbox_check(UI_GADGET_CHECKBOX * checkbox, int check);
344
 
345
extern UI_GADGET * ui_gadget_get_prev( UI_GADGET * gadget );
346
extern UI_GADGET * ui_gadget_get_next( UI_GADGET * gadget );
347
extern void ui_gadget_calc_keys( UI_DIALOG * dlg);
348
 
349
void ui_listbox_change(UI_DIALOG *dlg, UI_GADGET_LISTBOX *listbox, uint_fast32_t numitems, const char *const *list);
350
 
351
extern void ui_draw_inputbox( UI_DIALOG *dlg, UI_GADGET_INPUTBOX * inputbox );
352
__attribute_warn_unused_result
353
std::unique_ptr<UI_GADGET_INPUTBOX> ui_add_gadget_inputbox(UI_DIALOG * dlg, short x, short y, short w, short h, const char * text);
354
 
355
template <std::size_t SL, std::size_t L>
356
__attribute_warn_unused_result
357
static inline std::unique_ptr<UI_GADGET_INPUTBOX> ui_add_gadget_inputbox(UI_DIALOG * dlg, short x, short y, const char (&text)[L])
358
{
359
        static_assert(SL <= L, "SL too large");
360
        return ui_add_gadget_inputbox(dlg, x, y, L, SL, text);
361
}
362
 
363
window_event_result ui_inputbox_do( UI_DIALOG *dlg, UI_GADGET_INPUTBOX * inputbox, const d_event &event );
364
extern void ui_inputbox_set_text(UI_GADGET_INPUTBOX *inputbox, const char *text);
365
 
366
 
367
window_event_result ui_userbox_do( UI_DIALOG *dlg, UI_GADGET_USERBOX * userbox, const d_event &event );
368
__attribute_warn_unused_result
369
std::unique_ptr<UI_GADGET_USERBOX> ui_add_gadget_userbox(UI_DIALOG * dlg, short x, short y, short w, short h);
370
extern void ui_draw_userbox( UI_DIALOG *dlg, UI_GADGET_USERBOX * userbox );
371
 
372
 
373
int MenuX( int x, int y, int NumButtons, const char *const text[] );
374
 
375
int ui_get_filename(char (&filename)[PATH_MAX], const char *filespec, const char *message);
376
 
377
 
378
void * ui_malloc( int size );
379
void ui_free( void * buffer );
380
 
381
#define UI_RECORD_MOUSE     1
382
#define UI_RECORD_KEYS      2
383
#define UI_STATUS_NORMAL    0
384
#define UI_STATUS_RECORDING 1
385
#define UI_STATUS_PLAYING   2
386
#define UI_STATUS_FASTPLAY  3
387
 
388
int ui_get_file( char * filename, const char * Filespec  );
389
 
390
void ui_draw_icon( UI_GADGET_ICON * icon );
391
window_event_result ui_icon_do( UI_DIALOG *dlg, UI_GADGET_ICON * icon, const d_event &event );
392
__attribute_warn_unused_result
393
std::unique_ptr<UI_GADGET_ICON> ui_add_gadget_icon(UI_DIALOG * dlg, const char * text, short x, short y, short w, short h, int k,int (*f)());
394
 
395
int DecodeKeyText( const char * text );
396
void GetKeyDescription(char (&text)[100], uint_fast32_t keypress);
397
 
398
int menubar_init(grs_canvas &canvas, const char * filename );
399
extern void menubar_close();
400
extern void menubar_hide();
401
extern void menubar_show();
402
 
403
void ui_pad_init();
404
void ui_pad_close();
405
void ui_pad_activate(UI_DIALOG &dlg, uint_fast32_t x, uint_fast32_t y);
406
void ui_pad_deactivate();
407
void ui_pad_goto(int n);
408
void ui_pad_goto_next();
409
void ui_pad_goto_prev();
410
int ui_pad_read( int n, const char * filename );
411
int ui_pad_get_current();
412
void ui_pad_draw(UI_DIALOG *dlg, int x, int y);
413
 
414
void ui_barbox_open( const char * text, int length );
415
void ui_barbox_update( int position );
416
void ui_barbox_close();
417
 
418
extern int ui_button_any_drawn;
419
 
420
}
421
 
422
#endif