reflexion 0.5.2 → 0.6.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 +19 -1
- data/.doc/ext/reflex/chase_constraint.cpp +84 -0
- data/.doc/ext/reflex/clipboard.cpp +65 -0
- data/.doc/ext/reflex/constraint.cpp +135 -0
- data/.doc/ext/reflex/key_event.cpp +6 -6
- data/.doc/ext/reflex/link_constraint.cpp +178 -0
- data/.doc/ext/reflex/menu.cpp +302 -0
- data/.doc/ext/reflex/native.cpp +22 -4
- data/.doc/ext/reflex/pin.cpp +156 -0
- data/.doc/ext/reflex/pointer.cpp +2 -0
- data/.doc/ext/reflex/pointer_event.cpp +1 -1
- data/.doc/ext/reflex/reflex.cpp +42 -7
- data/.doc/ext/reflex/selector.cpp +4 -4
- data/.doc/ext/reflex/snap_constraint.cpp +125 -0
- data/.doc/ext/reflex/style_length.cpp +3 -2
- data/.doc/ext/reflex/view.cpp +96 -23
- data/.doc/ext/reflex/wheel_constraint.cpp +142 -0
- data/.doc/ext/reflex/window.cpp +59 -17
- data/.github/workflows/release-gem.yml +10 -1
- data/.github/workflows/test.yml +9 -0
- data/ChangeLog.md +30 -0
- data/README.md +1 -0
- data/VERSION +1 -1
- data/ext/reflex/application.cpp +21 -1
- data/ext/reflex/chase_constraint.cpp +89 -0
- data/ext/reflex/clipboard.cpp +69 -0
- data/ext/reflex/constraint.cpp +146 -0
- data/ext/reflex/key_event.cpp +6 -6
- data/ext/reflex/link_constraint.cpp +194 -0
- data/ext/reflex/menu.cpp +330 -0
- data/ext/reflex/native.cpp +22 -4
- data/ext/reflex/pin.cpp +165 -0
- data/ext/reflex/pointer.cpp +2 -0
- data/ext/reflex/pointer_event.cpp +1 -1
- data/ext/reflex/reflex.cpp +42 -7
- data/ext/reflex/selector.cpp +4 -4
- data/ext/reflex/selector.h +1 -1
- data/ext/reflex/snap_constraint.cpp +135 -0
- data/ext/reflex/style_length.cpp +3 -2
- data/ext/reflex/view.cpp +117 -37
- data/ext/reflex/wheel_constraint.cpp +154 -0
- data/ext/reflex/window.cpp +65 -18
- data/include/reflex/application.h +9 -0
- data/include/reflex/clipboard.h +53 -0
- data/include/reflex/constraint.h +275 -0
- data/include/reflex/defs.h +204 -195
- data/include/reflex/event.h +2 -0
- data/include/reflex/menu.h +120 -0
- data/include/reflex/pin.h +68 -0
- data/include/reflex/pointer.h +4 -0
- data/include/reflex/ruby/clipboard.h +23 -0
- data/include/reflex/ruby/constraint.h +94 -0
- data/include/reflex/ruby/menu.h +103 -0
- data/include/reflex/ruby/pin.h +40 -0
- data/include/reflex/ruby/view.h +36 -0
- data/include/reflex/ruby/window.h +36 -18
- data/include/reflex/view.h +39 -12
- data/include/reflex/window.h +17 -4
- data/include/reflex.h +5 -0
- data/lib/reflex/chase_constraint.rb +15 -0
- data/lib/reflex/clipboard.rb +19 -0
- data/lib/reflex/constraint.rb +29 -0
- data/lib/reflex/extension.rb +1 -1
- data/lib/reflex/helper.rb +28 -0
- data/lib/reflex/key_event.rb +7 -12
- data/lib/reflex/link_constraint.rb +31 -0
- data/lib/reflex/menu.rb +76 -0
- data/lib/reflex/pin.rb +39 -0
- data/lib/reflex/pointer.rb +18 -0
- data/lib/reflex/pointer_event.rb +1 -1
- data/lib/reflex/snap_constraint.rb +28 -0
- data/lib/reflex/view.rb +56 -4
- data/lib/reflex/wheel_constraint.rb +28 -0
- data/lib/reflex/wheel_event.rb +9 -0
- data/lib/reflex.rb +15 -6
- data/pod.rake +4 -2
- data/reflex.gemspec +3 -3
- data/samples/constraint.rb +152 -0
- data/samples/menu.rb +29 -0
- data/src/application.cpp +21 -2
- data/src/application.h +5 -0
- data/src/clipboard.cpp +81 -0
- data/src/constraint.cpp +1662 -0
- data/src/constraint.h +64 -0
- data/src/event.cpp +7 -1
- data/src/event.h +1 -2
- data/src/ios/application.mm +5 -0
- data/src/ios/clipboard.mm +44 -0
- data/src/ios/event.h +6 -2
- data/src/ios/event.mm +31 -12
- data/src/ios/menu.mm +36 -0
- data/src/ios/view_controller.mm +45 -12
- data/src/ios/window.mm +6 -0
- data/src/menu.cpp +325 -0
- data/src/menu.h +65 -0
- data/src/osx/app_delegate.mm +74 -125
- data/src/osx/application.mm +16 -0
- data/src/osx/clipboard.mm +45 -0
- data/src/osx/event.mm +40 -10
- data/src/osx/menu.h +25 -0
- data/src/osx/menu.mm +372 -0
- data/src/osx/native_window.mm +27 -0
- data/src/osx/opengl_view.mm +51 -0
- data/src/osx/window.mm +11 -0
- data/src/pin.cpp +137 -0
- data/src/pointer.cpp +27 -16
- data/src/pointer.h +6 -0
- data/src/sdl/application.cpp +5 -0
- data/src/sdl/clipboard.cpp +39 -0
- data/src/sdl/event.cpp +20 -3
- data/src/sdl/event.h +6 -3
- data/src/sdl/menu.cpp +35 -0
- data/src/sdl/window.cpp +26 -8
- data/src/view.cpp +313 -52
- data/src/view.h +18 -2
- data/src/win32/application.cpp +5 -0
- data/src/win32/clipboard.cpp +210 -0
- data/src/win32/event.cpp +11 -1
- data/src/win32/event.h +2 -0
- data/src/win32/menu.cpp +352 -0
- data/src/win32/menu.h +27 -0
- data/src/win32/window.cpp +62 -0
- data/src/win32/window.h +3 -0
- data/src/window.cpp +235 -22
- data/src/window.h +13 -2
- data/src/world.cpp +77 -14
- data/src/world.h +9 -2
- data/test/helper.rb +7 -0
- data/test/test_application.rb +11 -0
- data/test/test_chase_constraint.rb +124 -0
- data/test/test_clipboard.rb +54 -0
- data/test/test_constraint.rb +186 -0
- data/test/test_key_event.rb +6 -0
- data/test/test_link_constraint.rb +239 -0
- data/test/test_menu.rb +207 -0
- data/test/test_pin.rb +65 -0
- data/test/test_pointer.rb +23 -9
- data/test/test_pointer_event.rb +1 -1
- data/test/test_snap_constraint.rb +142 -0
- data/test/test_view.rb +113 -23
- data/test/test_wheel_constraint.rb +127 -0
- data/test/test_wheel_event.rb +15 -9
- data/test/test_window.rb +10 -0
- metadata +82 -8
data/test/test_menu.rb
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestMenu < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def menu(*args, &block)
|
|
7
|
+
Reflex::Menu.new(*args, &block)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_initialize()
|
|
11
|
+
assert_equal '', menu.label
|
|
12
|
+
assert_equal 'File', menu(:File).label
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_add_child()
|
|
16
|
+
menu.tap do |m|
|
|
17
|
+
m.add menu(:A)
|
|
18
|
+
m.add menu(:B)
|
|
19
|
+
m.add menu(:C), index: 1
|
|
20
|
+
assert_equal 3, m.size
|
|
21
|
+
assert_equal %w[A C B], m.map(&:label)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
menu.tap do |m|
|
|
25
|
+
m.add menu(:A)
|
|
26
|
+
m.add menu(:B), index: 0
|
|
27
|
+
m.add menu(:C), index: m.size
|
|
28
|
+
assert_equal %w[B A C], m.map(&:label)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
menu.tap do |m|
|
|
32
|
+
m.add menu(:A)
|
|
33
|
+
m.add menu(:B), index: 99
|
|
34
|
+
m.add menu(:C), index: -1
|
|
35
|
+
m.add menu(:D), index: nil
|
|
36
|
+
assert_equal %w[A B C D], m.map(&:label)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_add_twice_to_same_parent()
|
|
41
|
+
m = menu
|
|
42
|
+
c = m.add menu
|
|
43
|
+
m.add c
|
|
44
|
+
assert_equal 1, m.size
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_add_child_having_other_parent_raises()
|
|
48
|
+
a, b = menu, menu
|
|
49
|
+
c = a.add menu
|
|
50
|
+
assert_raise(ArgumentError, Reflex::ReflexError) {b.add c}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_add_nil_raises()
|
|
54
|
+
assert_raise(TypeError, ArgumentError) {menu.add nil}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def test_remove()
|
|
58
|
+
m = menu
|
|
59
|
+
a = m.add menu(:A)
|
|
60
|
+
m.add menu(:B)
|
|
61
|
+
m.remove a
|
|
62
|
+
assert_equal %w[B], m.map(&:label)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_clear_children()
|
|
66
|
+
m = menu
|
|
67
|
+
m.add menu(:A)
|
|
68
|
+
m.clear_children
|
|
69
|
+
assert_true m.empty?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_find_children()
|
|
73
|
+
root = menu
|
|
74
|
+
root.add(menu(:A)).name = :x
|
|
75
|
+
root.add(menu(:B)).name = :x
|
|
76
|
+
root.add(menu(:C)).name = :y
|
|
77
|
+
assert_equal 2, root.find_children(:x).size
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_find_children_recursive()
|
|
81
|
+
root = menu
|
|
82
|
+
file = root.add menu(:File)
|
|
83
|
+
file.add(menu :Open).name = :x
|
|
84
|
+
assert_equal 1, root.find_children(:x) .size
|
|
85
|
+
assert_equal 0, root.find_children(:x, false).size
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_label()
|
|
89
|
+
m = menu
|
|
90
|
+
m.label = :Open
|
|
91
|
+
assert_equal 'Open', m.label
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_label_changes_separator()
|
|
95
|
+
m = menu :File
|
|
96
|
+
assert_false m.separator?
|
|
97
|
+
m.label = '-'
|
|
98
|
+
assert_true m.separator?
|
|
99
|
+
m.label = :Edit
|
|
100
|
+
assert_false m.separator?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_enable_and_disable()
|
|
104
|
+
m = menu
|
|
105
|
+
assert_true m.enabled?
|
|
106
|
+
m.enable false
|
|
107
|
+
assert_false m.enabled?
|
|
108
|
+
m.enable
|
|
109
|
+
assert_true m.enabled?
|
|
110
|
+
m.disable
|
|
111
|
+
assert_false m.enabled?
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_check_and_uncheck()
|
|
115
|
+
m = menu
|
|
116
|
+
assert_false m.checked?
|
|
117
|
+
m.check true
|
|
118
|
+
assert_true m.checked?
|
|
119
|
+
m.uncheck
|
|
120
|
+
assert_false m.checked?
|
|
121
|
+
m.check
|
|
122
|
+
assert_true m.checked?
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def test_shortcut()
|
|
126
|
+
m = menu
|
|
127
|
+
m.shortcut_key = :s
|
|
128
|
+
assert_equal 's', m.shortcut_key
|
|
129
|
+
assert_equal [], m.shortcut_modifiers
|
|
130
|
+
|
|
131
|
+
m.shortcut = [:c, :command]
|
|
132
|
+
assert_equal 'c', m.shortcut_key
|
|
133
|
+
assert_equal [:command], m.shortcut_modifiers
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_shortcut_key_keeps_modifiers()
|
|
137
|
+
m = menu
|
|
138
|
+
m.shortcut = [:c, :command, :shift]
|
|
139
|
+
assert_equal 'c', m.shortcut_key
|
|
140
|
+
assert_equal %i[command shift].sort, m.shortcut_modifiers.sort
|
|
141
|
+
m.shortcut_key = :v
|
|
142
|
+
assert_equal 'v', m.shortcut_key
|
|
143
|
+
assert_equal %i[command shift].sort, m.shortcut_modifiers.sort
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_image()
|
|
147
|
+
m, img = menu, Reflex::Image.new(8, 8)
|
|
148
|
+
assert_nil m.image
|
|
149
|
+
m.image = img
|
|
150
|
+
assert_equal img, m.image
|
|
151
|
+
m.image = nil
|
|
152
|
+
assert_nil m.image
|
|
153
|
+
|
|
154
|
+
assert_raise(TypeError) {m.image = 1}
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def test_separator()
|
|
158
|
+
assert_false menu(:File).separator?
|
|
159
|
+
assert_true menu('-').separator?
|
|
160
|
+
assert_true menu('---').separator?
|
|
161
|
+
assert_false menu('').separator?
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def test_parent()
|
|
165
|
+
m = menu
|
|
166
|
+
c = m.add menu
|
|
167
|
+
assert_equal m, c.parent
|
|
168
|
+
assert_nil m.parent
|
|
169
|
+
m.remove c
|
|
170
|
+
assert_nil c.parent
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def test_children()
|
|
174
|
+
m = menu
|
|
175
|
+
c = m.add menu
|
|
176
|
+
assert_equal [c], m.children
|
|
177
|
+
assert_equal c, m.first
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_each_without_block()
|
|
181
|
+
m = menu
|
|
182
|
+
m.add menu(:A)
|
|
183
|
+
assert_kind_of Enumerator, m.each
|
|
184
|
+
assert_equal %w[A], m.each.map(&:label)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def test_nested()
|
|
188
|
+
root = menu
|
|
189
|
+
file = root.add menu(:File)
|
|
190
|
+
file.add menu(:Open)
|
|
191
|
+
assert_equal 'Open', root.first.first.label
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def test_event_hooks()
|
|
195
|
+
m = menu
|
|
196
|
+
fired = []
|
|
197
|
+
%i[click show hide open_submenu close_submenu].each {|ev| m.on(ev) {|e| fired << ev}}
|
|
198
|
+
e = Reflex::UpdateEvent.new 0, 0
|
|
199
|
+
m.on_click e
|
|
200
|
+
m.on_show e
|
|
201
|
+
m.on_hide e
|
|
202
|
+
m.on_open_submenu e
|
|
203
|
+
m.on_close_submenu e
|
|
204
|
+
assert_equal %i[click show hide open_submenu close_submenu], fired
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
end# TestMenu
|
data/test/test_pin.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestPin < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def pin(...)
|
|
7
|
+
Reflex::Pin.new(...)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view()
|
|
11
|
+
Reflex::View.new frame: [0, 0, 50, 50]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def point(*args)
|
|
15
|
+
Reflex::Point.new(*args)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_initialize()
|
|
19
|
+
v = view
|
|
20
|
+
assert_nil pin .view
|
|
21
|
+
assert_nil pin .pos
|
|
22
|
+
assert_nil pin( 1) .view
|
|
23
|
+
assert_equal point(1, 1), pin( 1) .pos
|
|
24
|
+
assert_nil pin( 2, 3) .view
|
|
25
|
+
assert_equal point(2, 3), pin( 2, 3) .pos
|
|
26
|
+
assert_equal v, pin(v) .view
|
|
27
|
+
assert_nil pin(v) .pos
|
|
28
|
+
assert_equal v, pin(v, 4, 5) .view
|
|
29
|
+
assert_equal point(4, 5), pin(v, 4, 5) .pos
|
|
30
|
+
assert_equal v, pin(v, [6, 7]).view
|
|
31
|
+
assert_equal point(6, 7), pin(v, [6, 7]).pos
|
|
32
|
+
assert_equal v, pin(v, point(8, 9)).view
|
|
33
|
+
assert_equal point(8, 9), pin(v, point(8, 9)).pos
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_dup()
|
|
37
|
+
v = view
|
|
38
|
+
assert_nil pin .dup.view
|
|
39
|
+
assert_nil pin .dup.pos
|
|
40
|
+
assert_nil pin( 1, 2).dup.view
|
|
41
|
+
assert_equal point(1, 2), pin( 1, 2).dup.pos
|
|
42
|
+
assert_equal v, pin(v, 3, 4).dup.view
|
|
43
|
+
assert_equal point(3, 4), pin(v, 3, 4).dup.pos
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_pin()
|
|
47
|
+
v = view
|
|
48
|
+
assert_instance_of Reflex::Pin, v.pin
|
|
49
|
+
|
|
50
|
+
assert_equal v, v.pin .view
|
|
51
|
+
assert_nil v.pin .pos
|
|
52
|
+
assert_equal v, v.pin( 1) .view
|
|
53
|
+
assert_equal point(1, 1), v.pin( 1) .pos
|
|
54
|
+
assert_equal v, v.pin( 2, 3) .view
|
|
55
|
+
assert_equal point(2, 3), v.pin( 2, 3) .pos
|
|
56
|
+
assert_equal v, v.pin( [4, 5]).view
|
|
57
|
+
assert_equal point(4, 5), v.pin( [4, 5]).pos
|
|
58
|
+
assert_equal v, v.pin(point(6, 7)).view
|
|
59
|
+
assert_equal point(6, 7), v.pin(point(6, 7)).pos
|
|
60
|
+
|
|
61
|
+
assert_raise(TypeError) {v.pin view}
|
|
62
|
+
assert_raise(TypeError) {v.pin "invalid"}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end# TestPin
|
data/test/test_pointer.rb
CHANGED
|
@@ -15,8 +15,10 @@ class TestPointer < Test::Unit::TestCase
|
|
|
15
15
|
DOWN = Reflex::Pointer::DOWN
|
|
16
16
|
UP = Reflex::Pointer::UP
|
|
17
17
|
MOVE = Reflex::Pointer::MOVE
|
|
18
|
-
STAY = Reflex::Pointer::STAY
|
|
19
18
|
CANCEL = Reflex::Pointer::CANCEL
|
|
19
|
+
ENTER = Reflex::Pointer::ENTER
|
|
20
|
+
LEAVE = Reflex::Pointer::LEAVE
|
|
21
|
+
STAY = Reflex::Pointer::STAY
|
|
20
22
|
|
|
21
23
|
T = true
|
|
22
24
|
F = false
|
|
@@ -44,7 +46,7 @@ class TestPointer < Test::Unit::TestCase
|
|
|
44
46
|
assert_equal [2, 3], p.position.to_a
|
|
45
47
|
assert_equal 2, p.x
|
|
46
48
|
assert_equal 3, p.y
|
|
47
|
-
assert_equal
|
|
49
|
+
assert_equal [:shift], p.modifiers
|
|
48
50
|
assert_equal 5, p.click_count
|
|
49
51
|
assert_equal true, p.drag?
|
|
50
52
|
assert_equal 6, p.time
|
|
@@ -99,28 +101,34 @@ class TestPointer < Test::Unit::TestCase
|
|
|
99
101
|
def action(a)
|
|
100
102
|
pointer(action: a).tap do |o|
|
|
101
103
|
def o.test()
|
|
102
|
-
[action, down?, up?, move?, cancel?, stay?]
|
|
104
|
+
[action, down?, up?, move?, cancel?, enter?, leave?, stay?]
|
|
103
105
|
end
|
|
104
106
|
end
|
|
105
107
|
end
|
|
106
108
|
|
|
107
109
|
o = action ACTION_NONE
|
|
108
|
-
assert_equal [:none, F, F, F, F, F], o.test
|
|
110
|
+
assert_equal [:none, F, F, F, F, F, F, F], o.test
|
|
109
111
|
|
|
110
112
|
o = action DOWN
|
|
111
|
-
assert_equal [:down, T, F, F, F, F], o.test
|
|
113
|
+
assert_equal [:down, T, F, F, F, F, F, F], o.test
|
|
112
114
|
|
|
113
115
|
o = action UP
|
|
114
|
-
assert_equal [:up, F, T, F, F, F], o.test
|
|
116
|
+
assert_equal [:up, F, T, F, F, F, F, F], o.test
|
|
115
117
|
|
|
116
118
|
o = action MOVE
|
|
117
|
-
assert_equal [:move, F, F, T, F, F], o.test
|
|
119
|
+
assert_equal [:move, F, F, T, F, F, F, F], o.test
|
|
118
120
|
|
|
119
121
|
o = action CANCEL
|
|
120
|
-
assert_equal [:cancel, F, F, F, T, F], o.test
|
|
122
|
+
assert_equal [:cancel, F, F, F, T, F, F, F], o.test
|
|
123
|
+
|
|
124
|
+
o = action ENTER
|
|
125
|
+
assert_equal [:enter, F, F, F, F, T, F, F], o.test
|
|
126
|
+
|
|
127
|
+
o = action LEAVE
|
|
128
|
+
assert_equal [:leave, F, F, F, F, F, T, F], o.test
|
|
121
129
|
|
|
122
130
|
o = action STAY
|
|
123
|
-
assert_equal [:stay, F, F, F, F, T], o.test
|
|
131
|
+
assert_equal [:stay, F, F, F, F, F, F, T], o.test
|
|
124
132
|
end
|
|
125
133
|
|
|
126
134
|
def test_position()
|
|
@@ -133,6 +141,12 @@ class TestPointer < Test::Unit::TestCase
|
|
|
133
141
|
assert_equal 2, pointer(position: [1, 2]).y
|
|
134
142
|
end
|
|
135
143
|
|
|
144
|
+
def test_modifiers()
|
|
145
|
+
p = pointer modifiers: Reflex::MOD_SHIFT | Reflex::MOD_NUMPAD
|
|
146
|
+
assert_equal [:shift, :numpad], p.modifiers
|
|
147
|
+
assert_equal [:shift], p.modifiers(locks: false)
|
|
148
|
+
end
|
|
149
|
+
|
|
136
150
|
def test_down()
|
|
137
151
|
assert_equal 1, pointer(id: 1, action: DOWN).down.id # DOWN pointer's down() returns itself
|
|
138
152
|
assert_nil pointer(id: 2, action: UP) .down
|
data/test/test_pointer_event.rb
CHANGED
|
@@ -50,7 +50,7 @@ class TestPointerEvent < Test::Unit::TestCase
|
|
|
50
50
|
assert_equal [2, 3], e.pos .to_a
|
|
51
51
|
assert_equal 2, e.x
|
|
52
52
|
assert_equal 3, e.y
|
|
53
|
-
assert_equal
|
|
53
|
+
assert_equal [:shift], e.modifiers
|
|
54
54
|
assert_equal 5, e.click_count
|
|
55
55
|
assert_equal true, e.drag?
|
|
56
56
|
assert_equal 6, e.time
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
require_relative 'helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class TestSnapConstraint < Test::Unit::TestCase
|
|
5
|
+
|
|
6
|
+
def window()
|
|
7
|
+
Reflex::Window.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
|
|
11
|
+
Reflex::View.new(
|
|
12
|
+
frame: [x, y, w, h],
|
|
13
|
+
shape: Reflex::RectShape.new(density: 1),
|
|
14
|
+
**options, &block)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def point(...)
|
|
18
|
+
Reflex::Point.new(...)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def setup_views(win = window)
|
|
22
|
+
v1 = view 100, 100, dynamic: true
|
|
23
|
+
v2 = view 200, 100, static: true
|
|
24
|
+
win&.add v1
|
|
25
|
+
win&.add v2
|
|
26
|
+
[v1, v2, win, win&.root]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_initial_state()
|
|
30
|
+
v1, v2, = setup_views
|
|
31
|
+
|
|
32
|
+
assert_equal v1, v1.snap(v2) .pins[0].view
|
|
33
|
+
assert_equal v2, v1.snap(v2) .pins[1].view
|
|
34
|
+
assert_nil v1.snap(v2) .angle
|
|
35
|
+
assert_equal 1..1, v1.snap(v2, angle: 1) .angle
|
|
36
|
+
assert_equal 2..3, v1.snap(v2, angle: 2..3) .angle
|
|
37
|
+
assert_nil v1.snap(v2) .motor
|
|
38
|
+
assert_equal 4, v1.snap(v2, motor: 4) .motor
|
|
39
|
+
assert_nil v1.snap(v2) .force
|
|
40
|
+
assert_equal 6, v1.snap(v2, force: 6) .force
|
|
41
|
+
assert_nil v1.snap(v2) .spring
|
|
42
|
+
assert_equal 5, v1.snap(v2, spring: 5) .spring
|
|
43
|
+
assert_in_delta 0.7, v1.snap(v2) .damping
|
|
44
|
+
assert_in_delta 0.1, v1.snap(v2, damping: 0.1).damping
|
|
45
|
+
assert_false v1.snap(v2) .collide?
|
|
46
|
+
assert_true v1.snap(v2) .active?
|
|
47
|
+
assert_false v1.snap(v2) .removed?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_snap_keeps_positions()
|
|
51
|
+
v1, v2, _, root = setup_views
|
|
52
|
+
v1.angle = 45
|
|
53
|
+
|
|
54
|
+
v1.snap v2 # nothing moves
|
|
55
|
+
|
|
56
|
+
10.times {root.update_world}
|
|
57
|
+
assert_equal_point point(0), v1.linear_velocity
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_snap_pulls_together()
|
|
61
|
+
v1, v2, _, root = setup_views
|
|
62
|
+
|
|
63
|
+
v1.pin(25, 25).snap v2.pin(25, 25), angle: 0, spring: 4
|
|
64
|
+
|
|
65
|
+
root.update_world
|
|
66
|
+
assert_operator v1.linear_velocity.x, :>, 0
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_snap_to_world()
|
|
70
|
+
v1, _, _, root = setup_views
|
|
71
|
+
root.gravity 0, 900
|
|
72
|
+
|
|
73
|
+
c = v1.snap
|
|
74
|
+
assert_nil c.pins[1].view
|
|
75
|
+
|
|
76
|
+
60.times {root.update_world}
|
|
77
|
+
assert_in_delta 100, v1.frame.y, 0.01 # hangs against gravity
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_weld_fixes_angle()
|
|
81
|
+
v1, v2, _, root = setup_views
|
|
82
|
+
|
|
83
|
+
v1.snap v2, angle: 0 # welds and fixes the angle
|
|
84
|
+
v1.angular_velocity = 90
|
|
85
|
+
|
|
86
|
+
10.times {root.update_world}
|
|
87
|
+
assert_in_delta 0, v1.angular_velocity
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_angle()
|
|
91
|
+
v1, v2, = setup_views
|
|
92
|
+
|
|
93
|
+
c = v1.snap v2, angle: -30..90
|
|
94
|
+
assert_equal(-30..90, c.angle)
|
|
95
|
+
|
|
96
|
+
c.angle = 0
|
|
97
|
+
assert_equal 0..0, c.angle
|
|
98
|
+
|
|
99
|
+
c.angle = nil
|
|
100
|
+
assert_nil c.angle
|
|
101
|
+
|
|
102
|
+
assert_raise(ArgumentError) {c.angle = 'invalid'}
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_motor()
|
|
106
|
+
v1, v2, _, root = setup_views
|
|
107
|
+
|
|
108
|
+
c = v1.snap v2, motor: 90
|
|
109
|
+
assert_equal 90, c.motor
|
|
110
|
+
|
|
111
|
+
3.times {root.update_world}
|
|
112
|
+
assert_in_delta 90, v1.angular_velocity
|
|
113
|
+
|
|
114
|
+
c.motor = nil
|
|
115
|
+
assert_nil c.motor
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_force()
|
|
119
|
+
v1, v2, = setup_views
|
|
120
|
+
|
|
121
|
+
c = v1.snap v2, motor: 90, force: 500
|
|
122
|
+
assert_equal 500, c.force
|
|
123
|
+
|
|
124
|
+
c.force = nil
|
|
125
|
+
assert_nil c.force
|
|
126
|
+
|
|
127
|
+
c.force = 100
|
|
128
|
+
assert_equal 100, c.force
|
|
129
|
+
|
|
130
|
+
assert_raise(ArgumentError) {c.force = -1}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def test_force_limits_the_motor()
|
|
134
|
+
v1, v2, _, root = setup_views
|
|
135
|
+
|
|
136
|
+
v1.snap v2, motor: 90, force: 0 # a powerless motor can not spin
|
|
137
|
+
|
|
138
|
+
3.times {root.update_world}
|
|
139
|
+
assert_in_delta 0, v1.angular_velocity
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end# TestSnapConstraint
|
data/test/test_view.rb
CHANGED
|
@@ -85,12 +85,36 @@ class TestView < Test::Unit::TestCase
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
def test_add_child()
|
|
88
|
+
view.tap do |v|
|
|
89
|
+
v.add view(name: :a)
|
|
90
|
+
v.add view(name: :b)
|
|
91
|
+
v.add view(name: :c), index: 1
|
|
92
|
+
assert_equal %w[a c b], v.children.map(&:name)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
view.tap do |v|
|
|
96
|
+
v.add view(name: :a)
|
|
97
|
+
v.add view(name: :b), index: 0
|
|
98
|
+
v.add view(name: :c), index: v.children.to_a.size
|
|
99
|
+
assert_equal %w[b a c], v.children.map(&:name)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
view.tap do |v|
|
|
103
|
+
v.add view(name: :a)
|
|
104
|
+
v.add view(name: :b), index: 99
|
|
105
|
+
v.add view(name: :c), index: -1
|
|
106
|
+
v.add view(name: :d), index: nil
|
|
107
|
+
assert_equal %w[a b c d], v.children.map(&:name)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
view.tap do |v|
|
|
111
|
+
assert_nothing_raised {v.add_child view}
|
|
112
|
+
assert_raise(ArgumentError) {v.add_child v}
|
|
113
|
+
end
|
|
114
|
+
|
|
88
115
|
assert_raise(ArgumentError) {view.add_child}
|
|
89
|
-
assert_raise(TypeError)
|
|
90
|
-
assert_raise(TypeError)
|
|
91
|
-
v = view
|
|
92
|
-
assert_raise(ArgumentError) {v.add_child v}
|
|
93
|
-
assert_nothing_raised {v.add_child view}
|
|
116
|
+
assert_raise(TypeError) {view.add_child nil}
|
|
117
|
+
assert_raise(TypeError) {view.add_child 1}
|
|
94
118
|
end
|
|
95
119
|
|
|
96
120
|
def test_remove_child()
|
|
@@ -144,6 +168,18 @@ class TestView < Test::Unit::TestCase
|
|
|
144
168
|
assert_not_includes v.find_styles(selector name: :N), s
|
|
145
169
|
end
|
|
146
170
|
|
|
171
|
+
def test_find_styles()
|
|
172
|
+
v, s = view, style(name: :N1, tag: :T1)
|
|
173
|
+
s.add_tag :T2
|
|
174
|
+
v.add_style s
|
|
175
|
+
|
|
176
|
+
assert_includes v.find_styles(:N1), s
|
|
177
|
+
assert_includes v.find_styles(selector tag: :T1), s
|
|
178
|
+
assert_includes v.find_styles(selector tags: [:T1, :T2]), s
|
|
179
|
+
assert_empty v.find_styles(selector tags: [:T1, :X])
|
|
180
|
+
assert_empty v.find_styles(selector tag: :X)
|
|
181
|
+
end
|
|
182
|
+
|
|
147
183
|
def test_shape()
|
|
148
184
|
s = shape
|
|
149
185
|
assert_equal 0, s.density
|
|
@@ -194,26 +230,80 @@ class TestView < Test::Unit::TestCase
|
|
|
194
230
|
end
|
|
195
231
|
|
|
196
232
|
def test_add_remove_shape()
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
233
|
+
view.tap do |v|
|
|
234
|
+
s = shape name: :S
|
|
235
|
+
s.density = 1
|
|
236
|
+
assert_equal 1, s.density
|
|
237
|
+
|
|
238
|
+
assert_equal 0, v.shapes.to_a.size
|
|
239
|
+
|
|
240
|
+
v.add_shape s
|
|
241
|
+
assert_equal 1, v.shapes.to_a.size
|
|
242
|
+
assert_includes v.find_shapes(selector name: :S), s
|
|
243
|
+
assert_equal 1, v.find_shapes(selector name: :S).first.density
|
|
244
|
+
|
|
245
|
+
v.remove_shape s
|
|
246
|
+
assert_equal 0, v.shapes.to_a.size
|
|
247
|
+
assert_not_includes v.find_shapes(selector name: :S), s
|
|
248
|
+
|
|
249
|
+
v.add_shape s
|
|
250
|
+
assert_equal 1, v.shapes.to_a.size
|
|
251
|
+
v.clear_shapes
|
|
252
|
+
assert_equal 0, v.shapes.to_a.size
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
view.tap do |v|
|
|
256
|
+
v.add_shape shape(name: :a)
|
|
257
|
+
v.add_shape shape(name: :b)
|
|
258
|
+
v.add_shape shape(name: :c), index: 1
|
|
259
|
+
assert_equal %w[a c b], v.shapes.map(&:name)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
view.tap do |v|
|
|
263
|
+
v.add_shape shape(name: :a)
|
|
264
|
+
v.add_shape shape(name: :b), index: 0
|
|
265
|
+
v.add_shape shape(name: :c), index: v.shapes.to_a.size
|
|
266
|
+
assert_equal %w[b a c], v.shapes.map(&:name)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
view.tap do |v|
|
|
270
|
+
v.add_shape shape(name: :a)
|
|
271
|
+
v.add_shape shape(name: :b), index: 99
|
|
272
|
+
v.add_shape shape(name: :c), index: -1
|
|
273
|
+
v.add_shape shape(name: :d), index: nil
|
|
274
|
+
assert_equal %w[a b c d], v.shapes.map(&:name)
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def test_find_shapes()
|
|
279
|
+
v, s = view, shape(name: :N1, tag: :T1)
|
|
280
|
+
s.add_tag :T2
|
|
204
281
|
v.add_shape s
|
|
205
|
-
assert_equal 1, v.shapes.to_a.size
|
|
206
|
-
assert_includes v.find_shapes(selector name: :S), s
|
|
207
|
-
assert_equal 1, v.find_shapes(selector name: :S).first.density
|
|
208
|
-
|
|
209
|
-
v.remove_shape s
|
|
210
|
-
assert_equal 0, v.shapes.to_a.size
|
|
211
|
-
assert_not_includes v.find_shapes(selector name: :S), s
|
|
212
282
|
|
|
213
|
-
v.
|
|
214
|
-
|
|
215
|
-
v.
|
|
216
|
-
|
|
283
|
+
assert_includes v.find_shapes(:N1), s
|
|
284
|
+
assert_includes v.find_shapes(selector tag: :T1), s
|
|
285
|
+
assert_includes v.find_shapes(selector tags: [:T1, :T2]), s
|
|
286
|
+
assert_empty v.find_shapes(selector tags: [:T1, :X])
|
|
287
|
+
assert_empty v.find_shapes(selector tag: :X)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def test_find_constraints()
|
|
291
|
+
win = window
|
|
292
|
+
v1 = view frame: [100, 100, 50, 50], shape: shape(density: 1), dynamic: true
|
|
293
|
+
v2 = view frame: [200, 100, 50, 50], shape: shape(density: 1), static: true
|
|
294
|
+
win.add v1
|
|
295
|
+
win.add v2
|
|
296
|
+
|
|
297
|
+
c = v1.link v2, name: :N1, tag: :T1
|
|
298
|
+
c.add_tag :T2
|
|
299
|
+
|
|
300
|
+
[v1, v2].each do |v|
|
|
301
|
+
assert_includes v.find_constraints(:N1), c
|
|
302
|
+
assert_includes v.find_constraints(selector tag: :T1), c
|
|
303
|
+
assert_includes v.find_constraints(selector tags: [:T1, :T2]), c
|
|
304
|
+
assert_empty v.find_constraints(selector tags: [:T2, :X])
|
|
305
|
+
assert_empty v.find_constraints(selector tags: [:X])
|
|
306
|
+
end
|
|
217
307
|
end
|
|
218
308
|
|
|
219
309
|
def test_name()
|