Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  423.