diff --git a/common/include/ui.h b/common/include/ui.h index 4be53f541..a329366dc 100644 --- a/common/include/ui.h +++ b/common/include/ui.h @@ -214,7 +214,7 @@ enum dialog_flags template using ui_subfunction_t = window_event_result (*)(struct UI_DIALOG *,const d_event &, T *); -struct UI_DIALOG : embed_window_pointer_t +struct UI_DIALOG : window { // TODO: Make these private ui_subfunction_t d_callback; @@ -227,9 +227,10 @@ struct UI_DIALOG : embed_window_pointer_t 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 callback, void *userdata, const void *createdata); + explicit UI_DIALOG(short x, short y, short w, short h, enum dialog_flags flags, ui_subfunction_t callback, void *userdata); ~UI_DIALOG(); + virtual window_event_result event_handler(const d_event &) override; }; #define B1_JUST_PRESSED (event.type == EVENT_MOUSE_BUTTON_DOWN && event_mouse_get_button(event) == 0) @@ -264,7 +265,9 @@ constexpr unused_ui_userdata_t *unused_ui_userdata = nullptr; template 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 callback, T1 *const userdata, T2 *const createdata = nullptr) { - return new UI_DIALOG(x, y, w, h, flags, reinterpret_cast>(callback), static_cast(userdata), static_cast(createdata)); + auto r = std::make_unique(x, y, w, h, flags, reinterpret_cast>(callback), static_cast(userdata)); + r->send_creation_events(createdata); + return r.release(); } template diff --git a/common/ui/dialog.cpp b/common/ui/dialog.cpp index 167e466b7..2762767d8 100644 --- a/common/ui/dialog.cpp +++ b/common/ui/dialog.cpp @@ -62,7 +62,7 @@ static void ui_dialog_draw(UI_DIALOG *dlg) // The dialog handler borrows heavily from the newmenu_handler -static window_event_result ui_dialog_handler(window *wind,const d_event &event, UI_DIALOG *dlg) +window_event_result UI_DIALOG::event_handler(const d_event &event) { window_event_result rval{window_event_result::ignored}; @@ -70,8 +70,8 @@ static window_event_result ui_dialog_handler(window *wind,const d_event &event, event.type == EVENT_WINDOW_DEACTIVATED) return window_event_result::ignored; - if (dlg->d_callback) - if ((rval = (*dlg->d_callback)(dlg, event, dlg->d_userdata)) != window_event_result::ignored) + if (d_callback) + if ((rval = (*d_callback)(this, event, d_userdata)) != window_event_result::ignored) return rval; // event handled switch (event.type) @@ -84,66 +84,55 @@ static window_event_result ui_dialog_handler(window *wind,const d_event &event, case EVENT_MOUSE_MOVED: case EVENT_KEY_COMMAND: case EVENT_KEY_RELEASE: - return ui_dialog_do_gadgets(dlg, event); + return ui_dialog_do_gadgets(this, event); case EVENT_WINDOW_DRAW: { - ui_dialog_draw(dlg); - rval = ui_dialog_do_gadgets(dlg, event); + ui_dialog_draw(this); + rval = ui_dialog_do_gadgets(this, event); if (rval != window_event_result::close) { d_event event2 = { EVENT_UI_DIALOG_DRAW }; - window_send_event(*wind, event2); + window_send_event(*this, event2); } return rval; } case EVENT_WINDOW_CLOSE: if (rval != window_event_result::deleted) // check if handler already deleted dialog (e.g. if UI_DIALOG was subclassed) - delete dlg; - return window_event_result::ignored; // free the window in any case (until UI_DIALOG is subclass of window) + delete this; + return window_event_result::deleted; // free the window in any case (until UI_DIALOG is subclass of window) default: return window_event_result::ignored; } } -UI_DIALOG::UI_DIALOG(short x, short y, const short w, const short h, const enum dialog_flags flags, const ui_subfunction_t callback, void *const userdata, const void *const createdata) : +static short adjust_starting_coordinate(short value, const int limit) +{ + if (value < 0) + value = 0; + if (value - 1 >= limit) + value = limit; + return value; +} + +UI_DIALOG::UI_DIALOG(short x, short y, const short w, const short h, const enum dialog_flags flags, const ui_subfunction_t callback, void *const userdata) : + window(grd_curscreen->sc_canvas, adjust_starting_coordinate(x, grd_curscreen->get_screen_width() - w), adjust_starting_coordinate(y, grd_curscreen->get_screen_height() - h), w, h), d_callback(callback), d_userdata(userdata), d_width(w), d_height(h), d_flags(flags) { - int sw, sh, req_w, req_h; - - auto dlg = this; - sw = grd_curscreen->get_screen_width(); - sh = grd_curscreen->get_screen_height(); - - //mouse_set_limits(0, 0, sw - 1, sh - 1); - - req_w = w; - req_h = h; - - if ( x < 0 ) x = 0; - if ( (x+w-1) >= sw ) x = sw - w; - if ( y < 0 ) y = 0; - if ( (y+h-1) >= sh ) y = sh - h; - selected_gadget = NULL; - dlg->wind = window_create(grd_curscreen->sc_canvas, - x, - y, - req_w, req_h, ui_dialog_handler, dlg, createdata); - if (!(flags & DF_MODAL)) - dlg->wind->set_modal(0); // make this window modeless, allowing events to propogate through the window stack + set_modal(0); // make this window modeless, allowing events to propogate through the window stack } window *ui_dialog_get_window(UI_DIALOG *dlg) { - return dlg->wind; + return dlg; } void ui_dialog_set_current_canvas(UI_DIALOG *dlg) { - gr_set_current_canvas(dlg->wind->w_canv); + gr_set_current_canvas(dlg->w_canv); } UI_DIALOG::~UI_DIALOG() @@ -153,7 +142,7 @@ UI_DIALOG::~UI_DIALOG() void ui_close_dialog( UI_DIALOG * dlg ) { - window_close(dlg->wind); + window_close(dlg); } #if 0