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/samples/menu.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
%w[xot rays reflex]
|
|
2
|
+
.map {|s| File.expand_path "../../#{s}/lib", __dir__}
|
|
3
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
4
|
+
|
|
5
|
+
require 'xot/util'
|
|
6
|
+
require 'reflex'
|
|
7
|
+
|
|
8
|
+
icon = Rays::Image.new(8, 8).paint {fill :red; ellipse 0, 0, 8}
|
|
9
|
+
|
|
10
|
+
Reflex.start do
|
|
11
|
+
mod = Xot.osx? ? :command : :control
|
|
12
|
+
app_menu = Reflex::Application.instance.menu || Reflex::Menu.new
|
|
13
|
+
file = app_menu.add Reflex::Menu.new('File'), index: 1
|
|
14
|
+
hello = file .add Reflex::Menu.new('Hello', image: icon, shortcut: [:e, mod])
|
|
15
|
+
help = file .add Reflex::Menu.new('Help', shortcut: :f1)
|
|
16
|
+
|
|
17
|
+
popup_menu = Reflex::Menu.new
|
|
18
|
+
cut = popup_menu.add Reflex::Menu.new('Cut')
|
|
19
|
+
copy = popup_menu.add Reflex::Menu.new('Copy')
|
|
20
|
+
paste = popup_menu.add Reflex::Menu.new('Paste')
|
|
21
|
+
|
|
22
|
+
hello.on(:click) {|e| p :hello}
|
|
23
|
+
help .on(:click) {|e| p :help}
|
|
24
|
+
cut .on(:click) {|e| p :cut}
|
|
25
|
+
copy .on(:click) {|e| p :copy}
|
|
26
|
+
paste.on(:click) {|e| p :paste}
|
|
27
|
+
|
|
28
|
+
win = Reflex::Window.new title: 'Menu Test', frame: [100, 100, 400, 300]
|
|
29
|
+
win.menu = app_menu if Xot.win32?
|
|
30
|
+
win.on(:pointer_down) {|e| popup_menu.popup win.root, e.x, e.y if e.right?}
|
|
31
|
+
win.show
|
|
32
|
+
end
|
data/samples/model.rb
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Manual check for Reflex.alert.
|
|
2
|
+
#
|
|
3
|
+
# ruby alert.rb
|
|
4
|
+
# -> a window counts its frames and shows the largest dt so far.
|
|
5
|
+
# each key shows an alert, which returns only when closed
|
|
6
|
+
# 1 with a title
|
|
7
|
+
# macos: the title in bold, the message under it
|
|
8
|
+
# windows: the title in the title bar
|
|
9
|
+
# 2 with no title
|
|
10
|
+
# macos: the message in bold
|
|
11
|
+
# windows: an empty title bar, not 'Error'
|
|
12
|
+
# 3 a long message over many lines, as a backtrace
|
|
13
|
+
# 4 a message and a title in japanese
|
|
14
|
+
# 5 in 3 seconds: switch to another app meanwhile
|
|
15
|
+
# -> the alert comes to the front and takes the keyboard
|
|
16
|
+
# q quit
|
|
17
|
+
# while an alert is open, the frame count stops. once it is
|
|
18
|
+
# closed, 'closed' is logged and the largest dt jumps by about the
|
|
19
|
+
# time it was open, as requestAnimationFrame does after alert()
|
|
20
|
+
# ruby alert.rb before
|
|
21
|
+
# -> an alert shows before the app starts, in front of the
|
|
22
|
+
# terminal, and closes with return. then the window opens and
|
|
23
|
+
# 'on_start' is logged: an alert does not keep the app from
|
|
24
|
+
# finishing its launch
|
|
25
|
+
|
|
26
|
+
%w[xot rays reflex]
|
|
27
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
28
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
29
|
+
|
|
30
|
+
require 'reflex'
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
KEYS = [
|
|
34
|
+
'1: with a title 2: with no title',
|
|
35
|
+
'3: long message 4: japanese',
|
|
36
|
+
'5: in 3 seconds q: quit'
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
LOG = []
|
|
40
|
+
|
|
41
|
+
def log(text)
|
|
42
|
+
LOG.unshift text
|
|
43
|
+
puts text
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
Reflex.alert 'Shown before the app starts.', title: 'Before' if ARGV[0] == 'before'
|
|
48
|
+
|
|
49
|
+
Reflex.start do
|
|
50
|
+
log 'on_start'
|
|
51
|
+
|
|
52
|
+
frames, max_dt = 0, 0
|
|
53
|
+
|
|
54
|
+
win = Reflex::Window.new title: 'Reflex.alert', frame: [100, 100, 560, 360]
|
|
55
|
+
|
|
56
|
+
alert = -> (message, title = nil) {
|
|
57
|
+
Reflex.alert message, title: title
|
|
58
|
+
log "closed: #{title.inspect}"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
win.on(:key_down) do |e|
|
|
62
|
+
case e.chars
|
|
63
|
+
when '1' then alert['The message.', 'The Title']
|
|
64
|
+
when '2' then alert['The message with no title.']
|
|
65
|
+
when '3'
|
|
66
|
+
lines = 40.times.map {" from /path/to/app/file_#{_1}.rb:#{_1 * 7}:in 'method_#{_1}'"}
|
|
67
|
+
alert[["boom (RuntimeError)", *lines].join("\n"), 'Long']
|
|
68
|
+
when '4' then alert['日本語のメッセージ', '日本語のタイトル']
|
|
69
|
+
when '5'
|
|
70
|
+
log 'an alert in 3 seconds'
|
|
71
|
+
win.root.delay(3) {alert['Shown by a timer.', 'Timer']}
|
|
72
|
+
when 'q' then Reflex.quit
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
win.on(:update) do |e|
|
|
77
|
+
frames += 1
|
|
78
|
+
max_dt = e.dt if e.dt > max_dt
|
|
79
|
+
win.redraw
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
win.on(:draw) do |e|
|
|
83
|
+
p = e.painter
|
|
84
|
+
p.background 0.1, 0.1, 0.15
|
|
85
|
+
p.fill 1
|
|
86
|
+
KEYS.each_with_index {|text, i| p.text text, 10, 10 + i * 18}
|
|
87
|
+
p.text "frames: #{frames} max dt: #{'%.3f' % max_dt}", 10, 76
|
|
88
|
+
p.fill 0.5, 1, 0.5
|
|
89
|
+
LOG.first(12).each_with_index {|text, i| p.text text, 10, 110 + i * 18}
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
win.show
|
|
93
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Manual check for always_on_top and always_on_bottom.
|
|
2
|
+
#
|
|
3
|
+
# Three windows sit on top of each other, one kept above every other
|
|
4
|
+
# application, one kept below, and one that behaves like any other window.
|
|
5
|
+
# The colour and the text say which is which.
|
|
6
|
+
#
|
|
7
|
+
# 1. click another application, a browser or a finder window
|
|
8
|
+
# -> the red one stays in front of it, the green one goes behind it,
|
|
9
|
+
# and the blue one behaves as usual
|
|
10
|
+
# 2. press 2 on the blue window
|
|
11
|
+
# -> it turns red and comes to the front, and stays there
|
|
12
|
+
# 3. press 3 on it
|
|
13
|
+
# -> it turns green and drops behind the other application
|
|
14
|
+
# 4. press 1 on it
|
|
15
|
+
# -> it is a plain window again
|
|
16
|
+
# 5. press 2 on the green window
|
|
17
|
+
# -> it turns red. the two ends are never both on
|
|
18
|
+
# 6. windows only: click the green one where another application covers it
|
|
19
|
+
# -> it must not come to the front
|
|
20
|
+
|
|
21
|
+
%w[xot rays reflex]
|
|
22
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
23
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
24
|
+
|
|
25
|
+
require 'reflex'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
COLORS = {
|
|
29
|
+
normal: [0.2, 0.3, 0.6],
|
|
30
|
+
top: [0.7, 0.2, 0.2],
|
|
31
|
+
bottom: [0.2, 0.5, 0.3]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def level_of(win)
|
|
35
|
+
case
|
|
36
|
+
when win.always_on_top? then :top
|
|
37
|
+
when win.always_on_bottom? then :bottom
|
|
38
|
+
else :normal
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def set_level(win, level)
|
|
43
|
+
win.always_on_top = level == :top
|
|
44
|
+
win.always_on_bottom = level == :bottom
|
|
45
|
+
puts "#{win.title}: #{level_of win}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
%i[normal top bottom].each_with_index do |level, i|
|
|
49
|
+
win = Reflex::Window.new(
|
|
50
|
+
title: level.to_s,
|
|
51
|
+
frame: [100 + i * 50, 100 + i * 50, 320, 140])
|
|
52
|
+
|
|
53
|
+
set_level win, level
|
|
54
|
+
|
|
55
|
+
win.on(:draw) do |e|
|
|
56
|
+
p = e.painter
|
|
57
|
+
p.background(*COLORS[level_of(win)])
|
|
58
|
+
p.fill 1, 1, 1
|
|
59
|
+
p.text level_of(win).to_s, 10, 10
|
|
60
|
+
p.text '1: normal 2: top 3: bottom', 10, 40
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
win.on(:key_down) do |e|
|
|
64
|
+
case e.chars
|
|
65
|
+
when '1' then set_level win, :normal
|
|
66
|
+
when '2' then set_level win, :top
|
|
67
|
+
when '3' then set_level win, :bottom
|
|
68
|
+
end
|
|
69
|
+
win.redraw
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
win.show
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
Reflex.start
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Manual check for Application#background and #background_menu.
|
|
2
|
+
#
|
|
3
|
+
# The application lives in the menu bar: no dock icon, a status item
|
|
4
|
+
# with a black circle, and it keeps running with no window open.
|
|
5
|
+
#
|
|
6
|
+
# 1. start and look at the dock
|
|
7
|
+
# -> the application is not there, and nothing steals the focus
|
|
8
|
+
# 2. click the black circle at the right end of the menu bar
|
|
9
|
+
# -> a menu opens with Settings, Toggle Dock and Quit
|
|
10
|
+
# 3. click Settings
|
|
11
|
+
# -> a small window opens, once per click
|
|
12
|
+
# 4. close every window
|
|
13
|
+
# -> the application keeps running, the status item stays
|
|
14
|
+
# 5. click Toggle Dock
|
|
15
|
+
# -> the application appears in the dock with the standard menu
|
|
16
|
+
# bar, and the status item stays
|
|
17
|
+
# 6. close every window, then click Toggle Dock in the status item menu
|
|
18
|
+
# -> gone from the dock again, still running
|
|
19
|
+
# 7. click Quit
|
|
20
|
+
# -> the application quits
|
|
21
|
+
|
|
22
|
+
%w[xot rays reflex]
|
|
23
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
24
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
25
|
+
|
|
26
|
+
require 'reflex'
|
|
27
|
+
|
|
28
|
+
icon = Rays::Image.new(16, 16).paint {fill :black; ellipse 2, 2, 12}
|
|
29
|
+
|
|
30
|
+
Reflex.start name: 'BackgroundApp' do
|
|
31
|
+
settings = Reflex::Menu.new('Settings')
|
|
32
|
+
toggle = Reflex::Menu.new('Toggle Dock')
|
|
33
|
+
quit = Reflex::Menu.new('Quit')
|
|
34
|
+
|
|
35
|
+
settings.on(:click) do |e|
|
|
36
|
+
Reflex::Window.new(title: 'Settings', frame: [100, 100, 300, 200]).show
|
|
37
|
+
end
|
|
38
|
+
toggle.on(:click) do |e|
|
|
39
|
+
app = Reflex::Application.instance
|
|
40
|
+
app.background = !app.background?
|
|
41
|
+
end
|
|
42
|
+
quit.on(:click) {|e| Reflex::Application.instance.quit}
|
|
43
|
+
|
|
44
|
+
self.background_menu = Reflex::Menu.new('BG', image: icon) do
|
|
45
|
+
add settings
|
|
46
|
+
add toggle
|
|
47
|
+
add Reflex::Menu.new('-')
|
|
48
|
+
add quit
|
|
49
|
+
end
|
|
50
|
+
self.background = true
|
|
51
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Manual check for the synthesized window enter/leave.
|
|
2
|
+
#
|
|
3
|
+
# The window's edge is drawn as a frame: green while the pointer is inside,
|
|
4
|
+
# red while it is outside, so what the log says can be seen at a glance.
|
|
5
|
+
#
|
|
6
|
+
# 1. move the mouse in and out with NO button held
|
|
7
|
+
# -> one :enter on the way in, one :leave on the way out, never a pair
|
|
8
|
+
# 2. press LEFT inside, drag out, drag back in, release inside
|
|
9
|
+
# -> :leave on the way out, :enter on the way back in, both WHILE
|
|
10
|
+
# dragging. this is what no platform used to send
|
|
11
|
+
# 3. release the button outside, then move back in
|
|
12
|
+
# -> a single :enter, not one for the release and one for the move
|
|
13
|
+
# 4. cross the edge quickly, several times
|
|
14
|
+
# -> the count of :enter and :leave stays balanced, never two in a row
|
|
15
|
+
# 5. macos only: after step 2, watch for a late :enter once the button is
|
|
16
|
+
# released
|
|
17
|
+
# -> there must NOT be one; it was already announced during the drag
|
|
18
|
+
# 6. right click inside to pop a menu up, dismiss it, then move in and out
|
|
19
|
+
# -> :cancel is logged, and the boundary keeps working afterwards. the
|
|
20
|
+
# frame may turn red while the menu covers the window
|
|
21
|
+
# 7. hold LEFT, drag outside, then right click to pop the menu up
|
|
22
|
+
# -> :cancel is logged for the left press; moving back in still gives a
|
|
23
|
+
# single :enter, and releasing left produces nothing
|
|
24
|
+
|
|
25
|
+
%w[xot rays reflex]
|
|
26
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
27
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
28
|
+
|
|
29
|
+
require 'reflex'
|
|
30
|
+
|
|
31
|
+
Reflex.start do
|
|
32
|
+
menu = Reflex::Menu.new
|
|
33
|
+
item = menu.add Reflex::Menu.new('Hello')
|
|
34
|
+
item.on(:click) {puts 'menu item clicked'}
|
|
35
|
+
|
|
36
|
+
win = Reflex::Window.new frame: [100, 100, 400, 300]
|
|
37
|
+
inside = false
|
|
38
|
+
last = nil
|
|
39
|
+
pressed = false
|
|
40
|
+
|
|
41
|
+
show = -> action, e do
|
|
42
|
+
puts "%-6s pressed:%-5s pos:%s" % [
|
|
43
|
+
action, pressed, e.position.to_a.map {_1.round}
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
boundary = -> action, e do
|
|
48
|
+
warn "TWO #{action} IN A ROW" if action == last
|
|
49
|
+
last = action
|
|
50
|
+
show[action, e]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
win.on(:pointer_enter) {|e| inside = true; boundary[:enter, e]; win.redraw}
|
|
54
|
+
win.on(:pointer_leave) {|e| inside = false; boundary[:leave, e]; win.redraw}
|
|
55
|
+
|
|
56
|
+
win.on(:pointer_down) do |e|
|
|
57
|
+
pressed = true
|
|
58
|
+
menu.popup win.root, e.x, e.y if e.right?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
win.on(:pointer_up) {|e| pressed = false}
|
|
62
|
+
|
|
63
|
+
win.on(:pointer_cancel) do |e|
|
|
64
|
+
pressed = false
|
|
65
|
+
show[:cancel, e]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
win.on(:draw) do |e|
|
|
69
|
+
e.painter.push fill: nil, stroke: (inside ? :green : :red), stroke_width: 8 do
|
|
70
|
+
e.painter.rect 4, 4, e.bounds.width - 8, e.bounds.height - 8
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
win.show
|
|
75
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Manual check for the paths into ruby that need a hand on the mouse or the
|
|
2
|
+
# keyboard, the rest is in test_application.rb. Reflex.start must return
|
|
3
|
+
# when the app quits, and a raise in a callback must come out of it as a
|
|
4
|
+
# ruby exception with a backtrace, never as 'libc++abi: terminating'.
|
|
5
|
+
#
|
|
6
|
+
# ruby callback_exception.rb
|
|
7
|
+
# -> quit with cmd-q, then again with the close button, then again
|
|
8
|
+
# from the dock menu, then again with the q key. 'after start'
|
|
9
|
+
# and 'at_exit' must be printed every time
|
|
10
|
+
# ruby callback_exception.rb block
|
|
11
|
+
# -> press cmd-q twice. the first one is blocked by on_quit, the
|
|
12
|
+
# second one goes. the close button would close the window
|
|
13
|
+
# first and leave the app running without one
|
|
14
|
+
# ruby callback_exception.rb HOOK
|
|
15
|
+
# -> raise in that hook, and expect a ruby backtrace and status 1
|
|
16
|
+
# pointer click the window
|
|
17
|
+
# key press a key
|
|
18
|
+
# resize resize the window
|
|
19
|
+
# activate switch to another app and back
|
|
20
|
+
# menu choose Raise from the File menu, or press cmd-r (ctrl-r on windows)
|
|
21
|
+
# file press o and choose a file in the dialog
|
|
22
|
+
# quit quit the app any way, on_quit raises
|
|
23
|
+
|
|
24
|
+
%w[xot rays reflex]
|
|
25
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
26
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
27
|
+
|
|
28
|
+
require 'xot/util'
|
|
29
|
+
require 'reflex'
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
MODE = ARGV[0] || 'none'
|
|
33
|
+
MOD = Xot.osx? ? :command : :control
|
|
34
|
+
|
|
35
|
+
NOTES = {
|
|
36
|
+
'none' => 'quit with cmd-q, the close button or the dock menu',
|
|
37
|
+
'block' => 'press cmd-q twice. the first one is blocked, the second one goes',
|
|
38
|
+
'pointer' => 'click the window',
|
|
39
|
+
'key' => 'press any key',
|
|
40
|
+
'resize' => 'resize the window',
|
|
41
|
+
'activate' => 'switch to another app and back',
|
|
42
|
+
'menu' => "choose Raise from the File menu, or press #{MOD}-r",
|
|
43
|
+
'file' => 'press o and choose a file',
|
|
44
|
+
'quit' => 'quit any way, on_quit raises'
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
unless NOTES.key? MODE
|
|
48
|
+
warn "unknown mode: #{MODE}"
|
|
49
|
+
exit 2
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
at_exit {puts 'at_exit'}
|
|
53
|
+
|
|
54
|
+
def boom(where)
|
|
55
|
+
raise "boom in #{where}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
quit_count = 0
|
|
60
|
+
|
|
61
|
+
Reflex.start do
|
|
62
|
+
on(:quit) do |e|
|
|
63
|
+
quit_count += 1
|
|
64
|
+
boom 'on_quit' if MODE == 'quit'
|
|
65
|
+
e.block if MODE == 'block' && quit_count == 1
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
win = Reflex::Window.new title: "callback_exception: #{MODE}", frame: [100, 100, 480, 240]
|
|
69
|
+
|
|
70
|
+
win.on(:draw) do |e|
|
|
71
|
+
p = e.painter
|
|
72
|
+
p.fill 1
|
|
73
|
+
p.text "mode: #{MODE}", 20, 30
|
|
74
|
+
p.text NOTES[MODE], 20, 60
|
|
75
|
+
p.text 'q: quit o: file dialog', 20, 100
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
win.on(:pointer_down) {|e| boom 'on_pointer_down' if MODE == 'pointer'}
|
|
79
|
+
win.on(:resize) {|e| boom 'on_resize' if MODE == 'resize'}
|
|
80
|
+
win.on(:activate) {|e| boom 'on_activate' if MODE == 'activate'}
|
|
81
|
+
|
|
82
|
+
win.on(:key_down) do |e|
|
|
83
|
+
boom 'on_key_down' if MODE == 'key'
|
|
84
|
+
case e.chars
|
|
85
|
+
when 'q' then Reflex.quit
|
|
86
|
+
when 'o'
|
|
87
|
+
dialog = Reflex::FileDialog.new owner: win
|
|
88
|
+
dialog.on(:file) {|e| boom 'on_file' if MODE == 'file'}
|
|
89
|
+
dialog.open_file {|path| puts "chosen: #{path}"}
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
app_menu = Reflex::Application.instance.menu || Reflex::Menu.new
|
|
94
|
+
file = app_menu.add Reflex::Menu.new('File'), index: 1
|
|
95
|
+
item = file .add Reflex::Menu.new('Raise', shortcut: [:r, MOD])
|
|
96
|
+
item.on(:click) {|e| boom 'menu on_click' if MODE == 'menu'}
|
|
97
|
+
|
|
98
|
+
win.show
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
puts 'after start'
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Manual check for Window_cancel_active_pointers and
|
|
2
|
+
# reject_unpaired_up_pointers.
|
|
3
|
+
#
|
|
4
|
+
# 1. right click
|
|
5
|
+
# -> :cancel logged (down_id set), then the menu opens
|
|
6
|
+
# 2. close the menu (click away or select), keep watching the log
|
|
7
|
+
# -> NO :up line for the canceled id must appear
|
|
8
|
+
# 3. move the mouse
|
|
9
|
+
# -> the white dot follows (tracking alive)
|
|
10
|
+
# 4. hold LEFT, then right click while holding
|
|
11
|
+
# -> :cancel logged for the left press, menu opens
|
|
12
|
+
# close the menu, release left
|
|
13
|
+
# -> NO :up for the left press
|
|
14
|
+
# press left again
|
|
15
|
+
# -> :down with a NEW id, then :up pairs with it as usual
|
|
16
|
+
# 5. plain left clicks behave as before (:down then :up, ids advance)
|
|
17
|
+
|
|
18
|
+
%w[xot rays reflex]
|
|
19
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
20
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
21
|
+
|
|
22
|
+
require 'reflex'
|
|
23
|
+
|
|
24
|
+
Reflex.start do
|
|
25
|
+
menu = Reflex::Menu.new
|
|
26
|
+
item = menu.add Reflex::Menu.new('Hello')
|
|
27
|
+
item.on(:click) {puts "menu item clicked"}
|
|
28
|
+
|
|
29
|
+
win = Reflex::Window.new frame: [100, 100, 400, 300]
|
|
30
|
+
pos = nil
|
|
31
|
+
|
|
32
|
+
win.on(:pointer) do |e|
|
|
33
|
+
e.each do |p|
|
|
34
|
+
next if p.move? && p.down.nil? # skip hover moves to keep the log readable
|
|
35
|
+
puts "%-7s id:%-3d down_id:%-5s buttons:%p pos:%s" % [
|
|
36
|
+
p.action, p.id, p.down&.id.inspect, p.types, p.position.to_a.map {_1.round}
|
|
37
|
+
]
|
|
38
|
+
end
|
|
39
|
+
if e.move?
|
|
40
|
+
pos = e.position
|
|
41
|
+
win.redraw
|
|
42
|
+
end
|
|
43
|
+
menu.popup win.root, e.x, e.y if e.down? && e.right?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
win.on(:draw) do |e|
|
|
47
|
+
e.painter.push fill: :white do
|
|
48
|
+
e.painter.ellipse pos.x - 5, pos.y - 5, 10, 10 if pos
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
win.show
|
|
53
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Manual check for ColorPicker, the rest is in test_color_picker.rb.
|
|
2
|
+
#
|
|
3
|
+
# ruby color_picker.rb
|
|
4
|
+
# -> press c to open the picker. the window background follows the
|
|
5
|
+
# picked color, and 'close' is printed when the picker closes
|
|
6
|
+
# macos: the block is called on every change while the panel is open
|
|
7
|
+
# windows: the block is called once when the dialog is closed with ok
|
|
8
|
+
# a toggle alpha, then press c again (macos only)
|
|
9
|
+
# d open a second picker. on macos the first one prints 'close' at
|
|
10
|
+
# once because the shared panel moves to the second one
|
|
11
|
+
# q quit
|
|
12
|
+
# ruby color_picker.rb raise
|
|
13
|
+
# -> the block raises. expect a ruby backtrace and status 1
|
|
14
|
+
|
|
15
|
+
%w[xot rays reflex]
|
|
16
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
17
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
18
|
+
|
|
19
|
+
require 'reflex'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
RAISE = ARGV[0] == 'raise'
|
|
23
|
+
|
|
24
|
+
at_exit {puts 'at_exit'}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Reflex.start do
|
|
28
|
+
win = Reflex::Window.new title: 'color_picker', frame: [100, 100, 480, 240]
|
|
29
|
+
pickers = 2.times.map do |i|
|
|
30
|
+
Reflex::ColorPicker.new(owner: win).tap do |picker|
|
|
31
|
+
picker.on(:close) {|e| puts "close #{i + 1}"}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
color = Reflex::Color.new 0.5, 0.5, 0.5
|
|
35
|
+
|
|
36
|
+
pick = -> picker do
|
|
37
|
+
picker.pick_color(color) do |c|
|
|
38
|
+
raise 'boom in the color block' if RAISE
|
|
39
|
+
color = c
|
|
40
|
+
win.redraw
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
win.on(:draw) do |e|
|
|
45
|
+
p = e.painter
|
|
46
|
+
p.fill color
|
|
47
|
+
p.rect e.bounds
|
|
48
|
+
p.fill 1
|
|
49
|
+
p.text "color: #{color} alpha: #{pickers[0].alpha?}", 20, 30
|
|
50
|
+
p.text 'c: pick d: pick with 2nd a: toggle alpha q: quit', 20, 60
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
win.on(:key_down) do |e|
|
|
54
|
+
case e.chars
|
|
55
|
+
when 'c' then pick.call pickers[0]
|
|
56
|
+
when 'd' then pick.call pickers[1]
|
|
57
|
+
when 'a' then pickers[0].alpha = !pickers[0].alpha?; win.redraw
|
|
58
|
+
when 'q' then Reflex.quit
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
win.show
|
|
63
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Manual check for FileDialog.
|
|
2
|
+
#
|
|
3
|
+
# Each key opens a dialog. The window logs what came back, newest first.
|
|
4
|
+
# A dialog with an owner appears as a sheet on macos.
|
|
5
|
+
#
|
|
6
|
+
# Three things answer a selection: the block given to open_file and
|
|
7
|
+
# friends, the on_file hook of the dialog, and the on_file hook of the
|
|
8
|
+
# owner window, in that order. A hook does not cost the block its turn,
|
|
9
|
+
# even though it hides the method the block used to be called from.
|
|
10
|
+
#
|
|
11
|
+
# 1. press 1 and pick a file
|
|
12
|
+
# -> 'block', 'dialog on_file' and 'window on_file_open' all log
|
|
13
|
+
# the path, in that order, the hook here costing nothing
|
|
14
|
+
# 2. press 1 and cancel
|
|
15
|
+
# -> 'dialog on_cancel' logs, and no path is logged
|
|
16
|
+
# 3. press 2 and pick more than one file
|
|
17
|
+
# -> every path is logged
|
|
18
|
+
# 4. press 3
|
|
19
|
+
# -> only directories can be chosen, and files are greyed out
|
|
20
|
+
# 5. press 4, type a name and save
|
|
21
|
+
# -> the path is logged, and 'window on_file_save' follows it
|
|
22
|
+
# 6. press 5
|
|
23
|
+
# -> the dialog opens in the home directory
|
|
24
|
+
# 7. press 6
|
|
25
|
+
# -> the name field is already filled with untitled.png
|
|
26
|
+
# 8. press 7
|
|
27
|
+
# -> the dialog is a window of its own, not a sheet, and the log
|
|
28
|
+
# shows no 'window on_file_open': it has no owner
|
|
29
|
+
# 9. press 1 and look at the file list
|
|
30
|
+
# -> only .png and .jpg files can be chosen, and folders stay open
|
|
31
|
+
# 10. press 1 where a file is named in capitals, IMAGE.PNG say
|
|
32
|
+
# -> it can be chosen too, the extension is matched either case
|
|
33
|
+
|
|
34
|
+
%w[xot rays reflex]
|
|
35
|
+
.map {|s| File.expand_path "../../../#{s}/lib", __dir__}
|
|
36
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
37
|
+
|
|
38
|
+
require 'reflex'
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
KEYS = [
|
|
42
|
+
'1: open_file 2: open_files',
|
|
43
|
+
'3: open_directory 4: save_file',
|
|
44
|
+
'5: open_files in ~ 6: save_file named untitled.png',
|
|
45
|
+
'7: open_files with no owner'
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
LOG = []
|
|
49
|
+
|
|
50
|
+
def log(text)
|
|
51
|
+
LOG.unshift text
|
|
52
|
+
puts text
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Reflex.start do
|
|
57
|
+
win = Reflex::Window.new title: 'FileDialog', frame: [100, 100, 560, 400]
|
|
58
|
+
|
|
59
|
+
# the event reaches the owner window too, after the dialog itself
|
|
60
|
+
win.on(:file_open) {|e| log "window on_file_open: #{e.paths}"}
|
|
61
|
+
win.on(:file_save) {|e| log "window on_file_save: #{e.path}"}
|
|
62
|
+
|
|
63
|
+
make = -> (title, owner: win) {
|
|
64
|
+
dialog = Reflex::FileDialog.new owner: owner, title: title do
|
|
65
|
+
extensions %w[png jpg]
|
|
66
|
+
end
|
|
67
|
+
# no super, and the block still runs: it is called from the wrapper,
|
|
68
|
+
# before this hook, rather than from the method this hook hides
|
|
69
|
+
dialog.on(:file) {|e| log "dialog on_file: #{e.action} #{e.paths}"}
|
|
70
|
+
dialog.on(:cancel) {|e| log 'dialog on_cancel'}
|
|
71
|
+
dialog
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
win.on(:key_down) do |e|
|
|
75
|
+
case e.chars
|
|
76
|
+
when '1' then make['Open a file'] .open_file {|path| log "block: #{path}"}
|
|
77
|
+
when '2' then make['Open files'] .open_files {|paths| log "block: #{paths}"}
|
|
78
|
+
when '3' then make['Open a directory'].open_directory {|path| log "block: #{path}"}
|
|
79
|
+
when '4' then make['Save a file'] .save_file {|path| log "block: #{path}"}
|
|
80
|
+
when '5' then make['Open files in ~'] .open_files('~') {|paths| log "block: #{paths}"}
|
|
81
|
+
when '6'
|
|
82
|
+
make['Save as'].save_file(name: 'untitled.png') {|path| log "block: #{path}"}
|
|
83
|
+
when '7'
|
|
84
|
+
make['No owner', owner: nil].open_files {|paths| log "block: #{paths}"}
|
|
85
|
+
else next
|
|
86
|
+
end
|
|
87
|
+
log "-- #{e.chars}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
win.on(:draw) do |e|
|
|
91
|
+
p = e.painter
|
|
92
|
+
p.background 0.1, 0.1, 0.15
|
|
93
|
+
p.fill 1
|
|
94
|
+
KEYS.each_with_index {|text, i| p.text text, 10, 10 + i * 18}
|
|
95
|
+
p.fill 0.5, 1, 0.5
|
|
96
|
+
LOG.first(14).each_with_index {|text, i| p.text text, 10, 100 + i * 18}
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
win.on(:update) {|e| win.redraw}
|
|
100
|
+
|
|
101
|
+
win.show
|
|
102
|
+
end
|