/* * This file is part of the DXX-Rebirth project . * It is copyright by its individual contributors, as recorded in the * project's Git history. See COPYING.txt at the top level for license * terms and a link to the Git history. */ /* * A 'window' is simply a canvas that can receive events. * It can be anything from a simple message box to the * game screen when playing. * * See event.c for event handling code. * * -kreator 2009-05-06 */ #pragma once #include "gr.h" #include "console.h" #include #include "fwd-window.h" #include "event.h" namespace dcx { class window { public: grs_subcanvas w_canv; // the window's canvas to draw to private: class window *prev; // the previous window in the doubly linked list class window *next = nullptr; // the next window in the doubly linked list uint8_t w_visible = 1; // whether it's visible uint8_t w_modal = 1; // modal = accept all user input exclusively bool *w_exists = nullptr; // optional pointer to a tracking variable public: explicit window(grs_canvas &src, int x, int y, int w, int h); window(const window &) = delete; window &operator=(const window &) = delete; virtual ~window(); virtual window_event_result event_handler(const d_event &) = 0; void send_creation_events(); friend int window_close(window *wind); friend window *window_get_front(); friend window *window_get_first(); friend void window_select(window &wind); #if !DXX_USE_OGL friend void window_update_canvases(); #endif uint8_t is_visible() const { return w_visible; } window *set_visible(uint8_t visible); void set_modal(uint8_t modal) { w_modal = modal; } uint8_t is_modal() const { return w_modal; } friend window_event_result window_send_event(window &wind, const d_event &event) { auto r = wind.event_handler(event); if (r == window_event_result::close) if (window_close(&wind)) return window_event_result::deleted; return r; } friend window *window_get_next(window &wind) { return wind.next; } friend window *window_get_prev(window &wind) { return wind.prev; } void track(bool *exists) { assert(w_exists == nullptr); w_exists = exists; } }; static inline window_event_result (WINDOW_SEND_EVENT)(window &w, const d_event &event, const char *const file, const unsigned line) { auto &c = w.w_canv; con_printf(CON_DEBUG, "%s:%u: sending event %i to window of dimensions %dx%d", file, line, event.type, c.cv_bitmap.bm_w, c.cv_bitmap.bm_h); return window_send_event(w, event); } void menu_destroy_hook(window *w); template T1 *window_create(ConstructionArgs &&... args) { auto r = std::make_unique(std::forward(args)...); r->send_creation_events(); return r.release(); } }