reflexion 0.2.1 → 0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.doc/ext/reflex/application.cpp +1 -1
- data/.doc/ext/reflex/capture_event.cpp +1 -1
- data/.doc/ext/reflex/contact_event.cpp +1 -1
- data/.doc/ext/reflex/draw_event.cpp +1 -1
- data/.doc/ext/reflex/ellipse_shape.cpp +1 -1
- data/.doc/ext/reflex/event.cpp +1 -1
- data/.doc/ext/reflex/filter.cpp +1 -1
- data/.doc/ext/reflex/focus_event.cpp +1 -1
- data/.doc/ext/reflex/frame_event.cpp +1 -1
- data/.doc/ext/reflex/image_view.cpp +1 -1
- data/.doc/ext/reflex/key_event.cpp +74 -69
- data/.doc/ext/reflex/line_shape.cpp +1 -1
- data/.doc/ext/reflex/motion_event.cpp +1 -1
- data/.doc/ext/reflex/pointer.cpp +1 -1
- data/.doc/ext/reflex/pointer_event.cpp +1 -1
- data/.doc/ext/reflex/polygon_shape.cpp +1 -1
- data/.doc/ext/reflex/rect_shape.cpp +1 -1
- data/.doc/ext/reflex/reflex.cpp +58 -50
- data/.doc/ext/reflex/screen.cpp +1 -1
- data/.doc/ext/reflex/scroll_event.cpp +1 -1
- data/.doc/ext/reflex/selector.cpp +2 -2
- data/.doc/ext/reflex/shape.cpp +1 -1
- data/.doc/ext/reflex/style.cpp +1 -1
- data/.doc/ext/reflex/style_length.cpp +2 -2
- data/.doc/ext/reflex/timer.cpp +1 -1
- data/.doc/ext/reflex/timer_event.cpp +1 -1
- data/.doc/ext/reflex/update_event.cpp +1 -1
- data/.doc/ext/reflex/view.cpp +1 -1
- data/.doc/ext/reflex/wheel_event.cpp +1 -1
- data/.doc/ext/reflex/window.cpp +1 -1
- data/.github/workflows/release-gem.yml +1 -1
- data/.github/workflows/test.yml +3 -0
- data/ChangeLog.md +5 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/ext/reflex/application.cpp +1 -1
- data/ext/reflex/capture_event.cpp +1 -1
- data/ext/reflex/contact_event.cpp +1 -1
- data/ext/reflex/defs.h +2 -0
- data/ext/reflex/draw_event.cpp +1 -1
- data/ext/reflex/ellipse_shape.cpp +1 -1
- data/ext/reflex/event.cpp +1 -1
- data/ext/reflex/extconf.rb +4 -4
- data/ext/reflex/filter.cpp +1 -1
- data/ext/reflex/focus_event.cpp +1 -1
- data/ext/reflex/frame_event.cpp +1 -1
- data/ext/reflex/image_view.cpp +1 -1
- data/ext/reflex/key_event.cpp +74 -69
- data/ext/reflex/line_shape.cpp +1 -1
- data/ext/reflex/motion_event.cpp +1 -1
- data/ext/reflex/pointer.cpp +1 -1
- data/ext/reflex/pointer_event.cpp +1 -1
- data/ext/reflex/polygon_shape.cpp +1 -1
- data/ext/reflex/rect_shape.cpp +1 -1
- data/ext/reflex/reflex.cpp +58 -50
- data/ext/reflex/screen.cpp +1 -1
- data/ext/reflex/scroll_event.cpp +1 -1
- data/ext/reflex/selector.cpp +2 -2
- data/ext/reflex/shape.cpp +1 -1
- data/ext/reflex/style.cpp +1 -1
- data/ext/reflex/style_length.cpp +2 -2
- data/ext/reflex/timer.cpp +1 -1
- data/ext/reflex/timer_event.cpp +1 -1
- data/ext/reflex/update_event.cpp +1 -1
- data/ext/reflex/view.cpp +1 -1
- data/ext/reflex/wheel_event.cpp +1 -1
- data/ext/reflex/window.cpp +1 -1
- data/include/reflex/defs.h +204 -187
- data/include/reflex/reflex.h +1 -0
- data/include/reflex/ruby/application.h +2 -2
- data/include/reflex/ruby/event.h +26 -26
- data/include/reflex/ruby/exception.h +3 -3
- data/include/reflex/ruby/filter.h +2 -2
- data/include/reflex/ruby/image_view.h +2 -2
- data/include/reflex/ruby/pointer.h +2 -2
- data/include/reflex/ruby/reflex.h +1 -1
- data/include/reflex/ruby/screen.h +2 -2
- data/include/reflex/ruby/selector.h +2 -2
- data/include/reflex/ruby/shape.h +10 -10
- data/include/reflex/ruby/style.h +4 -4
- data/include/reflex/ruby/timer.h +2 -2
- data/include/reflex/ruby/view.h +2 -2
- data/include/reflex/ruby/window.h +2 -2
- data/lib/reflex/extension.rb +4 -0
- data/reflex.gemspec +4 -4
- data/src/event.cpp +7 -3
- data/src/event.h +2 -0
- data/src/ios/event.mm +21 -27
- data/src/shape.cpp +2 -2
- data/src/view.cpp +1 -0
- data/src/win32/application.cpp +48 -35
- data/src/win32/device.cpp +18 -0
- data/src/win32/event.cpp +221 -0
- data/src/win32/event.h +50 -0
- data/src/win32/opengl.cpp +54 -27
- data/src/win32/opengl.h +15 -13
- data/src/win32/reflex.cpp +10 -16
- data/src/win32/screen.cpp +61 -0
- data/src/win32/screen.h +21 -0
- data/src/win32/window.cpp +445 -240
- data/src/window.cpp +1 -0
- data/test/test_window.rb +24 -21
- metadata +14 -11
- data/src/win32/defs.cpp +0 -303
- data/src/win32/defs.h +0 -34
data/src/win32/window.cpp
CHANGED
@@ -1,12 +1,19 @@
|
|
1
|
-
#include "
|
1
|
+
#include "../window.h"
|
2
2
|
|
3
3
|
|
4
|
+
#include <assert.h>
|
5
|
+
#include <map>
|
4
6
|
#include <memory>
|
5
|
-
#
|
6
|
-
#include <windows.h>
|
7
|
-
#include <rays/
|
8
|
-
#include "reflex/
|
9
|
-
#include "reflex/
|
7
|
+
#include <xot/time.h>
|
8
|
+
#include <xot/windows.h>
|
9
|
+
#include <rays/rays.h>
|
10
|
+
#include "reflex/defs.h"
|
11
|
+
#include "reflex/application.h"
|
12
|
+
#include "reflex/exception.h"
|
13
|
+
#include "reflex/debug.h"
|
14
|
+
#include "../view.h"
|
15
|
+
#include "event.h"
|
16
|
+
#include "screen.h"
|
10
17
|
#include "opengl.h"
|
11
18
|
|
12
19
|
|
@@ -14,77 +21,48 @@ namespace Reflex
|
|
14
21
|
{
|
15
22
|
|
16
23
|
|
17
|
-
|
18
|
-
{
|
19
|
-
|
20
|
-
Window* this_;
|
21
|
-
|
22
|
-
HWND hwnd;
|
23
|
-
|
24
|
-
int hidecount;
|
24
|
+
typedef std::map<int, String> PressingKeyMap;
|
25
25
|
|
26
|
-
bool redraw;
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
View::Ref root;
|
31
|
-
|
32
|
-
String title_tmp;
|
27
|
+
static const char* WINDOWCLASS = "Reflex:WindowClass";
|
33
28
|
|
34
|
-
|
29
|
+
static const char* USERDATA_PROP = "Reflex:Window:HWND";
|
35
30
|
|
36
|
-
|
37
|
-
: this_(NULL), hwnd(NULL), hidecount(1), redraw(true), root(new View)
|
38
|
-
{
|
39
|
-
root->set_name("root");
|
40
|
-
}
|
31
|
+
enum {UPDATE_TIMER_ID = 99999};
|
41
32
|
|
42
|
-
~Data ()
|
43
|
-
{
|
44
|
-
unbind();
|
45
|
-
}
|
46
33
|
|
47
|
-
|
48
|
-
|
49
|
-
if (!obj) return;
|
34
|
+
struct WindowData : public Window::Data
|
35
|
+
{
|
50
36
|
|
51
|
-
|
52
|
-
}
|
37
|
+
HWND hwnd = NULL;
|
53
38
|
|
54
|
-
|
55
|
-
{
|
56
|
-
this_ = NULL;
|
57
|
-
}
|
39
|
+
OpenGLContext context;
|
58
40
|
|
59
|
-
|
60
|
-
{
|
61
|
-
unbind_reflex();
|
62
|
-
}
|
41
|
+
PressingKeyMap pressing_keys;
|
63
42
|
|
64
|
-
|
65
|
-
{
|
66
|
-
return this_ && hwnd && IsWindow(hwnd);
|
67
|
-
}
|
43
|
+
mutable String title_tmp;
|
68
44
|
|
69
|
-
bool
|
45
|
+
bool is_valid () const
|
70
46
|
{
|
71
|
-
return
|
47
|
+
return hwnd && IsWindow(hwnd);
|
72
48
|
}
|
73
49
|
|
74
|
-
};//
|
75
|
-
|
76
|
-
typedef std::shared_ptr<Window::Data> WindowData;
|
77
|
-
|
78
|
-
|
79
|
-
static const char* WINDOWCLASS = "Reflex:WindowClass";
|
80
|
-
|
81
|
-
static const char* USERDATA_PROP = "Reflex:Window:HWND";
|
82
|
-
|
83
|
-
enum {UPDATE_TIMER_ID = 99999};
|
50
|
+
};// WindowData
|
84
51
|
|
85
52
|
|
86
53
|
static LRESULT CALLBACK wndproc (HWND, UINT, WPARAM, LPARAM);
|
87
54
|
|
55
|
+
static WindowData*
|
56
|
+
get_data (Window* window)
|
57
|
+
{
|
58
|
+
return (WindowData*) window->self.get();
|
59
|
+
}
|
60
|
+
|
61
|
+
static const WindowData*
|
62
|
+
get_data (const Window* window)
|
63
|
+
{
|
64
|
+
return get_data(const_cast<Window*>(window));
|
65
|
+
}
|
88
66
|
|
89
67
|
static bool
|
90
68
|
window_has_wndproc (HWND hwnd)
|
@@ -113,88 +91,270 @@ namespace Reflex
|
|
113
91
|
static Window*
|
114
92
|
get_window_from_hwnd (HWND hwnd)
|
115
93
|
{
|
116
|
-
WindowData* data = NULL;
|
117
94
|
if (window_has_wndproc(hwnd))
|
118
|
-
|
95
|
+
return (Window*) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
119
96
|
else
|
120
|
-
|
121
|
-
|
122
|
-
return data ? (*data)->this_ : NULL;
|
97
|
+
return (Window*) GetProp(hwnd, USERDATA_PROP);
|
123
98
|
}
|
124
99
|
|
125
|
-
static
|
100
|
+
static void
|
126
101
|
setup_window (Window* win, HWND hwnd)
|
127
102
|
{
|
128
|
-
if (
|
103
|
+
if (*win)
|
104
|
+
Xot::invalid_state_error(__FILE__, __LINE__);
|
129
105
|
|
130
|
-
WindowData*
|
106
|
+
WindowData* self = get_data(win);
|
131
107
|
|
132
|
-
bool ret = false;
|
133
108
|
if (window_has_wndproc(hwnd))
|
134
109
|
{
|
135
110
|
SetLastError(0);
|
136
|
-
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)
|
137
|
-
|
111
|
+
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) win);
|
112
|
+
if (GetLastError() != 0)
|
113
|
+
system_error(__FILE__, __LINE__);
|
138
114
|
}
|
139
115
|
else
|
140
|
-
|
116
|
+
{
|
117
|
+
if (!SetProp(hwnd, USERDATA_PROP, (HANDLE) win))
|
118
|
+
system_error(__FILE__, __LINE__);
|
119
|
+
}
|
141
120
|
|
142
|
-
|
121
|
+
self->hwnd = hwnd;
|
122
|
+
self->context.init(hwnd);
|
123
|
+
win->retain();
|
124
|
+
}
|
125
|
+
|
126
|
+
static void
|
127
|
+
cleanup_window (Window* win)
|
128
|
+
{
|
129
|
+
if (!*win)
|
130
|
+
Xot::invalid_state_error(__FILE__, __LINE__);
|
131
|
+
|
132
|
+
WindowData* self = get_data(win);
|
133
|
+
|
134
|
+
if (window_has_wndproc(self->hwnd))
|
143
135
|
{
|
144
|
-
|
145
|
-
|
136
|
+
SetLastError(0);
|
137
|
+
SetWindowLongPtr(self->hwnd, GWLP_USERDATA, 0);
|
138
|
+
if (GetLastError() != 0)
|
139
|
+
system_error(__FILE__, __LINE__);
|
146
140
|
}
|
147
141
|
else
|
148
|
-
|
142
|
+
{
|
143
|
+
if (!RemoveProp(self->hwnd, USERDATA_PROP))
|
144
|
+
system_error(__FILE__, __LINE__);
|
145
|
+
}
|
149
146
|
|
150
|
-
|
147
|
+
if (self->context.is_active())
|
148
|
+
Rays::activate_offscreen_context();
|
149
|
+
|
150
|
+
self->context.fin();
|
151
|
+
self->hwnd = NULL;
|
152
|
+
win->release();
|
151
153
|
}
|
152
154
|
|
155
|
+
static void
|
156
|
+
update (Window* win)
|
157
|
+
{
|
158
|
+
WindowData* self = get_data(win);
|
159
|
+
|
160
|
+
double now = Xot::time();
|
161
|
+
Reflex::UpdateEvent e(now, now - self->prev_time_update);
|
162
|
+
self->prev_time_update = now;
|
163
|
+
|
164
|
+
win->on_update(&e);
|
165
|
+
if (!e.is_blocked())
|
166
|
+
Reflex::View_update_tree(win->root(), e);
|
167
|
+
|
168
|
+
if (self->redraw)
|
169
|
+
{
|
170
|
+
#if 1
|
171
|
+
InvalidateRect(self->hwnd, NULL, FALSE);
|
172
|
+
#else
|
173
|
+
RedrawWindow(
|
174
|
+
self->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | EDW_ALLCHILDREN);
|
175
|
+
#endif
|
176
|
+
|
177
|
+
self->redraw = false;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
static void
|
182
|
+
draw (Window* win)
|
183
|
+
{
|
184
|
+
WindowData* self = get_data(win);
|
185
|
+
|
186
|
+
//update_pixel_density(win);
|
187
|
+
|
188
|
+
//if (update_count == 0)
|
189
|
+
//update(win);
|
190
|
+
|
191
|
+
double now = Xot::time();
|
192
|
+
double dt = now - self->prev_time_draw;
|
193
|
+
double fps = 1. / dt;
|
194
|
+
|
195
|
+
fps = self->prev_fps * 0.9 + fps * 0.1;// LPF
|
196
|
+
|
197
|
+
self->prev_time_draw = now;
|
198
|
+
self->prev_fps = fps;
|
199
|
+
|
200
|
+
Reflex::DrawEvent e(dt, fps);
|
201
|
+
Window_call_draw_event(win, &e);
|
202
|
+
}
|
203
|
+
|
204
|
+
static void
|
205
|
+
frame_changed (Window* win)
|
206
|
+
{
|
207
|
+
Rays::Bounds b = win->frame();
|
208
|
+
Rays::Point dpos = b.position() - win->self->prev_position;
|
209
|
+
Rays::Point dsize = b.size() - win->self->prev_size;
|
210
|
+
win->self->prev_position = b.position();
|
211
|
+
win->self->prev_size = b.size();
|
212
|
+
|
213
|
+
if (dpos == 0 && dsize == 0) return;
|
214
|
+
|
215
|
+
Reflex::FrameEvent e(b, dpos.x, dpos.y, 0, dsize.x, dsize.y, 0);
|
216
|
+
if (dpos != 0) win->on_move(&e);
|
217
|
+
if (dsize != 0)
|
218
|
+
{
|
219
|
+
Rays::Bounds b = win->frame();
|
220
|
+
b.move_to(0, 0);
|
221
|
+
|
222
|
+
if (win->painter())
|
223
|
+
win->painter()->canvas(b, win->painter()->pixel_density());
|
224
|
+
|
225
|
+
if (win->root())
|
226
|
+
View_set_frame(win->root(), b);
|
227
|
+
|
228
|
+
win->on_resize(&e);
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
static void
|
233
|
+
key_down (Window* win, UINT msg, WPARAM wp, LPARAM lp)
|
234
|
+
{
|
235
|
+
assert(*win);
|
236
|
+
|
237
|
+
WindowData* self = get_data(win);
|
238
|
+
|
239
|
+
MSG wmchar;
|
240
|
+
UINT filter = msg == WM_SYSKEYDOWN ? WM_SYSCHAR : WM_CHAR;
|
241
|
+
BOOL peeked = PeekMessage(&wmchar, self->hwnd, filter, filter, PM_NOREMOVE);
|
242
|
+
|
243
|
+
String chars;
|
244
|
+
if (peeked) chars += (char) wmchar.wParam;
|
245
|
+
|
246
|
+
NativeKeyEvent e(msg, wp, lp, chars);
|
247
|
+
|
248
|
+
self->pressing_keys.insert_or_assign(e.code(), chars);
|
249
|
+
#if 0
|
250
|
+
for (auto kv : self->pressing_keys)
|
251
|
+
doutln("0x%x : %s", kv.first, (const char*) kv.second);
|
252
|
+
#endif
|
253
|
+
|
254
|
+
Window_call_key_event(win, &e);
|
255
|
+
}
|
256
|
+
|
257
|
+
static void
|
258
|
+
key_up (Window* win, UINT msg, WPARAM wp, LPARAM lp)
|
259
|
+
{
|
260
|
+
assert(*win);
|
261
|
+
|
262
|
+
WindowData* self = get_data(win);
|
263
|
+
|
264
|
+
NativeKeyEvent e(msg, wp, lp);
|
265
|
+
|
266
|
+
auto it = self->pressing_keys.find(e.code());
|
267
|
+
if (it != self->pressing_keys.end())
|
268
|
+
KeyEvent_set_chars(&e, it->second);
|
269
|
+
|
270
|
+
Window_call_key_event(win, &e);
|
271
|
+
|
272
|
+
if (it != self->pressing_keys.end()) self->pressing_keys.erase(it);
|
273
|
+
}
|
274
|
+
|
275
|
+
#ifndef MOUSEEVENTF_FROMTOUCH
|
276
|
+
#define MOUSEEVENTF_FROMTOUCH 0xff515700
|
277
|
+
#endif
|
278
|
+
|
153
279
|
static bool
|
154
|
-
|
280
|
+
is_from_touch_event ()
|
155
281
|
{
|
156
|
-
|
282
|
+
return (GetMessageExtraInfo() & 0xffffff00) == MOUSEEVENTF_FROMTOUCH;
|
283
|
+
}
|
157
284
|
|
158
|
-
|
159
|
-
|
285
|
+
static void
|
286
|
+
mouse (Window* win, UINT msg, WPARAM wp, LPARAM lp)
|
287
|
+
{
|
288
|
+
if (is_from_touch_event()) return;
|
160
289
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
else
|
165
|
-
data = (WindowData*) GetProp(hwnd, USERDATA_PROP);
|
290
|
+
NativePointerEvent e(msg, wp, lp);
|
291
|
+
Window_call_pointer_event(win, &e);
|
292
|
+
}
|
166
293
|
|
167
|
-
|
168
|
-
|
294
|
+
static void
|
295
|
+
mouse_wheel (Window* win, UINT msg, WPARAM wp, LPARAM lp)
|
296
|
+
{
|
297
|
+
assert(msg == WM_MOUSEWHEEL || msg == WM_MOUSEHWHEEL);
|
298
|
+
|
299
|
+
WindowData* self = get_data(win);
|
169
300
|
|
170
|
-
|
171
|
-
if (
|
301
|
+
WPARAM wp_x = 0, wp_y = 0;
|
302
|
+
if (msg == WM_MOUSEWHEEL)
|
172
303
|
{
|
173
|
-
|
174
|
-
|
175
|
-
|
304
|
+
wp_y = wp;
|
305
|
+
MSG m;
|
306
|
+
if (PeekMessage(&m, self->hwnd, WM_MOUSEHWHEEL, WM_MOUSEHWHEEL, PM_REMOVE))
|
307
|
+
wp_x = m.wParam;
|
176
308
|
}
|
177
309
|
else
|
178
|
-
ret = RemoveProp(hwnd, USERDATA_PROP) != NULL;
|
179
|
-
|
180
|
-
if (ret)
|
181
310
|
{
|
182
|
-
|
183
|
-
|
184
|
-
|
311
|
+
wp_x = wp;
|
312
|
+
MSG m;
|
313
|
+
if (PeekMessage(&m, self->hwnd, WM_MOUSEWHEEL, WM_MOUSEWHEEL, PM_REMOVE))
|
314
|
+
wp_y = m.wParam;
|
185
315
|
}
|
186
316
|
|
187
|
-
|
317
|
+
NativeWheelEvent e(wp_x, wp_y, lp);
|
318
|
+
Window_call_wheel_event(win, &e);
|
319
|
+
}
|
320
|
+
|
321
|
+
static void
|
322
|
+
touch (Window* win, UINT msg, WPARAM wp, LPARAM lp)
|
323
|
+
{
|
324
|
+
WindowData* self = get_data(win);
|
325
|
+
|
326
|
+
size_t size = LOWORD(wp);
|
327
|
+
if (size <= 0) return;
|
328
|
+
|
329
|
+
HTOUCHINPUT handle = (HTOUCHINPUT) lp;
|
330
|
+
std::unique_ptr<TOUCHINPUT[]> touches(new TOUCHINPUT[size]);
|
331
|
+
|
332
|
+
if (!GetTouchInputInfo(handle, size, &touches[0], sizeof(TOUCHINPUT)))
|
333
|
+
return;
|
334
|
+
|
335
|
+
NativePointerEvent e(self->hwnd, &touches[0], size);
|
336
|
+
Window_call_pointer_event(win, &e);
|
337
|
+
|
338
|
+
CloseTouchInputHandle(handle);
|
188
339
|
}
|
189
340
|
|
190
341
|
static LRESULT CALLBACK
|
191
342
|
window_proc (Window* win, HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
192
343
|
{
|
193
|
-
if (!win || !*win ||
|
344
|
+
if (!win || !*win || hwnd != get_data(win)->hwnd)
|
194
345
|
return DefWindowProc(hwnd, msg, wp, lp);
|
195
346
|
|
347
|
+
WindowData* self = get_data(win);
|
348
|
+
|
196
349
|
switch (msg)
|
197
350
|
{
|
351
|
+
case WM_ACTIVATE:
|
352
|
+
{
|
353
|
+
if ((wp & 0xFFFF) == WA_INACTIVE)
|
354
|
+
self->pressing_keys.clear();
|
355
|
+
break;
|
356
|
+
}
|
357
|
+
|
198
358
|
case WM_CLOSE:
|
199
359
|
{
|
200
360
|
win->close();
|
@@ -203,45 +363,82 @@ namespace Reflex
|
|
203
363
|
|
204
364
|
case WM_PAINT:
|
205
365
|
{
|
366
|
+
self->context.make_current();
|
367
|
+
|
206
368
|
PAINTSTRUCT ps;
|
207
369
|
BeginPaint(hwnd, &ps);
|
208
370
|
|
209
|
-
|
210
|
-
|
211
|
-
win->draw();
|
212
|
-
win->self->opengl.swap_buffers();
|
213
|
-
}
|
371
|
+
draw(win);
|
372
|
+
self->context.swap_buffers();
|
214
373
|
|
215
374
|
EndPaint(hwnd, &ps);
|
216
375
|
return 0;
|
217
376
|
}
|
218
377
|
|
378
|
+
case WM_ERASEBKGND:
|
379
|
+
{
|
380
|
+
// do nothing.
|
381
|
+
return 0;
|
382
|
+
}
|
383
|
+
|
219
384
|
case WM_MOVE:
|
220
385
|
{
|
221
|
-
|
222
|
-
win->get_bounds(&x, &y);
|
223
|
-
win->moved(x, y);
|
386
|
+
frame_changed(win);
|
224
387
|
break;
|
225
388
|
}
|
226
389
|
|
227
390
|
case WM_SIZE:
|
228
391
|
{
|
229
|
-
|
230
|
-
win->get_bounds(NULL, NULL, &w, &h);
|
231
|
-
win->resized(w, h);
|
392
|
+
frame_changed(win);
|
232
393
|
break;
|
233
394
|
}
|
234
395
|
|
235
|
-
case
|
396
|
+
case WM_KEYDOWN:
|
397
|
+
case WM_SYSKEYDOWN:
|
236
398
|
{
|
237
|
-
|
238
|
-
|
399
|
+
key_down(win, msg, wp, lp);
|
400
|
+
break;
|
401
|
+
}
|
402
|
+
|
403
|
+
case WM_KEYUP:
|
404
|
+
case WM_SYSKEYUP:
|
405
|
+
{
|
406
|
+
key_up(win, msg, wp, lp);
|
407
|
+
break;
|
408
|
+
}
|
409
|
+
|
410
|
+
case WM_LBUTTONDOWN:
|
411
|
+
case WM_RBUTTONDOWN:
|
412
|
+
case WM_MBUTTONDOWN:
|
413
|
+
case WM_LBUTTONDBLCLK:
|
414
|
+
case WM_RBUTTONDBLCLK:
|
415
|
+
case WM_MBUTTONDBLCLK:
|
416
|
+
case WM_LBUTTONUP:
|
417
|
+
case WM_RBUTTONUP:
|
418
|
+
case WM_MBUTTONUP:
|
419
|
+
case WM_MOUSEMOVE:
|
420
|
+
{
|
421
|
+
mouse(win, msg, wp, lp);
|
422
|
+
break;
|
423
|
+
}
|
424
|
+
|
425
|
+
case WM_MOUSEWHEEL:
|
426
|
+
case WM_MOUSEHWHEEL:
|
427
|
+
{
|
428
|
+
mouse_wheel(win, msg, wp, lp);
|
429
|
+
break;
|
430
|
+
}
|
431
|
+
|
432
|
+
case WM_TOUCH:
|
433
|
+
{
|
434
|
+
touch(win, msg, wp, lp);
|
435
|
+
break;
|
239
436
|
}
|
240
437
|
|
241
438
|
case WM_TIMER:
|
242
439
|
{
|
243
440
|
if (wp == UPDATE_TIMER_ID)
|
244
|
-
|
441
|
+
update(win);
|
245
442
|
return 0;
|
246
443
|
}
|
247
444
|
|
@@ -283,17 +480,17 @@ namespace Reflex
|
|
283
480
|
cleanup_window(win);
|
284
481
|
|
285
482
|
if (--window_total == 0)
|
286
|
-
Reflex::quit();
|
483
|
+
Reflex::app()->quit();
|
287
484
|
}
|
288
485
|
|
289
486
|
return ret;
|
290
487
|
}
|
291
488
|
|
292
|
-
static
|
489
|
+
static void
|
293
490
|
register_windowclass ()
|
294
491
|
{
|
295
492
|
static bool registered = false;
|
296
|
-
if (registered) return
|
493
|
+
if (registered) return;
|
297
494
|
|
298
495
|
WNDCLASSEX wc;
|
299
496
|
memset(&wc, 0, sizeof(wc));
|
@@ -301,7 +498,7 @@ namespace Reflex
|
|
301
498
|
wc.cbSize = sizeof(wc);
|
302
499
|
wc.lpszClassName = WINDOWCLASS;
|
303
500
|
wc.lpfnWndProc = (WNDPROC) wndproc;
|
304
|
-
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
501
|
+
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
|
305
502
|
wc.hInstance = GetModuleHandle(NULL);
|
306
503
|
//wc.hIcon = LoadIcon(wc.hInstance, IDI_APP_LARGE);
|
307
504
|
//wc.hIconSm = LoadIcon(wc.hInstance, IDI_APP_SMALL);
|
@@ -311,130 +508,135 @@ namespace Reflex
|
|
311
508
|
wc.cbWndExtra = sizeof(Window*);
|
312
509
|
|
313
510
|
if (!RegisterClassEx(&wc))
|
314
|
-
|
511
|
+
system_error(__FILE__, __LINE__);
|
315
512
|
|
316
|
-
|
513
|
+
registered = true;
|
317
514
|
}
|
318
515
|
|
319
|
-
static
|
516
|
+
static void
|
320
517
|
create_window (Window* win)
|
321
518
|
{
|
322
|
-
if (
|
519
|
+
if (*win)
|
520
|
+
invalid_state_error(__FILE__, __LINE__);
|
323
521
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
CreateWindowEx(
|
522
|
+
register_windowclass();
|
523
|
+
HWND hwnd = CreateWindowEx(
|
328
524
|
0, WINDOWCLASS, "",
|
329
525
|
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
330
526
|
0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), win);
|
331
|
-
|
332
|
-
|
527
|
+
if (!hwnd)
|
528
|
+
system_error(__FILE__, __LINE__);
|
333
529
|
|
530
|
+
if (!*win)
|
531
|
+
invalid_state_error(__FILE__, __LINE__);
|
334
532
|
|
335
|
-
|
336
|
-
|
337
|
-
|
533
|
+
if (!RegisterTouchWindow(hwnd, 0))
|
534
|
+
system_error(__FILE__, __LINE__);
|
535
|
+
}
|
338
536
|
|
339
|
-
create_window(this);
|
340
537
|
|
341
|
-
|
538
|
+
Window::Data*
|
539
|
+
Window_create_data ()
|
540
|
+
{
|
541
|
+
return new WindowData();
|
342
542
|
}
|
343
543
|
|
344
|
-
|
544
|
+
uint
|
545
|
+
Window_default_flags ()
|
345
546
|
{
|
346
|
-
|
547
|
+
return
|
548
|
+
Window::FLAG_CLOSABLE |
|
549
|
+
Window::FLAG_RESIZABLE |
|
550
|
+
Window::FLAG_MINIMIZABLE;
|
551
|
+
}
|
347
552
|
|
348
|
-
|
553
|
+
void
|
554
|
+
Window_initialize (Window* window)
|
555
|
+
{
|
556
|
+
create_window(window);
|
349
557
|
}
|
350
558
|
|
351
|
-
static
|
559
|
+
static void
|
352
560
|
start_timer (HWND hwnd, UINT id, UINT interval)
|
353
561
|
{
|
354
|
-
if (!hwnd)
|
562
|
+
if (!hwnd)
|
563
|
+
argument_error(__FILE__, __LINE__);
|
355
564
|
|
356
|
-
|
565
|
+
if (!SetTimer(hwnd, id, interval, NULL))
|
566
|
+
system_error(__FILE__, __LINE__);
|
357
567
|
}
|
358
568
|
|
359
|
-
static
|
569
|
+
static void
|
360
570
|
stop_timer (HWND hwnd, UINT id)
|
361
571
|
{
|
362
|
-
if (!hwnd
|
572
|
+
if (!hwnd)
|
573
|
+
argument_error(__FILE__, __LINE__);
|
574
|
+
|
575
|
+
if (id == 0) return;
|
363
576
|
|
364
|
-
|
577
|
+
if (!KillTimer(hwnd, id))
|
578
|
+
system_error(__FILE__, __LINE__);
|
365
579
|
}
|
366
580
|
|
367
|
-
|
368
|
-
Window
|
581
|
+
void
|
582
|
+
Window_show (Window* window)
|
369
583
|
{
|
370
|
-
if (!*
|
584
|
+
if (!*window)
|
585
|
+
invalid_state_error(__FILE__, __LINE__);
|
371
586
|
|
372
|
-
|
587
|
+
WindowData* self = get_data(window);
|
373
588
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
if (!UpdateWindow(self->hwnd))
|
379
|
-
return false;
|
589
|
+
SetWindowPos(
|
590
|
+
self->hwnd, HWND_TOP, 0, 0, 0, 0,
|
591
|
+
SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
|
592
|
+
UpdateWindow(self->hwnd);
|
380
593
|
|
381
594
|
start_timer(self->hwnd, UPDATE_TIMER_ID, 1000 / 60);
|
382
|
-
return true;
|
383
595
|
}
|
384
596
|
|
385
|
-
|
386
|
-
Window
|
597
|
+
void
|
598
|
+
Window_hide (Window* window)
|
387
599
|
{
|
388
|
-
if (!*
|
600
|
+
if (!*window)
|
601
|
+
invalid_state_error(__FILE__, __LINE__);
|
389
602
|
|
390
|
-
|
603
|
+
WindowData* self = get_data(window);
|
391
604
|
|
392
|
-
|
393
|
-
|
394
|
-
|
605
|
+
SetWindowPos(
|
606
|
+
self->hwnd, NULL, 0, 0, 0, 0,
|
607
|
+
SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE);
|
395
608
|
|
396
609
|
stop_timer(self->hwnd, UPDATE_TIMER_ID);
|
397
|
-
return true;
|
398
610
|
}
|
399
611
|
|
400
|
-
|
401
|
-
Window
|
612
|
+
void
|
613
|
+
Window_close (Window* window)
|
402
614
|
{
|
403
|
-
if (
|
404
|
-
|
615
|
+
if (!*window)
|
616
|
+
invalid_state_error(__FILE__, __LINE__);
|
405
617
|
|
406
|
-
|
618
|
+
if (!DestroyWindow(get_data(window)->hwnd))
|
619
|
+
system_error(__FILE__, __LINE__);
|
407
620
|
}
|
408
621
|
|
409
|
-
|
410
|
-
Window
|
622
|
+
void
|
623
|
+
Window_set_title (Window* window, const char* title)
|
411
624
|
{
|
412
|
-
if (
|
413
|
-
|
414
|
-
#if 1
|
415
|
-
self->redraw = true;
|
416
|
-
return true;
|
417
|
-
#elif 1
|
418
|
-
InvalidateRect(self->hwnd, NULL, FALSE);
|
419
|
-
return true;
|
420
|
-
#else
|
421
|
-
return FALSE != RedrawWindow(
|
422
|
-
self->hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | EDW_ALLCHILDREN);
|
423
|
-
#endif
|
424
|
-
}
|
625
|
+
if (!title)
|
626
|
+
argument_error(__FILE__, __LINE__);
|
425
627
|
|
426
|
-
|
427
|
-
Window::set_title (const char* title)
|
428
|
-
{
|
429
|
-
if (!*this || !title) return false;
|
628
|
+
if (!*window) return;
|
430
629
|
|
431
|
-
|
630
|
+
if (!SetWindowText(get_data(window)->hwnd, title))
|
631
|
+
system_error(__FILE__, __LINE__);
|
432
632
|
}
|
433
633
|
|
434
634
|
const char*
|
435
|
-
Window
|
635
|
+
Window_get_title (const Window& window)
|
436
636
|
{
|
437
|
-
if (
|
637
|
+
if (!window) return "";
|
638
|
+
|
639
|
+
const WindowData* self = get_data(&window);
|
438
640
|
|
439
641
|
int size = GetWindowTextLength(self->hwnd);
|
440
642
|
if (size <= 0) return "";
|
@@ -447,58 +649,51 @@ namespace Reflex
|
|
447
649
|
return self->title_tmp.c_str();
|
448
650
|
}
|
449
651
|
|
450
|
-
static
|
652
|
+
static void
|
451
653
|
get_window_bounds (
|
452
654
|
HWND hwnd, coord* x, coord* y, coord* width, coord* height,
|
453
655
|
coord* nonclient_width = NULL, coord* nonclient_height = NULL)
|
454
656
|
{
|
455
|
-
if (
|
456
|
-
|
457
|
-
(!x && !y && !width && !height) ||
|
458
|
-
!!nonclient_width != !!nonclient_height)
|
459
|
-
{
|
460
|
-
return false;
|
461
|
-
}
|
657
|
+
if (!x && !y && !width && !height && !nonclient_width && !nonclient_height)
|
658
|
+
argument_error(__FILE__, __LINE__);
|
462
659
|
|
463
|
-
RECT window
|
464
|
-
if (
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
660
|
+
RECT window;
|
661
|
+
if (!GetWindowRect(hwnd, &window))
|
662
|
+
system_error(__FILE__, __LINE__);
|
663
|
+
|
664
|
+
RECT client;
|
665
|
+
if (!GetClientRect(hwnd, &client))
|
666
|
+
system_error(__FILE__, __LINE__);
|
470
667
|
|
471
668
|
if (x) *x = window.left;
|
472
669
|
if (y) *y = window.top;
|
473
670
|
if (width) *width = client.right - client.left;
|
474
671
|
if (height) *height = client.bottom - client.top;
|
475
672
|
|
476
|
-
if (nonclient_width
|
673
|
+
if (nonclient_width)
|
477
674
|
{
|
478
675
|
coord ww = window.right - window.left;
|
479
|
-
coord wh = window.bottom - window.top;
|
480
676
|
coord cw = client.right - client.left;
|
481
|
-
coord ch = client.bottom - client.top;
|
482
|
-
|
483
677
|
*nonclient_width = ww - cw;
|
678
|
+
}
|
679
|
+
if (nonclient_height)
|
680
|
+
{
|
681
|
+
coord wh = window.bottom - window.top;
|
682
|
+
coord ch = client.bottom - client.top;
|
484
683
|
*nonclient_height = wh - ch;
|
485
684
|
}
|
486
|
-
|
487
|
-
return true;
|
488
685
|
}
|
489
686
|
|
490
|
-
|
491
|
-
Window
|
687
|
+
void
|
688
|
+
Window_set_frame (Window* window, coord x, coord y, coord width, coord height)
|
492
689
|
{
|
493
|
-
if (!*
|
690
|
+
if (!*window) return;
|
691
|
+
|
692
|
+
WindowData* self = get_data(window);
|
494
693
|
|
495
694
|
coord xx, yy, ww, hh, nonclient_w, nonclient_h;
|
496
|
-
|
497
|
-
|
498
|
-
self->hwnd, &xx, &yy, &ww, &hh, &nonclient_w, &nonclient_h))
|
499
|
-
{
|
500
|
-
return false;
|
501
|
-
}
|
695
|
+
get_window_bounds(
|
696
|
+
self->hwnd, &xx, &yy, &ww, &hh, &nonclient_w, &nonclient_h);
|
502
697
|
|
503
698
|
width += nonclient_w;
|
504
699
|
height += nonclient_h;
|
@@ -507,42 +702,52 @@ namespace Reflex
|
|
507
702
|
if (x == xx && y == yy) flags |= SWP_NOMOVE;
|
508
703
|
if (width == ww && height == hh) flags |= SWP_NOSIZE;
|
509
704
|
|
510
|
-
if (flags == (SWP_NOMOVE | SWP_NOSIZE))
|
705
|
+
if (flags == (SWP_NOMOVE | SWP_NOSIZE))
|
706
|
+
return;
|
511
707
|
|
512
|
-
|
708
|
+
if (!SetWindowPos(
|
513
709
|
self->hwnd, NULL, (int) x, (int) y, (int) width, (int) height,
|
514
|
-
flags | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER)
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
Window::get_bounds (coord* x, coord* y, coord* width, coord* height)
|
519
|
-
{
|
520
|
-
return *this && get_window_bounds(self->hwnd, x, y, width, height);
|
710
|
+
flags | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER))
|
711
|
+
{
|
712
|
+
system_error(__FILE__, __LINE__);
|
713
|
+
}
|
521
714
|
}
|
522
715
|
|
523
|
-
|
524
|
-
Window
|
716
|
+
Bounds
|
717
|
+
Window_get_frame (const Window& window)
|
525
718
|
{
|
526
|
-
if (
|
719
|
+
if (!window)
|
720
|
+
invalid_state_error(__FILE__, __LINE__);
|
527
721
|
|
528
|
-
|
722
|
+
coord x, y, w, h;
|
723
|
+
get_window_bounds(get_data(&window)->hwnd, &x, &y, &w, &h);
|
724
|
+
return Bounds(x, y, w, h);
|
529
725
|
}
|
530
726
|
|
531
|
-
|
532
|
-
Window
|
727
|
+
Screen
|
728
|
+
Window_get_screen (const Window& window)
|
533
729
|
{
|
534
|
-
|
730
|
+
Screen s;
|
731
|
+
HMONITOR hmonitor =
|
732
|
+
MonitorFromWindow(get_data(&window)->hwnd, MONITOR_DEFAULTTONULL);
|
733
|
+
if (hmonitor) Screen_initialize(&s, hmonitor);
|
734
|
+
return s;
|
535
735
|
}
|
536
736
|
|
537
|
-
|
538
|
-
Window
|
737
|
+
void
|
738
|
+
Window_set_flags (Window* window, uint flags)
|
539
739
|
{
|
540
|
-
|
740
|
+
if (Xot::has_flag(flags, Window::FLAG_PORTRAIT))
|
741
|
+
argument_error(__FILE__, __LINE__, "FLAG_PORTRAIT is not supported");
|
742
|
+
|
743
|
+
if (Xot::has_flag(flags, Window::FLAG_LANDSCAPE))
|
744
|
+
argument_error(__FILE__, __LINE__, "FLAG_LANDSCAPE is not supported");
|
541
745
|
}
|
542
746
|
|
543
|
-
|
747
|
+
float
|
748
|
+
Window_get_pixel_density (const Window& window)
|
544
749
|
{
|
545
|
-
return
|
750
|
+
return 1;
|
546
751
|
}
|
547
752
|
|
548
753
|
|