Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
3
 * It is copyright by its individual contributors, as recorded in the
4
 * project's Git history.  See COPYING.txt at the top level for license
5
 * terms and a link to the Git history.
6
 */
7
/*
8
 *  A 'window' is simply a canvas that can receive events.
9
 *  It can be anything from a simple message box to the
10
 *      game screen when playing.
11
 *
12
 *  See event.c for event handling code.
13
 *
14
 *      -kreator 2009-05-06
15
 */
16
 
17
#pragma once
18
 
19
#include "gr.h"
20
#include "console.h"
21
 
22
#ifdef __cplusplus
23
#include <assert.h>
24
 
25
#include "fwd-window.h"
26
#include "event.h"
27
namespace dcx {
28
 
29
constexpr const unused_window_userdata_t *unused_window_userdata = nullptr;
30
 
31
struct embed_window_pointer_t
32
{
33
        window *wind;
34
};
35
 
36
struct ignore_window_pointer_t
37
{
38
};
39
 
40
static inline void set_embedded_window_pointer(embed_window_pointer_t *wp, window *w)
41
{
42
        wp->wind = w;
43
}
44
 
45
static inline void set_embedded_window_pointer(ignore_window_pointer_t *, window *) {}
46
 
47
class window
48
{
49
        grs_canvas w_canv;                                      // the window's canvas to draw to
50
        int w_visible;                                          // whether it's visible
51
        int w_modal;                                            // modal = accept all user input exclusively
52
        class window *prev;                             // the previous window in the doubly linked list
53
        class window *next;                             // the next window in the doubly linked list
54
        bool *w_exists;                                 // optional pointer to a tracking variable
55
 
56
public:
57
        // For creating the window, there are two ways - using the (older) window_create function
58
        // or using the constructor, passing an event handler that takes a subclass of window.
59
        explicit window(grs_canvas &src, int x, int y, int w, int h);
60
 
61
        virtual ~window();
62
 
63
        virtual window_event_result event_handler(const d_event &) = 0;
64
 
65
        void send_creation_events(const void *createdata);
66
        // Declaring as friends to keep function syntax, for historical reasons (for now at least)
67
        // Intended to transition to the class method form
68
        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);
69
 
70
        friend int window_close(window *wind);
71
        friend window *window_get_front();
72
        friend window *window_get_first();
73
        friend void window_select(window &wind);
74
        friend window *window_set_visible(window &wind, int visible);
75
#if !DXX_USE_OGL
76
        friend void window_update_canvases();
77
#endif
78
 
79
        friend grs_canvas &window_get_canvas(window &wind)
80
        {
81
                return wind.w_canv;
82
        }
83
 
84
        friend window *window_set_visible(window *wind, int visible)
85
        {
86
                return window_set_visible(*wind, visible);
87
        }
88
 
89
        int is_visible()
90
        {
91
                return w_visible;
92
        }
93
 
94
        friend int window_is_visible(window *wind)
95
        {
96
                return wind->is_visible();
97
        }
98
 
99
        void set_modal(int modal)
100
        {
101
                w_modal = modal;
102
        }
103
 
104
        friend void window_set_modal(window *wind, int modal)
105
        {
106
                wind->set_modal(modal);
107
        }
108
 
109
        friend int window_is_modal(window &wind)
110
        {
111
                return wind.w_modal;
112
        }
113
 
114
        friend window_event_result window_send_event(window &wind, const d_event &event)
115
        {
116
                auto r = wind.event_handler(event);
117
                if (r == window_event_result::close)
118
                        if (window_close(&wind))
119
                                return window_event_result::deleted;
120
 
121
                return r;
122
        }
123
 
124
        friend window *window_get_next(window &wind)
125
        {
126
                return wind.next;
127
        }
128
 
129
        friend window *window_get_prev(window &wind)
130
        {
131
                return wind.prev;
132
        }
133
 
134
        void track(bool *exists)
135
        {
136
                assert(w_exists == nullptr);
137
                w_exists = exists;
138
        }
139
};
140
 
141
class callback_window : public window
142
{
143
        window_subfunction<void> w_callback;    // the event handler
144
        void *w_data;                                           // whatever the user wants (eg menu data for 'newmenu' menus)
145
public:
146
        callback_window(grs_canvas &src, int x, int y, int w, int h, window_subfunction<void> event_callback, void *data);
147
        virtual window_event_result event_handler(const d_event &) override;
148
};
149
 
150
template <typename T1, typename T2 = const void>
151
static inline callback_window *window_create(grs_canvas &src, int x, int y, int w, int h, window_subfunction<T1> event_callback, T1 *data, T2 *createdata = nullptr)
152
{
153
        const auto win = new callback_window(src, x, y, w, h, reinterpret_cast<window_subfunction<void>>(event_callback), static_cast<void *>(data));
154
        set_embedded_window_pointer(data, win);
155
        win->send_creation_events(createdata);
156
        return win;
157
}
158
 
159
template <typename T1, typename T2 = const void>
160
static inline callback_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)
161
{
162
        const auto win = new callback_window(src, x, y, w, h, reinterpret_cast<window_subfunction<void>>(event_callback), static_cast<void *>(const_cast<T1 *>(userdata)));
163
        win->send_creation_events(createdata);
164
        return win;
165
}
166
 
167
static inline window_event_result (WINDOW_SEND_EVENT)(window &w, const d_event &event, const char *const file, const unsigned line)
168
{
169
        auto &c = window_get_canvas(w);
170
        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);
171
        return window_send_event(w, event);
172
}
173
 
174
void menu_destroy_hook(window *w);
175
 
176
}
177
#endif