reflexion 0.5.3 → 0.7.0
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 +56 -7
- data/.doc/ext/reflex/capture_event.cpp +1 -1
- data/.doc/ext/reflex/chase_constraint.cpp +84 -0
- data/.doc/ext/reflex/clipboard.cpp +65 -0
- data/.doc/ext/reflex/color_event.cpp +76 -0
- data/.doc/ext/reflex/color_picker.cpp +113 -0
- data/.doc/ext/reflex/constraint.cpp +135 -0
- data/.doc/ext/reflex/contact_event.cpp +1 -1
- data/.doc/ext/reflex/control_change_event.cpp +1 -1
- data/.doc/ext/reflex/device.cpp +1 -1
- data/.doc/ext/reflex/device_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/file_dialog.cpp +181 -0
- data/.doc/ext/reflex/file_event.cpp +103 -0
- 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/gamepad.cpp +48 -0
- data/.doc/ext/reflex/image_view.cpp +1 -1
- data/.doc/ext/reflex/key_event.cpp +1 -274
- data/.doc/ext/reflex/line_shape.cpp +1 -1
- data/.doc/ext/reflex/link_constraint.cpp +178 -0
- data/.doc/ext/reflex/menu.cpp +303 -0
- data/.doc/ext/reflex/midi.cpp +9 -2
- data/.doc/ext/reflex/midi_event.cpp +1 -1
- data/.doc/ext/reflex/motion_event.cpp +1 -1
- data/.doc/ext/reflex/native.cpp +40 -10
- data/.doc/ext/reflex/note_event.cpp +1 -1
- data/.doc/ext/reflex/pin.cpp +156 -0
- data/.doc/ext/reflex/pointer.cpp +3 -1
- data/.doc/ext/reflex/pointer_event.cpp +3 -3
- data/.doc/ext/reflex/polygon_shape.cpp +1 -1
- data/.doc/ext/reflex/rect_shape.cpp +1 -1
- data/.doc/ext/reflex/reflex.cpp +606 -237
- data/.doc/ext/reflex/screen.cpp +27 -1
- data/.doc/ext/reflex/scroll_event.cpp +1 -1
- data/.doc/ext/reflex/selector.cpp +5 -5
- data/.doc/ext/reflex/shape.cpp +1 -1
- data/.doc/ext/reflex/snap_constraint.cpp +125 -0
- data/.doc/ext/reflex/style.cpp +1 -1
- data/.doc/ext/reflex/style_length.cpp +4 -3
- data/.doc/ext/reflex/text_event.cpp +104 -0
- 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 +206 -79
- data/.doc/ext/reflex/wheel_constraint.cpp +142 -0
- data/.doc/ext/reflex/wheel_event.cpp +1 -1
- data/.doc/ext/reflex/window.cpp +282 -31
- data/.github/workflows/release-gem.yml +2 -40
- data/.github/workflows/tag.yml +5 -28
- data/.github/workflows/test.yml +1 -28
- data/ChangeLog.md +79 -0
- data/Gemfile.lock +13 -8
- data/README.md +1 -0
- data/Rakefile +13 -2
- data/Reflex.podspec +2 -2
- data/VERSION +1 -1
- data/ext/reflex/application.cpp +62 -7
- data/ext/reflex/capture_event.cpp +1 -1
- data/ext/reflex/chase_constraint.cpp +89 -0
- data/ext/reflex/clipboard.cpp +69 -0
- data/ext/reflex/color_event.cpp +80 -0
- data/ext/reflex/color_picker.cpp +121 -0
- data/ext/reflex/constraint.cpp +146 -0
- data/ext/reflex/contact_event.cpp +1 -1
- data/ext/reflex/control_change_event.cpp +1 -1
- data/ext/reflex/device.cpp +1 -1
- data/ext/reflex/device_event.cpp +1 -1
- 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 -2
- data/ext/reflex/file_dialog.cpp +194 -0
- data/ext/reflex/file_event.cpp +108 -0
- 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/gamepad.cpp +50 -0
- data/ext/reflex/image_view.cpp +1 -1
- data/ext/reflex/key_event.cpp +1 -275
- data/ext/reflex/line_shape.cpp +1 -1
- data/ext/reflex/link_constraint.cpp +194 -0
- data/ext/reflex/menu.cpp +331 -0
- data/ext/reflex/midi.cpp +11 -3
- data/ext/reflex/midi_event.cpp +1 -1
- data/ext/reflex/motion_event.cpp +1 -1
- data/ext/reflex/native.cpp +40 -10
- data/ext/reflex/note_event.cpp +1 -1
- data/ext/reflex/pin.cpp +165 -0
- data/ext/reflex/pointer.cpp +3 -1
- data/ext/reflex/pointer_event.cpp +3 -3
- data/ext/reflex/polygon_shape.cpp +1 -1
- data/ext/reflex/rect_shape.cpp +1 -1
- data/ext/reflex/reflex.cpp +608 -237
- data/ext/reflex/screen.cpp +31 -2
- data/ext/reflex/scroll_event.cpp +1 -1
- data/ext/reflex/selector.cpp +5 -5
- data/ext/reflex/selector.h +10 -10
- data/ext/reflex/shape.cpp +1 -1
- data/ext/reflex/snap_constraint.cpp +135 -0
- data/ext/reflex/style.cpp +1 -1
- data/ext/reflex/style_length.cpp +4 -3
- data/ext/reflex/text_event.cpp +111 -0
- 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 +236 -96
- data/ext/reflex/wheel_constraint.cpp +154 -0
- data/ext/reflex/wheel_event.cpp +1 -1
- data/ext/reflex/window.cpp +318 -40
- data/include/reflex/application.h +19 -0
- data/include/reflex/clipboard.h +53 -0
- data/include/reflex/color_picker.h +65 -0
- data/include/reflex/constraint.h +275 -0
- data/include/reflex/defs.h +204 -195
- data/include/reflex/event.h +180 -88
- data/include/reflex/file_dialog.h +73 -0
- data/include/reflex/gamepad.h +3 -0
- data/include/reflex/menu.h +120 -0
- data/include/reflex/midi.h +3 -0
- data/include/reflex/pin.h +68 -0
- data/include/reflex/pointer.h +4 -0
- data/include/reflex/reflex.h +2 -0
- data/include/reflex/ruby/application.h +6 -1
- data/include/reflex/ruby/clipboard.h +23 -0
- data/include/reflex/ruby/color_picker.h +89 -0
- data/include/reflex/ruby/constraint.h +94 -0
- data/include/reflex/ruby/event.h +62 -29
- data/include/reflex/ruby/file_dialog.h +89 -0
- data/include/reflex/ruby/gamepad.h +46 -0
- data/include/reflex/ruby/menu.h +103 -0
- data/include/reflex/ruby/pin.h +40 -0
- data/include/reflex/ruby/reflex.h +3 -0
- data/include/reflex/ruby/view.h +123 -39
- data/include/reflex/ruby/window.h +96 -19
- data/include/reflex/ruby.h +3 -0
- data/include/reflex/screen.h +11 -2
- data/include/reflex/view.h +66 -27
- data/include/reflex/window.h +57 -12
- data/include/reflex.h +8 -0
- data/lib/reflex/application.rb +5 -5
- data/lib/reflex/autoinit.rb +3 -1
- data/lib/reflex/button.rb +3 -3
- data/lib/reflex/chase_constraint.rb +15 -0
- data/lib/reflex/clipboard.rb +19 -0
- data/lib/reflex/color_event.rb +16 -0
- data/lib/reflex/color_picker.rb +45 -0
- data/lib/reflex/constraint.rb +29 -0
- data/lib/reflex/control_change_event.rb +17 -0
- data/lib/reflex/extension.rb +1 -1
- data/lib/reflex/file_dialog.rb +70 -0
- data/lib/reflex/file_event.rb +37 -0
- data/lib/reflex/helper.rb +79 -0
- data/lib/reflex/key_event.rb +14 -14
- data/lib/reflex/link_constraint.rb +31 -0
- data/lib/reflex/menu.rb +92 -0
- data/lib/reflex/model.rb +19 -19
- data/lib/reflex/note_event.rb +1 -1
- data/lib/reflex/pin.rb +39 -0
- data/lib/reflex/pointer.rb +30 -1
- data/lib/reflex/pointer_event.rb +13 -2
- data/lib/reflex/reflex.rb +5 -0
- data/lib/reflex/shape.rb +14 -14
- data/lib/reflex/snap_constraint.rb +28 -0
- data/lib/reflex/style.rb +16 -16
- data/lib/reflex/text_event.rb +40 -0
- data/lib/reflex/timer.rb +3 -3
- data/lib/reflex/view.rb +85 -18
- data/lib/reflex/wheel_constraint.rb +28 -0
- data/lib/reflex/wheel_event.rb +19 -1
- data/lib/reflex/window.rb +25 -13
- data/lib/reflex.rb +23 -8
- data/pod.rake +1 -1
- data/reflex.gemspec +4 -4
- data/samples/constraint.rb +152 -0
- data/samples/ime.rb +100 -0
- data/samples/ios/hello/hello.xcodeproj/project.pbxproj +236 -224
- data/samples/menu.rb +32 -0
- data/samples/model.rb +3 -3
- data/samples/test/alert.rb +93 -0
- data/samples/test/always_on.rb +76 -0
- data/samples/test/app_background.rb +51 -0
- data/samples/test/boundary.rb +75 -0
- data/samples/test/callback_exception.rb +101 -0
- data/samples/test/cancel.rb +53 -0
- data/samples/test/color_picker.rb +63 -0
- data/samples/test/file_dialog.rb +102 -0
- data/samples/window_style.rb +156 -0
- data/src/application.cpp +180 -20
- data/src/application.h +95 -5
- data/src/clipboard.cpp +81 -0
- data/src/color_picker.cpp +113 -0
- data/src/color_picker.h +36 -0
- data/src/constraint.cpp +1662 -0
- data/src/constraint.h +64 -0
- data/src/event.cpp +416 -252
- data/src/event.h +13 -2
- data/src/file_dialog.cpp +163 -0
- data/src/file_dialog.h +52 -0
- data/src/gamepad.cpp +42 -5
- data/src/gamepad.h +4 -0
- data/src/ios/app_delegate.mm +5 -3
- data/src/ios/application.mm +29 -0
- data/src/ios/clipboard.mm +44 -0
- data/src/ios/color_picker.mm +19 -0
- data/src/ios/event.h +6 -2
- data/src/ios/event.mm +31 -12
- data/src/ios/file_dialog.mm +21 -0
- data/src/ios/gamepad.mm +4 -4
- data/src/ios/menu.mm +41 -0
- data/src/ios/reflex.mm +8 -0
- data/src/ios/screen.mm +26 -0
- data/src/ios/view_controller.mm +47 -42
- data/src/ios/window.mm +44 -9
- data/src/menu.cpp +387 -0
- data/src/menu.h +81 -0
- data/src/midi.cpp +61 -31
- data/src/osx/app_delegate.h +4 -0
- data/src/osx/app_delegate.mm +168 -139
- data/src/osx/application.mm +103 -5
- data/src/osx/clipboard.mm +45 -0
- data/src/osx/color_picker.mm +112 -0
- data/src/osx/event.h +10 -0
- data/src/osx/event.mm +114 -30
- data/src/osx/file_dialog.mm +168 -0
- data/src/osx/gamepad.mm +2 -2
- data/src/osx/gamepad_hid.mm +1 -1
- data/src/osx/menu.h +25 -0
- data/src/osx/menu.mm +516 -0
- data/src/osx/native_window.h +16 -2
- data/src/osx/native_window.mm +141 -57
- data/src/osx/opengl_view.h +2 -1
- data/src/osx/opengl_view.mm +229 -37
- data/src/osx/reflex.mm +38 -0
- data/src/osx/screen.mm +36 -0
- data/src/osx/window.mm +117 -24
- data/src/pin.cpp +137 -0
- data/src/pointer.cpp +36 -16
- data/src/pointer.h +10 -0
- data/src/rays.h +46 -0
- data/src/sdl/application.cpp +73 -8
- data/src/sdl/clipboard.cpp +39 -0
- data/src/sdl/color_picker.cpp +18 -0
- data/src/sdl/event.cpp +44 -6
- data/src/sdl/event.h +18 -3
- data/src/sdl/file_dialog.cpp +20 -0
- data/src/sdl/gamepad.cpp +3 -7
- data/src/sdl/menu.cpp +40 -0
- data/src/sdl/reflex.cpp +20 -0
- data/src/sdl/screen.cpp +36 -0
- data/src/sdl/window.cpp +168 -37
- data/src/shape.cpp +15 -10
- data/src/view.cpp +583 -233
- data/src/view.h +22 -4
- data/src/vk.h +416 -0
- data/src/win32/application.cpp +167 -12
- data/src/win32/application.h +20 -0
- data/src/win32/clipboard.cpp +210 -0
- data/src/win32/color_picker.cpp +82 -0
- data/src/win32/event.cpp +123 -11
- data/src/win32/event.h +22 -3
- data/src/win32/file_dialog.cpp +226 -0
- data/src/win32/gamepad.cpp +9 -2
- data/src/win32/menu.cpp +490 -0
- data/src/win32/menu.h +35 -0
- data/src/win32/opengl.cpp +2 -9
- data/src/win32/reflex.cpp +44 -3
- data/src/win32/screen.cpp +164 -3
- data/src/win32/screen.h +8 -0
- data/src/win32/tray.cpp +191 -0
- data/src/win32/tray.h +22 -0
- data/src/win32/vk.cpp +11 -0
- data/src/win32/window.cpp +858 -135
- data/src/win32/window.h +9 -0
- data/src/window.cpp +929 -183
- data/src/window.h +77 -33
- data/src/world.cpp +86 -15
- data/src/world.h +9 -2
- data/test/helper.rb +24 -0
- data/test/test_application.rb +101 -1
- data/test/test_chase_constraint.rb +122 -0
- data/test/test_clipboard.rb +54 -0
- data/test/test_color_event.rb +36 -0
- data/test/test_color_picker.rb +62 -0
- data/test/test_constraint.rb +184 -0
- data/test/test_event.rb +1 -1
- data/test/test_file_dialog.rb +48 -0
- data/test/test_file_event.rb +43 -0
- data/test/test_has_text_preedit.rb +54 -0
- data/test/test_key_event.rb +23 -2
- data/test/test_link_constraint.rb +237 -0
- data/test/test_menu.rb +237 -0
- data/test/test_pin.rb +65 -0
- data/test/test_pointer.rb +50 -26
- data/test/test_pointer_event.rb +25 -10
- data/test/test_reflex.rb +36 -0
- data/test/test_screen.rb +24 -2
- data/test/test_snap_constraint.rb +140 -0
- data/test/test_text_event.rb +54 -0
- data/test/test_view.rb +152 -25
- data/test/test_wheel_constraint.rb +125 -0
- data/test/test_wheel_event.rb +24 -10
- data/test/test_window.rb +205 -43
- metadata +154 -10
- data/.github/workflows/utils.rb +0 -127
data/src/win32/menu.cpp
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
#include "menu.h"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#include <string>
|
|
5
|
+
#include <vector>
|
|
6
|
+
#include <xot/time.h>
|
|
7
|
+
#include "reflex/exception.h"
|
|
8
|
+
#include "reflex/event.h"
|
|
9
|
+
#include "reflex/view.h"
|
|
10
|
+
#include "../rays.h"
|
|
11
|
+
#include "window.h"
|
|
12
|
+
#include "screen.h"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
namespace Reflex
|
|
16
|
+
{
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
static UINT
|
|
20
|
+
next_menu_id ()
|
|
21
|
+
{
|
|
22
|
+
static UINT id = 100;
|
|
23
|
+
return id++;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static HMENU
|
|
27
|
+
create_hmenu (Menu* menu, bool menubar)
|
|
28
|
+
{
|
|
29
|
+
HMENU hmenu = menubar ? CreateMenu() : CreatePopupMenu();
|
|
30
|
+
if (!hmenu)
|
|
31
|
+
system_error(__FILE__, __LINE__);
|
|
32
|
+
|
|
33
|
+
MENUINFO mi = {sizeof(mi)};
|
|
34
|
+
mi.fMask = MIM_MENUDATA | MIM_STYLE;
|
|
35
|
+
mi.dwMenuData = (ULONG_PTR) menu;
|
|
36
|
+
mi.dwStyle = MNS_NOTIFYBYPOS;
|
|
37
|
+
SetMenuInfo(hmenu, &mi);
|
|
38
|
+
|
|
39
|
+
return hmenu;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static void
|
|
43
|
+
destroy_hmenu (HMENU hmenu)
|
|
44
|
+
{
|
|
45
|
+
if (!hmenu || !IsMenu(hmenu)) return;
|
|
46
|
+
|
|
47
|
+
while (GetMenuItemCount(hmenu) > 0)
|
|
48
|
+
RemoveMenu(hmenu, 0, MF_BYPOSITION);
|
|
49
|
+
|
|
50
|
+
DestroyMenu(hmenu);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
struct MenuData : public Menu::Data
|
|
55
|
+
{
|
|
56
|
+
|
|
57
|
+
UINT id = next_menu_id();
|
|
58
|
+
|
|
59
|
+
HMENU hparent = NULL;
|
|
60
|
+
|
|
61
|
+
HMENU hsubmenu = NULL;
|
|
62
|
+
|
|
63
|
+
bool menubar = false;
|
|
64
|
+
|
|
65
|
+
bool modified = false;
|
|
66
|
+
|
|
67
|
+
Image image;
|
|
68
|
+
|
|
69
|
+
std::shared_ptr<HBITMAP__> hbitmap;
|
|
70
|
+
|
|
71
|
+
virtual ~MenuData ()
|
|
72
|
+
{
|
|
73
|
+
destroy_hmenu(hsubmenu);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
HMENU get_hsubmenu (Menu* menu, bool menubar = false);
|
|
77
|
+
|
|
78
|
+
HBITMAP get_hbitmap (const Image& image)
|
|
79
|
+
{
|
|
80
|
+
if (image != this->image)
|
|
81
|
+
{
|
|
82
|
+
this->image = image;
|
|
83
|
+
if (image)
|
|
84
|
+
hbitmap.reset(Rays::Bitmap_get_hbitmap(image.bitmap()), DeleteObject);
|
|
85
|
+
else
|
|
86
|
+
hbitmap.reset();
|
|
87
|
+
}
|
|
88
|
+
return hbitmap.get();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
};// MenuData
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
static MenuData&
|
|
95
|
+
get_data (Menu* menu)
|
|
96
|
+
{
|
|
97
|
+
if (!menu)
|
|
98
|
+
argument_error(__FILE__, __LINE__);
|
|
99
|
+
|
|
100
|
+
return (MenuData&) *menu->self;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static Menu*
|
|
104
|
+
get_root (Menu* menu)
|
|
105
|
+
{
|
|
106
|
+
while (menu->parent()) menu = menu->parent();
|
|
107
|
+
return menu;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static void
|
|
111
|
+
set_modified (Menu* menu)
|
|
112
|
+
{
|
|
113
|
+
get_data(get_root(menu)).modified = true;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static Menu*
|
|
117
|
+
get_item_owner (HMENU hparent, uint index)
|
|
118
|
+
{
|
|
119
|
+
if (!hparent) return NULL;
|
|
120
|
+
|
|
121
|
+
MENUITEMINFOW mii = {sizeof(mii)};
|
|
122
|
+
mii.fMask = MIIM_DATA;
|
|
123
|
+
if (!GetMenuItemInfoW(hparent, index, TRUE, &mii))
|
|
124
|
+
return NULL;
|
|
125
|
+
|
|
126
|
+
return (Menu*) mii.dwItemData;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static Menu*
|
|
130
|
+
get_submenu_owner (HMENU hsubmenu)
|
|
131
|
+
{
|
|
132
|
+
if (!hsubmenu) return NULL;
|
|
133
|
+
|
|
134
|
+
MENUINFO mi = {sizeof(mi)};
|
|
135
|
+
mi.fMask = MIM_MENUDATA;
|
|
136
|
+
if (!GetMenuInfo(hsubmenu, &mi))
|
|
137
|
+
return NULL;
|
|
138
|
+
|
|
139
|
+
return (Menu*) mi.dwMenuData;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static void
|
|
143
|
+
insert_item (HMENU hparent, Menu* item, int index)
|
|
144
|
+
{
|
|
145
|
+
MenuData& self = get_data(item);
|
|
146
|
+
|
|
147
|
+
MENUITEMINFOW mii = {sizeof(mii)};
|
|
148
|
+
mii.fMask = MIIM_ID | MIIM_DATA | MIIM_FTYPE | MIIM_STRING;
|
|
149
|
+
mii.fType = MFT_STRING;
|
|
150
|
+
mii.wID = self.id;
|
|
151
|
+
mii.dwItemData = (ULONG_PTR) item;
|
|
152
|
+
mii.dwTypeData = (LPWSTR) L"";
|
|
153
|
+
|
|
154
|
+
if (!InsertMenuItemW(hparent, (UINT) index, TRUE, &mii))
|
|
155
|
+
system_error(__FILE__, __LINE__);
|
|
156
|
+
|
|
157
|
+
self.hparent = hparent;
|
|
158
|
+
|
|
159
|
+
Menu_update(item);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
Menu::Data*
|
|
163
|
+
Menu_create_data ()
|
|
164
|
+
{
|
|
165
|
+
return new MenuData();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
void
|
|
169
|
+
Menu_validate_shortcut_modifiers (uint modifiers)
|
|
170
|
+
{
|
|
171
|
+
static const uint SUPPORTED =
|
|
172
|
+
MOD_SHIFT | MOD_CONTROL | MOD_ALT | MOD_OPTION;
|
|
173
|
+
|
|
174
|
+
if (modifiers & ~SUPPORTED)
|
|
175
|
+
{
|
|
176
|
+
argument_error(
|
|
177
|
+
__FILE__, __LINE__,
|
|
178
|
+
"modifiers 0x%X can not be used for a shortcut on Windows.",
|
|
179
|
+
modifiers & ~SUPPORTED);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static String
|
|
184
|
+
get_shortcut_key_name (int key)
|
|
185
|
+
{
|
|
186
|
+
if (key < 0) return "";
|
|
187
|
+
|
|
188
|
+
UINT vsc = MapVirtualKeyW((UINT) key, MAPVK_VK_TO_VSC_EX);
|
|
189
|
+
if (vsc == 0) return "";
|
|
190
|
+
|
|
191
|
+
LONG lparam = (LONG) ((vsc & 0xff) << 16);
|
|
192
|
+
if (vsc & 0xff00) lparam |= 1 << 24;// extended key
|
|
193
|
+
|
|
194
|
+
wchar_t name[64] = {0};
|
|
195
|
+
int len = GetKeyNameTextW(lparam, name, (int) (sizeof(name) / sizeof(*name)));
|
|
196
|
+
if (len <= 0) return "";
|
|
197
|
+
|
|
198
|
+
return String(name, (size_t) len);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static String
|
|
202
|
+
make_item_string (const Menu* menu)
|
|
203
|
+
{
|
|
204
|
+
String str = menu->label();
|
|
205
|
+
String key = menu->empty() ? get_shortcut_key_name(menu->shortcut_key()) : "";
|
|
206
|
+
if (!key.empty())
|
|
207
|
+
{
|
|
208
|
+
str += '\t';
|
|
209
|
+
uint mods = menu->shortcut_modifiers();
|
|
210
|
+
if (mods & MOD_CONTROL) str += "Ctrl+";
|
|
211
|
+
if (mods & MOD_SHIFT) str += "Shift+";
|
|
212
|
+
if (mods & (MOD_ALT | MOD_OPTION)) str += "Alt+";
|
|
213
|
+
str += key;
|
|
214
|
+
}
|
|
215
|
+
return str;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
void
|
|
219
|
+
Menu_update (Menu* menu)
|
|
220
|
+
{
|
|
221
|
+
MenuData& self = get_data(menu);
|
|
222
|
+
|
|
223
|
+
if (!self.hparent) return;
|
|
224
|
+
|
|
225
|
+
MENUITEMINFOW mii = {sizeof(mii)};
|
|
226
|
+
mii.fMask =
|
|
227
|
+
MIIM_ID | MIIM_DATA | MIIM_FTYPE | MIIM_STATE | MIIM_BITMAP | MIIM_SUBMENU;
|
|
228
|
+
mii.wID = self.id;
|
|
229
|
+
mii.dwItemData = (ULONG_PTR) menu;
|
|
230
|
+
|
|
231
|
+
std::wstring label;
|
|
232
|
+
if (menu->is_separator())
|
|
233
|
+
mii.fType = MFT_SEPARATOR;
|
|
234
|
+
else
|
|
235
|
+
{
|
|
236
|
+
label = make_item_string(menu).to_wstr();
|
|
237
|
+
|
|
238
|
+
mii.fMask |= MIIM_STRING;
|
|
239
|
+
mii.fType = MFT_STRING;
|
|
240
|
+
mii.dwTypeData = (LPWSTR) label.c_str();
|
|
241
|
+
mii.fState =
|
|
242
|
+
(menu->is_enabled() ? MFS_ENABLED : MFS_GRAYED) |
|
|
243
|
+
(menu->is_checked() ? MFS_CHECKED : MFS_UNCHECKED);
|
|
244
|
+
mii.hbmpItem = self.get_hbitmap(menu->image());
|
|
245
|
+
mii.hSubMenu = menu->empty() ? NULL : self.hsubmenu;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
SetMenuItemInfoW(self.hparent, self.id, FALSE, &mii);
|
|
249
|
+
|
|
250
|
+
set_modified(menu);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
void
|
|
254
|
+
Menu_popup (Menu* menu, View* view, coord x, coord y)
|
|
255
|
+
{
|
|
256
|
+
Menu_cancel_active_pointers_for_popup(view);
|
|
257
|
+
|
|
258
|
+
MenuData& self = get_data(menu);
|
|
259
|
+
|
|
260
|
+
HMENU hmenu = self.get_hsubmenu(menu);
|
|
261
|
+
if (!hmenu)
|
|
262
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
263
|
+
|
|
264
|
+
HWND hwnd = NULL;
|
|
265
|
+
POINT pos = Screen_to_native_coord(x, y);
|
|
266
|
+
|
|
267
|
+
if (view)
|
|
268
|
+
{
|
|
269
|
+
Window* win = view->window();
|
|
270
|
+
if (!win)
|
|
271
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
272
|
+
|
|
273
|
+
hwnd = Window_get_hwnd(win);
|
|
274
|
+
if (!hwnd)
|
|
275
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
276
|
+
|
|
277
|
+
pos = Window_to_native_coord(*win, view->to_window(Point(x, y)));
|
|
278
|
+
ClientToScreen(hwnd, &pos);
|
|
279
|
+
}
|
|
280
|
+
else
|
|
281
|
+
hwnd = GetActiveWindow();
|
|
282
|
+
|
|
283
|
+
if (!hwnd) return;
|
|
284
|
+
|
|
285
|
+
Menu_track_popup(
|
|
286
|
+
hmenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, pos, hwnd);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
void
|
|
290
|
+
Menu_child_added (Menu* parent, Menu* child, int index)
|
|
291
|
+
{
|
|
292
|
+
MenuData& c = get_data(child);
|
|
293
|
+
|
|
294
|
+
if (c.hparent)
|
|
295
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
296
|
+
|
|
297
|
+
insert_item(get_data(parent).get_hsubmenu(parent), child, index);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
void
|
|
301
|
+
Menu_child_removed (Menu* parent, Menu* child)
|
|
302
|
+
{
|
|
303
|
+
MenuData& p = get_data(parent);
|
|
304
|
+
MenuData& c = get_data(child);
|
|
305
|
+
|
|
306
|
+
if (!p.hsubmenu)
|
|
307
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
308
|
+
if (c.hparent != p.hsubmenu)
|
|
309
|
+
invalid_state_error(__FILE__, __LINE__);
|
|
310
|
+
|
|
311
|
+
RemoveMenu(p.hsubmenu, c.id, MF_BYCOMMAND);
|
|
312
|
+
c.hparent = NULL;
|
|
313
|
+
|
|
314
|
+
set_modified(parent);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
void
|
|
319
|
+
Menu_track_popup (HMENU hmenu, UINT flags, POINT pos, HWND owner)
|
|
320
|
+
{
|
|
321
|
+
double start = Xot::time();
|
|
322
|
+
|
|
323
|
+
// TrackPopupMenu needs the owner window in the foreground
|
|
324
|
+
SetForegroundWindow(owner);
|
|
325
|
+
|
|
326
|
+
TrackPopupMenu(hmenu, flags, pos.x, pos.y, 0, owner, NULL);
|
|
327
|
+
|
|
328
|
+
// the documented workaround for the menu not closing
|
|
329
|
+
// on the first outside click
|
|
330
|
+
PostMessageW(owner, WM_NULL, 0, 0);
|
|
331
|
+
|
|
332
|
+
Window_skip_update_time_of_all(Xot::time() - start);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
HMENU
|
|
336
|
+
Menu_get_hmenu (Menu* menu, bool menubar)
|
|
337
|
+
{
|
|
338
|
+
return menu ? get_data(menu).get_hsubmenu(menu, menubar) : NULL;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
bool
|
|
342
|
+
Menu_is_modified (Menu* menu)
|
|
343
|
+
{
|
|
344
|
+
return menu && get_data(menu).modified;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
static void
|
|
348
|
+
collect_accels (std::vector<ACCEL>* accels, Menu* menu)
|
|
349
|
+
{
|
|
350
|
+
for (auto& child : *menu)
|
|
351
|
+
{
|
|
352
|
+
Menu* item = child.get();
|
|
353
|
+
if (!item) continue;
|
|
354
|
+
|
|
355
|
+
int key = item->shortcut_key();
|
|
356
|
+
if (key >= 0 && item->empty())
|
|
357
|
+
{
|
|
358
|
+
uint mods = item->shortcut_modifiers();
|
|
359
|
+
|
|
360
|
+
ACCEL accel = {0};
|
|
361
|
+
accel.key = (WORD) key;// KeyCode == VK
|
|
362
|
+
accel.cmd = (WORD) get_data(item).id;
|
|
363
|
+
accel.fVirt = (BYTE) (FVIRTKEY |
|
|
364
|
+
(mods & MOD_CONTROL ? FCONTROL : 0) |
|
|
365
|
+
(mods & MOD_SHIFT ? FSHIFT : 0) |
|
|
366
|
+
(mods & (MOD_ALT | MOD_OPTION) ? FALT : 0));
|
|
367
|
+
accels->emplace_back(accel);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
collect_accels(accels, item);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
HACCEL
|
|
375
|
+
Menu_create_accelerator_table (Menu* menu)
|
|
376
|
+
{
|
|
377
|
+
if (!menu) return NULL;
|
|
378
|
+
|
|
379
|
+
get_data(menu).modified = false;
|
|
380
|
+
|
|
381
|
+
std::vector<ACCEL> accels;
|
|
382
|
+
collect_accels(&accels, menu);
|
|
383
|
+
if (accels.empty()) return NULL;
|
|
384
|
+
|
|
385
|
+
return CreateAcceleratorTableW(accels.data(), (int) accels.size());
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
static Menu*
|
|
389
|
+
find_item (Menu* menu, UINT id)
|
|
390
|
+
{
|
|
391
|
+
for (auto& child : *menu)
|
|
392
|
+
{
|
|
393
|
+
Menu* item = child.get();
|
|
394
|
+
if (!item || !item->is_enabled()) continue;
|
|
395
|
+
|
|
396
|
+
if (get_data(item).id == id) return item;
|
|
397
|
+
|
|
398
|
+
Menu* found = find_item(item, id);
|
|
399
|
+
if (found) return found;
|
|
400
|
+
}
|
|
401
|
+
return NULL;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
void
|
|
405
|
+
Menu_call_command_event (Menu* menu, uint id)
|
|
406
|
+
{
|
|
407
|
+
if (!menu) return;
|
|
408
|
+
|
|
409
|
+
Menu* item = find_item(menu, (UINT) id);
|
|
410
|
+
if (!item) return;
|
|
411
|
+
|
|
412
|
+
Event e;
|
|
413
|
+
Menu_call_click_event(item, &e);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
void
|
|
417
|
+
Menu_call_command_event (HMENU hmenu, uint index)
|
|
418
|
+
{
|
|
419
|
+
Menu* menu = get_item_owner(hmenu, index);
|
|
420
|
+
if (!menu) return;
|
|
421
|
+
|
|
422
|
+
Event e;
|
|
423
|
+
Menu_call_click_event(menu, &e);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
void
|
|
427
|
+
Menu_call_open_event (HMENU hmenu)
|
|
428
|
+
{
|
|
429
|
+
Menu* menu = get_submenu_owner(hmenu);
|
|
430
|
+
if (!menu) return;
|
|
431
|
+
|
|
432
|
+
Event e;
|
|
433
|
+
Menu_call_open_submenu_event(menu, &e);
|
|
434
|
+
|
|
435
|
+
int count = GetMenuItemCount(hmenu);
|
|
436
|
+
for (int i = 0; i < count; ++i)
|
|
437
|
+
{
|
|
438
|
+
Menu* child = get_item_owner(hmenu, i);
|
|
439
|
+
if (!child) continue;
|
|
440
|
+
|
|
441
|
+
Event ce;
|
|
442
|
+
Menu_call_show_event(child, &ce);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
void
|
|
447
|
+
Menu_call_close_event (HMENU hmenu)
|
|
448
|
+
{
|
|
449
|
+
Menu* menu = get_submenu_owner(hmenu);
|
|
450
|
+
if (!menu) return;
|
|
451
|
+
|
|
452
|
+
int count = GetMenuItemCount(hmenu);
|
|
453
|
+
for (int i = 0; i < count; ++i)
|
|
454
|
+
{
|
|
455
|
+
Menu* child = get_item_owner(hmenu, i);
|
|
456
|
+
if (!child) continue;
|
|
457
|
+
|
|
458
|
+
Event ce;
|
|
459
|
+
Menu_call_hide_event(child, &ce);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
Event e;
|
|
463
|
+
Menu_call_close_submenu_event(menu, &e);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
HMENU
|
|
468
|
+
MenuData::get_hsubmenu (Menu* menu, bool menubar)
|
|
469
|
+
{
|
|
470
|
+
if (!hsubmenu)
|
|
471
|
+
{
|
|
472
|
+
hsubmenu = create_hmenu(menu, menubar);
|
|
473
|
+
this->menubar = menubar;
|
|
474
|
+
}
|
|
475
|
+
else if (menubar != this->menubar)
|
|
476
|
+
{
|
|
477
|
+
HMENU old = hsubmenu;
|
|
478
|
+
hsubmenu = create_hmenu(menu, menubar);
|
|
479
|
+
this->menubar = menubar;
|
|
480
|
+
|
|
481
|
+
int index = 0;
|
|
482
|
+
for (auto it = menu->begin(); it != menu->end(); ++it, ++index)
|
|
483
|
+
insert_item(hsubmenu, it->get(), index);
|
|
484
|
+
destroy_hmenu(old);
|
|
485
|
+
}
|
|
486
|
+
return hsubmenu;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
}// Reflex
|
data/src/win32/menu.h
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// -*- c++ -*-
|
|
2
|
+
#pragma once
|
|
3
|
+
#ifndef __REFLEX_SRC_WIN32_MENU_H__
|
|
4
|
+
#define __REFLEX_SRC_WIN32_MENU_H__
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include <xot/windows.h>
|
|
8
|
+
#include "../menu.h"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
namespace Reflex
|
|
12
|
+
{
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
void Menu_track_popup (HMENU hmenu, UINT flags, POINT pos, HWND owner);
|
|
16
|
+
|
|
17
|
+
HMENU Menu_get_hmenu (Menu* menu, bool menubar = false);
|
|
18
|
+
|
|
19
|
+
bool Menu_is_modified (Menu* menu);
|
|
20
|
+
|
|
21
|
+
HACCEL Menu_create_accelerator_table (Menu* menu);
|
|
22
|
+
|
|
23
|
+
void Menu_call_command_event (Menu* menu, uint id);
|
|
24
|
+
|
|
25
|
+
void Menu_call_command_event (HMENU hmenu, uint index);
|
|
26
|
+
|
|
27
|
+
void Menu_call_open_event (HMENU hmenu);
|
|
28
|
+
|
|
29
|
+
void Menu_call_close_event (HMENU hmenu);
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
}// Reflex
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
#endif//EOH
|
data/src/win32/opengl.cpp
CHANGED
|
@@ -3,14 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#include <rays/rays.h>
|
|
5
5
|
#include "reflex/exception.h"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
namespace Rays
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
const PIXELFORMATDESCRIPTOR* get_pixel_format_descriptor ();
|
|
12
|
-
|
|
13
|
-
}// Rays
|
|
6
|
+
#include "../rays.h"
|
|
14
7
|
|
|
15
8
|
|
|
16
9
|
namespace Reflex
|
|
@@ -40,7 +33,7 @@ namespace Reflex
|
|
|
40
33
|
if (!hdc)
|
|
41
34
|
system_error(__FILE__, __LINE__);
|
|
42
35
|
|
|
43
|
-
const auto* pfd = Rays::
|
|
36
|
+
const auto* pfd = Rays::OpenGL_get_pixel_format_descriptor();
|
|
44
37
|
int pf = ChoosePixelFormat(hdc, pfd);
|
|
45
38
|
if (pf == 0)
|
|
46
39
|
system_error(__FILE__, __LINE__);
|
data/src/win32/reflex.cpp
CHANGED
|
@@ -1,17 +1,38 @@
|
|
|
1
1
|
#include "reflex/reflex.h"
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
#include <xot/windows.h>
|
|
4
5
|
#include "reflex/exception.h"
|
|
6
|
+
#include "../rays.h"
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
namespace Reflex
|
|
8
10
|
{
|
|
9
11
|
|
|
10
12
|
|
|
13
|
+
static struct ReflexLoaded
|
|
14
|
+
{
|
|
15
|
+
ReflexLoaded ()
|
|
16
|
+
{
|
|
17
|
+
Rays::Rays_set_pre_init_fun(pre_init);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static void pre_init ()
|
|
21
|
+
{
|
|
22
|
+
// enable High DPI: before Rays makes the hidden window for its OpenGL
|
|
23
|
+
// context, as Windows takes no declaration after a window
|
|
24
|
+
SetProcessDPIAware();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
} reflex_loaded;
|
|
28
|
+
|
|
29
|
+
|
|
11
30
|
namespace global
|
|
12
31
|
{
|
|
13
32
|
|
|
14
|
-
static bool initialized
|
|
33
|
+
static bool initialized = false;
|
|
34
|
+
|
|
35
|
+
static bool com_initialized = false;
|
|
15
36
|
|
|
16
37
|
}// global
|
|
17
38
|
|
|
@@ -21,8 +42,10 @@ namespace Reflex
|
|
|
21
42
|
{
|
|
22
43
|
if (global::initialized)
|
|
23
44
|
reflex_error(__FILE__, __LINE__, "already initialized.");
|
|
24
|
-
|
|
25
45
|
global::initialized = true;
|
|
46
|
+
|
|
47
|
+
global::com_initialized =
|
|
48
|
+
SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
|
|
26
49
|
}
|
|
27
50
|
|
|
28
51
|
void
|
|
@@ -30,8 +53,26 @@ namespace Reflex
|
|
|
30
53
|
{
|
|
31
54
|
if (!global::initialized)
|
|
32
55
|
reflex_error(__FILE__, __LINE__, "not initialized.");
|
|
33
|
-
|
|
34
56
|
global::initialized = false;
|
|
57
|
+
|
|
58
|
+
if (global::com_initialized)
|
|
59
|
+
{
|
|
60
|
+
CoUninitialize();
|
|
61
|
+
global::com_initialized = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
void
|
|
66
|
+
alert (const char* message, const char* title)
|
|
67
|
+
{
|
|
68
|
+
if (!message)
|
|
69
|
+
argument_error(__FILE__, __LINE__);
|
|
70
|
+
|
|
71
|
+
MessageBoxW(
|
|
72
|
+
GetActiveWindow(),
|
|
73
|
+
String(message) .to_wstr().c_str(),
|
|
74
|
+
String(title ? title : "").to_wstr().c_str(),
|
|
75
|
+
MB_OK | MB_ICONINFORMATION | MB_TASKMODAL);
|
|
35
76
|
}
|
|
36
77
|
|
|
37
78
|
|