426 lines
15 KiB
C++
426 lines
15 KiB
C++
/*
|
|
* Portions of this file are copyright Rebirth contributors and licensed as
|
|
* described in COPYING.txt.
|
|
* Portions of this file are copyright Parallax Software and licensed
|
|
* according to the Parallax license below.
|
|
* See COPYING.txt for license details.
|
|
|
|
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
|
|
SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
|
|
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
|
|
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
|
|
IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
|
|
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
|
|
FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
|
|
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
|
|
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
|
|
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|
*/
|
|
|
|
/*
|
|
*
|
|
* Header file for user interface
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "dxxsconf.h"
|
|
#include "dsx-ns.h"
|
|
#include "fwd-event.h"
|
|
#include "fmtcheck.h"
|
|
#include "u_mem.h"
|
|
|
|
#ifdef __cplusplus
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include "fwd-gr.h"
|
|
#include "varutil.h"
|
|
#include "window.h"
|
|
#include "compiler-array.h"
|
|
#include "compiler-make_unique.h"
|
|
#include "compiler-type_traits.h"
|
|
#include "ntstring.h"
|
|
|
|
struct grs_bitmap;
|
|
struct grs_font;
|
|
|
|
namespace dcx {
|
|
|
|
struct UI_KEYPAD {
|
|
typedef array<char, 100> buttontext_element_t;
|
|
typedef array<buttontext_element_t, 17> buttontext_t;
|
|
UI_KEYPAD();
|
|
unsigned numkeys;
|
|
ntstring<99> description;
|
|
array<short, 100> keycode;
|
|
array<int, 100> function_number;
|
|
buttontext_t buttontext;
|
|
};
|
|
|
|
struct UI_EVENT
|
|
{
|
|
unsigned int frame;
|
|
int type;
|
|
int data;
|
|
};
|
|
|
|
struct UI_GADGET
|
|
{
|
|
uint8_t kind;
|
|
short x1,y1,x2,y2;
|
|
int hotkey;
|
|
struct UI_GADGET * prev; \
|
|
struct UI_GADGET * next; \
|
|
struct UI_GADGET * when_tab; \
|
|
struct UI_GADGET * when_btab; \
|
|
struct UI_GADGET * when_up; \
|
|
struct UI_GADGET * when_down; \
|
|
struct UI_GADGET * when_left; \
|
|
struct UI_GADGET * when_right; \
|
|
struct UI_GADGET * parent; \
|
|
int status; \
|
|
int oldstatus; \
|
|
grs_subcanvas_ptr canvas; \
|
|
protected:
|
|
~UI_GADGET() = default;
|
|
};
|
|
|
|
struct UI_GADGET_USERBOX : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 7>{};
|
|
short width, height;
|
|
short b1_held_down;
|
|
short b1_clicked;
|
|
short b1_double_clicked;
|
|
short b1_dragging;
|
|
short b1_drag_x1, b1_drag_y1;
|
|
short b1_drag_x2, b1_drag_y2;
|
|
short b1_done_dragging;
|
|
short mouse_onme;
|
|
short mouse_x, mouse_y;
|
|
int keypress;
|
|
grs_bitmap * bitmap;
|
|
};
|
|
|
|
struct UI_GADGET_BUTTON : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 1>{};
|
|
std::string text;
|
|
short width, height;
|
|
short position;
|
|
short oldposition;
|
|
short pressed;
|
|
uint8_t dim_if_no_function;
|
|
int hotkey1;
|
|
int (*user_function)(void);
|
|
int (*user_function1)(void);
|
|
};
|
|
|
|
struct UI_GADGET_INPUTBOX : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 6>{};
|
|
RAIIdmem<char[]> text;
|
|
short width, height;
|
|
short length;
|
|
short slength;
|
|
short position;
|
|
short oldposition;
|
|
short pressed;
|
|
short first_time;
|
|
};
|
|
|
|
struct UI_GADGET_RADIO : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 4>{};
|
|
RAIIdmem<char[]> text;
|
|
short width, height;
|
|
short position;
|
|
short oldposition;
|
|
short pressed;
|
|
short group;
|
|
short flag;
|
|
};
|
|
|
|
struct UI_GADGET_ICON : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 9>{};
|
|
RAIIdmem<char[]> text;
|
|
short width, height;
|
|
sbyte flag;
|
|
sbyte pressed;
|
|
sbyte position;
|
|
sbyte oldposition;
|
|
int trap_key;
|
|
int (*user_function)(void);
|
|
};
|
|
|
|
struct UI_GADGET_CHECKBOX : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 5>{};
|
|
RAIIdmem<char[]> text;
|
|
short width, height;
|
|
short position;
|
|
short oldposition;
|
|
short pressed;
|
|
short group;
|
|
short flag;
|
|
};
|
|
|
|
struct UI_GADGET_SCROLLBAR : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 3>{};
|
|
short horz;
|
|
short width, height;
|
|
int start;
|
|
int stop;
|
|
int position;
|
|
int window_size;
|
|
int fake_length;
|
|
int fake_position;
|
|
int fake_size;
|
|
std::unique_ptr<UI_GADGET_BUTTON> up_button, down_button;
|
|
fix64 last_scrolled;
|
|
short drag_x, drag_y;
|
|
int drag_starting;
|
|
int dragging;
|
|
int moved;
|
|
};
|
|
|
|
struct UI_GADGET_LISTBOX : UI_GADGET
|
|
{
|
|
static constexpr auto s_kind = tt::integral_constant<uint8_t, 2>{};
|
|
const char *const *list;
|
|
short width, height;
|
|
int num_items;
|
|
int num_items_displayed;
|
|
int first_item;
|
|
int old_first_item;
|
|
int current_item;
|
|
int selected_item;
|
|
int old_current_item;
|
|
int dragging;
|
|
int textheight;
|
|
int moved;
|
|
std::unique_ptr<UI_GADGET_SCROLLBAR> scrollbar;
|
|
fix64 last_scrolled;
|
|
};
|
|
|
|
enum dialog_flags
|
|
{
|
|
DF_BORDER = 1,
|
|
DF_FILLED = 2,
|
|
DF_SAVE_BG = 4,
|
|
DF_DIALOG = (4+2+1),
|
|
DF_MODAL = 8 // modal = accept all user input exclusively
|
|
};
|
|
|
|
template <typename T>
|
|
using ui_subfunction_t = window_event_result (*)(struct UI_DIALOG *,const d_event &, T *);
|
|
|
|
template <typename T>
|
|
using ui_subclass_subfunction_t = window_event_result (*)(T *,const d_event &, void *);
|
|
|
|
struct UI_DIALOG : embed_window_pointer_t
|
|
{
|
|
// TODO: Make these private
|
|
ui_subfunction_t<void> d_callback;
|
|
UI_GADGET * gadget;
|
|
UI_GADGET * keyboard_focus_gadget;
|
|
void *d_userdata;
|
|
short d_x, d_y;
|
|
short d_width, d_height;
|
|
short d_text_x, d_text_y;
|
|
enum dialog_flags d_flags;
|
|
|
|
public:
|
|
// For creating the dialog, there are two ways - using the (older) ui_create_dialog function
|
|
// or using the constructor, passing an event handler that takes a subclass of UI_DIALOG.
|
|
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);
|
|
|
|
template <typename T>
|
|
UI_DIALOG(short x, short y, short w, short h, enum dialog_flags flags, ui_subclass_subfunction_t<T> callback) :
|
|
UI_DIALOG(x, y, w, h, flags, reinterpret_cast<ui_subclass_subfunction_t<UI_DIALOG>>(callback), nullptr, nullptr) {}
|
|
|
|
~UI_DIALOG();
|
|
};
|
|
|
|
#define B1_JUST_PRESSED (event.type == EVENT_MOUSE_BUTTON_DOWN && event_mouse_get_button(event) == 0)
|
|
#define B1_JUST_RELEASED (event.type == EVENT_MOUSE_BUTTON_UP && event_mouse_get_button(event) == 0)
|
|
#define B1_DOUBLE_CLICKED (event.type == EVENT_MOUSE_DOUBLE_CLICKED && event_mouse_get_button(event) == 0)
|
|
|
|
extern grs_font_ptr ui_small_font;
|
|
|
|
extern unsigned char CBLACK,CGREY,CWHITE,CBRIGHT,CRED;
|
|
extern UI_GADGET * selected_gadget;
|
|
|
|
#define Hline(C,x1,x2,y,c) Hline(C,x1,y,x2,c)
|
|
#define Vline(C,y1,y2,x,c) Vline(C,x,y1,y2,c)
|
|
void Hline(grs_canvas &, fix x1, fix x2, fix y, uint8_t color);
|
|
void Vline(grs_canvas &, fix y1, fix y2, fix x, uint8_t color);
|
|
void ui_string_centered(grs_canvas &, unsigned x, unsigned y, const char *s);
|
|
void ui_draw_box_out(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
|
|
void ui_draw_box_in(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
|
|
void ui_draw_frame(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2);
|
|
void ui_draw_shad(grs_canvas &, unsigned x1, unsigned y1, unsigned x2, unsigned y2, unsigned c1, unsigned c2);
|
|
|
|
int ui_init();
|
|
void ui_close();
|
|
|
|
typedef cstring_tie<10> ui_messagebox_tie;
|
|
int ui_messagebox( short xc, short yc, const char * text, const ui_messagebox_tie &Button );
|
|
#define ui_messagebox(X,Y,N,T,...) ((ui_messagebox)((X),(Y),(T), ui_messagebox_tie(__VA_ARGS__)))
|
|
|
|
class unused_ui_userdata_t;
|
|
constexpr unused_ui_userdata_t *unused_ui_userdata = nullptr;
|
|
|
|
template <typename T1, typename T2 = const void>
|
|
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)
|
|
{
|
|
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));
|
|
}
|
|
|
|
template <typename T1, typename T2 = const void>
|
|
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)
|
|
{
|
|
auto r = ui_create_dialog(x, y, w, h, flags, callback, userdata.get(), createdata);
|
|
userdata.release();
|
|
return r;
|
|
}
|
|
|
|
extern class window *ui_dialog_get_window(UI_DIALOG *dlg);
|
|
extern void ui_dialog_set_current_canvas(UI_DIALOG *dlg);
|
|
extern void ui_close_dialog( UI_DIALOG * dlg );
|
|
|
|
#define GADGET_PRESSED(g) (event.type == EVENT_UI_GADGET_PRESSED && ui_event_get_gadget(event) == g)
|
|
|
|
void ui_gadget_add(UI_DIALOG *dlg, short x1, short y1, short x2, short y2, UI_GADGET *);
|
|
template <typename T>
|
|
__attribute_warn_unused_result
|
|
static std::unique_ptr<T> ui_gadget_add(UI_DIALOG *dlg, short x1, short y1, short x2, short y2)
|
|
{
|
|
auto t = make_unique<T>();
|
|
t->kind = T::s_kind;
|
|
ui_gadget_add(dlg, x1, y1, x2, y2, t.get());
|
|
return t;
|
|
}
|
|
__attribute_warn_unused_result
|
|
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)());
|
|
window_event_result ui_gadget_send_event(UI_DIALOG *dlg, enum event_type type, UI_GADGET *gadget);
|
|
extern UI_GADGET *ui_event_get_gadget(const d_event &event);
|
|
window_event_result ui_dialog_do_gadgets( UI_DIALOG * dlg, const d_event &event );
|
|
extern void ui_draw_button( UI_DIALOG *dlg, UI_GADGET_BUTTON * button );
|
|
|
|
extern int ui_mouse_on_gadget( UI_GADGET * gadget );
|
|
|
|
window_event_result ui_button_do( UI_DIALOG *dlg, UI_GADGET_BUTTON * button, const d_event &event );
|
|
|
|
window_event_result ui_listbox_do( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox, const d_event &event );
|
|
extern void ui_draw_listbox( UI_DIALOG *dlg, UI_GADGET_LISTBOX * listbox );
|
|
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);
|
|
|
|
extern void ui_mega_process();
|
|
|
|
void ui_get_button_size(const grs_font &, const char *text, int &width, int &height);
|
|
|
|
__attribute_warn_unused_result
|
|
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);
|
|
window_event_result ui_scrollbar_do( UI_DIALOG *dlg, UI_GADGET_SCROLLBAR * scrollbar, const d_event &event );
|
|
extern void ui_draw_scrollbar( UI_DIALOG *dlg, UI_GADGET_SCROLLBAR * scrollbar );
|
|
|
|
|
|
void ui_dputs_at( UI_DIALOG * dlg, short x, short y, const char * str );
|
|
extern void ui_dprintf_at( UI_DIALOG * dlg, short x, short y, const char * format, ... ) __attribute_format_printf(4, 5);
|
|
#define ui_dprintf_at(A1,A2,A3,F,...) dxx_call_printf_checked(ui_dprintf_at,ui_dputs_at,(A1,A2,A3),(F),##__VA_ARGS__)
|
|
|
|
extern void ui_draw_radio( UI_DIALOG *dlg, UI_GADGET_RADIO * radio );
|
|
__attribute_warn_unused_result
|
|
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);
|
|
window_event_result ui_radio_do( UI_DIALOG *dlg, UI_GADGET_RADIO * radio, const d_event &event );
|
|
extern void ui_radio_set_value(UI_GADGET_RADIO *radio, int value);
|
|
|
|
extern void ui_draw_checkbox( UI_DIALOG *dlg, UI_GADGET_CHECKBOX * checkbox );
|
|
__attribute_warn_unused_result
|
|
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);
|
|
window_event_result ui_checkbox_do( UI_DIALOG *dlg, UI_GADGET_CHECKBOX * checkbox, const d_event &event );
|
|
extern void ui_checkbox_check(UI_GADGET_CHECKBOX * checkbox, int check);
|
|
|
|
extern UI_GADGET * ui_gadget_get_prev( UI_GADGET * gadget );
|
|
extern UI_GADGET * ui_gadget_get_next( UI_GADGET * gadget );
|
|
extern void ui_gadget_calc_keys( UI_DIALOG * dlg);
|
|
|
|
void ui_listbox_change(UI_DIALOG *dlg, UI_GADGET_LISTBOX *listbox, uint_fast32_t numitems, const char *const *list);
|
|
|
|
extern void ui_draw_inputbox( UI_DIALOG *dlg, UI_GADGET_INPUTBOX * inputbox );
|
|
__attribute_warn_unused_result
|
|
std::unique_ptr<UI_GADGET_INPUTBOX> ui_add_gadget_inputbox(UI_DIALOG * dlg, short x, short y, short w, short h, const char * text);
|
|
|
|
template <std::size_t SL, std::size_t L>
|
|
__attribute_warn_unused_result
|
|
static inline std::unique_ptr<UI_GADGET_INPUTBOX> ui_add_gadget_inputbox(UI_DIALOG * dlg, short x, short y, const char (&text)[L])
|
|
{
|
|
static_assert(SL <= L, "SL too large");
|
|
return ui_add_gadget_inputbox(dlg, x, y, L, SL, text);
|
|
}
|
|
|
|
window_event_result ui_inputbox_do( UI_DIALOG *dlg, UI_GADGET_INPUTBOX * inputbox, const d_event &event );
|
|
extern void ui_inputbox_set_text(UI_GADGET_INPUTBOX *inputbox, const char *text);
|
|
|
|
|
|
window_event_result ui_userbox_do( UI_DIALOG *dlg, UI_GADGET_USERBOX * userbox, const d_event &event );
|
|
__attribute_warn_unused_result
|
|
std::unique_ptr<UI_GADGET_USERBOX> ui_add_gadget_userbox(UI_DIALOG * dlg, short x, short y, short w, short h);
|
|
extern void ui_draw_userbox( UI_DIALOG *dlg, UI_GADGET_USERBOX * userbox );
|
|
|
|
|
|
int MenuX( int x, int y, int NumButtons, const char *const text[] );
|
|
|
|
int ui_get_filename(char (&filename)[PATH_MAX], const char *filespec, const char *message);
|
|
|
|
|
|
void * ui_malloc( int size );
|
|
void ui_free( void * buffer );
|
|
|
|
#define UI_RECORD_MOUSE 1
|
|
#define UI_RECORD_KEYS 2
|
|
#define UI_STATUS_NORMAL 0
|
|
#define UI_STATUS_RECORDING 1
|
|
#define UI_STATUS_PLAYING 2
|
|
#define UI_STATUS_FASTPLAY 3
|
|
|
|
int ui_get_file( char * filename, const char * Filespec );
|
|
|
|
void ui_draw_icon( UI_GADGET_ICON * icon );
|
|
window_event_result ui_icon_do( UI_DIALOG *dlg, UI_GADGET_ICON * icon, const d_event &event );
|
|
__attribute_warn_unused_result
|
|
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)());
|
|
|
|
int DecodeKeyText( const char * text );
|
|
void GetKeyDescription(char (&text)[100], uint_fast32_t keypress);
|
|
|
|
extern int menubar_init(const char * filename );
|
|
extern void menubar_close();
|
|
extern void menubar_hide();
|
|
extern void menubar_show();
|
|
|
|
void ui_pad_init();
|
|
void ui_pad_close();
|
|
void ui_pad_activate(UI_DIALOG &dlg, uint_fast32_t x, uint_fast32_t y);
|
|
void ui_pad_deactivate();
|
|
void ui_pad_goto(int n);
|
|
void ui_pad_goto_next();
|
|
void ui_pad_goto_prev();
|
|
int ui_pad_read( int n, const char * filename );
|
|
int ui_pad_get_current();
|
|
void ui_pad_draw(UI_DIALOG *dlg, int x, int y);
|
|
|
|
void ui_barbox_open( const char * text, int length );
|
|
void ui_barbox_update( int position );
|
|
void ui_barbox_close();
|
|
|
|
extern int ui_button_any_drawn;
|
|
|
|
}
|
|
|
|
#endif
|