Allow dcx::window struct to be subclassed - step 2

Allow dcx::window struct to be subclassed step 2. This step renames and reconfigures window_create in window.cpp to be the main constructor. Also add a template constructor that allows an event handler that takes a subclass of window.
This commit is contained in:
Chris Taylor 2016-10-02 14:49:22 +08:00
parent 15e9f4a383
commit f117df9eee
3 changed files with 21 additions and 14 deletions

View file

@ -25,18 +25,18 @@ namespace dcx {
static window *FrontWindow = NULL;
static window *FirstWindow = NULL;
window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction<void> event_callback, void *data, const void *createdata)
window::window(grs_canvas *src, int x, int y, int w, int h, window_subfunction<void> event_callback, void *data, const void *createdata)
{
window *prev = window_get_front();
window *prev_front = window_get_front();
d_create_event event;
window *wind = new window;
window *wind = this;
Assert(src != NULL);
Assert(event_callback != NULL);
gr_init_sub_canvas(wind->w_canv, *src, x, y, w, h);
wind->w_callback = event_callback;
wind->w_visible = 1; // default to visible
wind->w_modal = 1; // default to modal
wind->data = data;
wind->w_data = data;
if (FirstWindow == NULL)
FirstWindow = wind;
@ -45,14 +45,12 @@ window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfun
FrontWindow->next = wind;
wind->next = NULL;
FrontWindow = wind;
if (prev)
WINDOW_SEND_EVENT(prev, EVENT_WINDOW_DEACTIVATED);
if (prev_front)
WINDOW_SEND_EVENT(prev_front, EVENT_WINDOW_DEACTIVATED);
event.createdata = createdata;
WINDOW_SEND_EVENT(wind, EVENT_WINDOW_CREATED);
WINDOW_SEND_EVENT(wind, EVENT_WINDOW_ACTIVATED);
return wind;
}
int window_close(window *wind)

View file

@ -24,14 +24,15 @@ enum class window_event_result : uint8_t;
template <typename T>
using window_subfunction = window_event_result (*)(window *menu,const d_event &event, T *userdata);
template <typename T>
using window_subclass_subfunction = window_event_result (*)(T *menu,const d_event &event, void*);
class unused_window_userdata_t;
/* No declaration for embed_window_pointer_t or ignore_window_pointer_t
* since every user needs the full definition.
*/
window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction<void> event_callback, void *userdata, const void *createdata);
int window_close(window *wind);
int window_exists(window *wind);
window *window_get_front();

View file

@ -57,11 +57,19 @@ private:
window_subfunction<void> w_callback; // the event handler
int w_visible; // whether it's visible
int w_modal; // modal = accept all user input exclusively
void *data; // whatever the user wants (eg menu data for 'newmenu' menus)
void *w_data; // whatever the user wants (eg menu data for 'newmenu' menus)
struct window *prev; // the previous window in the doubly linked list
struct window *next; // the next window in the doubly linked list
public:
// For creating the window, there are two ways - using the (older) window_create function
// or using the constructor, passing an event handler that takes a subclass of window.
explicit window(grs_canvas *src, int x, int y, int w, int h, window_subfunction<void> event_callback, void *data, const void *createdata);
template <typename T>
window(grs_canvas *src, int x, int y, int w, int h, window_subclass_subfunction<T> event_callback) :
window(src, x, y, w, h, reinterpret_cast<window_subclass_subfunction<window>>(event_callback), nullptr, nullptr) {}
// Declaring as friends to keep function syntax, for historical reasons (for now at least)
// Intended to transition to the class method form
friend window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction<void> event_callback, void *userdata, const void *createdata);
@ -113,7 +121,7 @@ public:
friend window_event_result window_send_event(window &wind, const d_event &event)
{
auto r = wind.w_callback(&wind, event, wind.data);
auto r = wind.w_callback(&wind, event, wind.w_data);
if (r == window_event_result::close)
window_close(&wind);
return r;
@ -134,7 +142,7 @@ public:
template <typename T1, typename T2 = const void>
static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction<T1> event_callback, T1 *data, T2 *createdata = nullptr)
{
auto win = window_create(src, x, y, w, h, reinterpret_cast<window_subfunction<void>>(event_callback), static_cast<void *>(data), static_cast<const void *>(createdata));
auto win = new window(src, x, y, w, h, reinterpret_cast<window_subfunction<void>>(event_callback), static_cast<void *>(data), static_cast<const void *>(createdata));
set_embedded_window_pointer(data, win);
return win;
}
@ -142,7 +150,7 @@ static inline window *window_create(grs_canvas *src, int x, int y, int w, int h,
template <typename T1, typename T2 = const void>
static inline window *window_create(grs_canvas *src, int x, int y, int w, int h, window_subfunction<const T1> event_callback, const T1 *userdata, T2 *createdata = nullptr)
{
return window_create(src, x, y, w, h, reinterpret_cast<window_subfunction<void>>(event_callback), static_cast<void *>(const_cast<T1 *>(userdata)), static_cast<const void *>(createdata));
return new window(src, x, y, w, h, reinterpret_cast<window_subfunction<void>>(event_callback), static_cast<void *>(const_cast<T1 *>(userdata)), static_cast<const void *>(createdata));
}
static inline window_event_result (WINDOW_SEND_EVENT)(window &w, const d_event &event, const char *file, unsigned line, const char *e)