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

Allow dcx::window struct to be subclassed step 1. This step moves the definition for the window struct into window.h, keeping all member variables private and declaring the window related functions as 'friends'. This avoids changes to source files that use the window struct at this stage. Also moving some of the simpler functions in window.cpp into the struct definition to inline them. I would prefer to use class methods, so changing some of these to class methods as well.
This commit is contained in:
Chris Taylor 2016-10-02 14:32:30 +08:00
parent 437d1717d8
commit 15e9f4a383
3 changed files with 82 additions and 65 deletions

View file

@ -22,17 +22,6 @@
namespace dcx {
struct window
{
grs_canvas w_canv; // the window's canvas to draw to
window_event_result (*w_callback)(window *wind,const d_event &event, void *data); // 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)
struct window *prev; // the previous window in the doubly linked list
struct window *next; // the next window in the doubly linked list
};
static window *FrontWindow = NULL;
static window *FirstWindow = NULL;
@ -127,16 +116,6 @@ window *window_get_first(void)
return FirstWindow;
}
window *window_get_next(window &wind)
{
return wind.next;
}
window *window_get_prev(window &wind)
{
return wind.prev;
}
// Make wind the front window
void window_select(window &wind)
{
@ -156,7 +135,7 @@ void window_select(window &wind)
wind.next = nullptr;
FrontWindow = &wind;
if (window_is_visible(wind))
if (wind.is_visible())
{
if (prev)
WINDOW_SEND_EVENT(prev, EVENT_WINDOW_DEACTIVATED);
@ -181,16 +160,6 @@ window *window_set_visible(window &w, int visible)
return wind;
}
int window_is_visible(window &wind)
{
return wind.w_visible;
}
grs_canvas &window_get_canvas(window &wind)
{
return wind.w_canv;
}
#if !DXX_USE_OGL
void window_update_canvases()
{
@ -206,22 +175,4 @@ void window_update_canvases()
}
#endif
window_event_result window_send_event(window &wind, const d_event &event)
{
auto r = wind.w_callback(&wind, event, wind.data);
if (r == window_event_result::close)
window_close(&wind);
return r;
}
void window_set_modal(window &wind, int modal)
{
wind.w_modal = modal;
}
int window_is_modal(window &wind)
{
return wind.w_modal;
}
}

View file

@ -40,13 +40,11 @@ window *window_get_next(window &wind);
window *window_get_prev(window &wind);
void window_select(window &wind);
window *window_set_visible(window &wind, int visible);
int window_is_visible(window &wind);
grs_canvas &window_get_canvas(window &wind);
#if !DXX_USE_OGL
void window_update_canvases();
#endif
window_event_result window_send_event(window &wind,const d_event &event);
void window_set_modal(window &wind, int modal);
int window_is_modal(window &wind);
#define WINDOW_SEND_EVENT(w, e) (event.type = e, (WINDOW_SEND_EVENT)(*w, event, __FILE__, __LINE__, #e))

View file

@ -50,6 +50,87 @@ static inline void set_embedded_window_pointer(embed_window_pointer_t *wp, windo
static inline void set_embedded_window_pointer(ignore_window_pointer_t *, window *) {}
struct window
{
private:
grs_canvas w_canv; // the window's canvas to draw to
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)
struct window *prev; // the previous window in the doubly linked list
struct window *next; // the next window in the doubly linked list
public:
// 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);
friend int window_close(window *wind);
friend int window_exists(window *wind);
friend window *window_get_front();
friend window *window_get_first();
friend void window_select(window &wind);
friend window *window_set_visible(window &wind, int visible);
#if !DXX_USE_OGL
friend void window_update_canvases();
#endif
friend grs_canvas &window_get_canvas(window &wind)
{
return wind.w_canv;
}
friend window *window_set_visible(window *wind, int visible)
{
return window_set_visible(*wind, visible);
}
int is_visible()
{
return w_visible;
}
friend int window_is_visible(window *wind)
{
return wind->is_visible();
}
void set_modal(int modal)
{
w_modal = modal;
}
friend void window_set_modal(window *wind, int modal)
{
wind->set_modal(modal);
}
friend int window_is_modal(window &wind)
{
return wind.w_modal;
}
friend window_event_result window_send_event(window &wind, const d_event &event)
{
auto r = wind.w_callback(&wind, event, wind.data);
if (r == window_event_result::close)
window_close(&wind);
return r;
}
friend window *window_get_next(window &wind)
{
return wind.next;
}
friend window *window_get_prev(window &wind)
{
return wind.prev;
}
};
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)
{
@ -64,19 +145,6 @@ static inline window *window_create(grs_canvas *src, int x, int y, int w, int h,
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));
}
static inline window *window_set_visible(window *wind, int visible)
{
return window_set_visible(*wind, visible);
}
static inline int window_is_visible(window *wind)
{
return window_is_visible(*wind);
}
static inline void window_set_modal(window *wind, int modal)
{
window_set_modal(*wind, modal);
}
static inline window_event_result (WINDOW_SEND_EVENT)(window &w, const d_event &event, const char *file, unsigned line, const char *e)
{
auto &c = window_get_canvas(w);