hokusai-zero 0.2.6.pre.pinephone6 → 0.2.6

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/README.md +1 -1
  5. data/ast/src/core/input.h +1 -0
  6. data/ast/src/core/util.c +23 -23
  7. data/ast/src/core/util.h +7 -7
  8. data/ext/extconf.rb +3 -3
  9. data/hokusai.gemspec +2 -1
  10. data/ui/examples/counter.rb +1 -2
  11. data/ui/examples/forum/file.rb +1 -1
  12. data/ui/examples/forum/post.rb +1 -0
  13. data/ui/examples/forum.rb +7 -7
  14. data/ui/examples/spreadsheet.rb +0 -1
  15. data/ui/examples/tic_tac_toe.rb +6 -6
  16. data/ui/lib/lib_hokusai.rb +24 -25
  17. data/ui/spec/spec_helper.rb +1 -1
  18. data/ui/src/hokusai/assets/chevron-down.svg +1 -0
  19. data/ui/src/hokusai/automation/driver_commands/base.rb +8 -2
  20. data/ui/src/hokusai/automation/driver_commands/trigger_keyboard.rb +6 -3
  21. data/ui/src/hokusai/automation/driver_commands/trigger_mouse.rb +5 -12
  22. data/ui/src/hokusai/automation/server.rb +3 -2
  23. data/ui/src/hokusai/backends/raylib/config.rb +1 -2
  24. data/ui/src/hokusai/backends/raylib/font.rb +3 -24
  25. data/ui/src/hokusai/backends/raylib.rb +36 -167
  26. data/ui/src/hokusai/backends/sdl2/config.rb +6 -9
  27. data/ui/src/hokusai/backends/sdl2/font.rb +1 -3
  28. data/ui/src/hokusai/backends/sdl2.rb +93 -188
  29. data/ui/src/hokusai/blocks/input.rb +2 -2
  30. data/ui/src/hokusai/commands/rect.rb +3 -12
  31. data/ui/src/hokusai/commands.rb +0 -22
  32. data/ui/src/hokusai/event.rb +1 -2
  33. data/ui/src/hokusai/events/keyboard.rb +18 -11
  34. data/ui/src/hokusai/events/mouse.rb +8 -10
  35. data/ui/src/hokusai/mounting/loop_entry.rb +1 -1
  36. data/ui/src/hokusai/painter.rb +8 -31
  37. data/ui/src/hokusai/types.rb +244 -20
  38. data/ui/src/hokusai.rb +35 -61
  39. data/xmake.lua +1 -1
  40. metadata +22 -32
  41. data/ui/examples/drag.rb +0 -154
  42. data/ui/examples/embedded.rb +0 -58
  43. data/ui/examples/game.rb +0 -143
  44. data/ui/examples/keyboard.rb +0 -47
  45. data/ui/examples/overlay.rb +0 -233
  46. data/ui/examples/provider.rb +0 -56
  47. data/ui/examples/shader/test.rb +0 -155
  48. data/ui/examples/shader.rb +0 -100
  49. data/ui/examples/wiki.rb +0 -82
  50. data/ui/spec/hokusai/e2e/keyboard_spec.rb +0 -52
  51. data/ui/src/hokusai/assets/arrow-down-line.png +0 -0
  52. data/ui/src/hokusai/assets/arrow-down-wide-line.png +0 -0
  53. data/ui/src/hokusai/assets/icons/outline/arrow-big-up.svg +0 -19
  54. data/ui/src/hokusai/assets/icons/outline/backspace.svg +0 -20
  55. data/ui/src/hokusai/blocks/color_picker.rb +0 -1080
  56. data/ui/src/hokusai/blocks/keyboard.rb +0 -249
  57. data/ui/src/hokusai/blocks/shader_begin.rb +0 -22
  58. data/ui/src/hokusai/blocks/shader_end.rb +0 -12
  59. data/ui/src/hokusai/blocks/slider.rb +0 -139
  60. data/ui/src/hokusai/blocks/texture.rb +0 -23
  61. data/ui/src/hokusai/commands/shader.rb +0 -33
  62. data/ui/src/hokusai/commands/texture.rb +0 -26
  63. data/ui/src/hokusai/events/touch.rb +0 -62
  64. data/ui/src/hokusai/types/display.rb +0 -151
  65. data/ui/src/hokusai/types/keyboard.rb +0 -168
  66. data/ui/src/hokusai/types/mouse.rb +0 -36
  67. data/ui/src/hokusai/types/primitives.rb +0 -56
  68. data/ui/src/hokusai/types/touch.rb +0 -181
  69. data/ui/src/hokusai/util/wrap_stream.rb +0 -193
@@ -1,151 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hokusai
4
- Outline = Struct.new(:top, :right, :bottom, :left) do
5
- def self.default
6
- new(0.0, 0.0, 0.0, 0.0)
7
- end
8
-
9
- def hash
10
- [self.class, top, right, bottom, left].hash
11
- end
12
-
13
- def self.convert(value)
14
- case value
15
- when String
16
- if value =~ /,/
17
- convert(value.split(",").map(&:to_f))
18
- else
19
- convert(value.to_f)
20
- end
21
- when Float
22
- new(value, value, value, value)
23
- when Array
24
- new(value[0] || 0.0, value[1] || 0.0, value[2] || 0.0, value[3] || 0.0)
25
- when Outline
26
- value
27
- end
28
- end
29
-
30
- def present?
31
- top > 0.0 || right > 0.0 || bottom > 0.0 || left > 0.0
32
- end
33
-
34
- def uniform?
35
- top == right && top == bottom && top == left
36
- end
37
- end
38
-
39
- class Padding
40
- attr_reader :top, :left, :right, :bottom
41
- def initialize(top, right, bottom, left)
42
- @top = top
43
- @left = left
44
- @right = right
45
- @bottom = bottom
46
- end
47
-
48
- alias_method :t, :top
49
- alias_method :l, :left
50
- alias_method :r, :right
51
- alias_method :b, :bottom
52
-
53
- def width
54
- right + left
55
- end
56
-
57
- def height
58
- top + bottom
59
- end
60
-
61
- def self.convert(value)
62
- case value
63
- when String
64
- if value =~ /,/
65
- convert(value.split(",").map(&:to_f))
66
- else
67
- convert(value.to_i)
68
- end
69
- when Integer
70
- new(value, value, value, value)
71
- when Array
72
- new(value[0], value[1], value[2], value[3])
73
- when Padding
74
- value
75
- else
76
- raise Hokusai::Error.new("Unsupported conversion type #{value.class} for Hokusai::Padding")
77
- end
78
- end
79
-
80
- def hash
81
- [self.class, top, right, bottom, left].hash
82
- end
83
- end
84
-
85
- class Canvas
86
- attr_accessor :width, :height, :x, :y, :vertical, :reverse
87
- def initialize(width, height, x = 0.0, y = 0.0, vertical = true, reverse = false)
88
- @width = width
89
- @height = height
90
- @x = x
91
- @y = y
92
- @vertical = vertical
93
- @reverse = reverse
94
- end
95
-
96
- def reset(x, y, width, height, vertical: true, reverse: false)
97
- self.x = x
98
- self.y = y
99
- self.width = width
100
- self.height = height
101
- self.vertical = vertical
102
- self.reverse = reverse
103
- end
104
-
105
- def to_bounds
106
- Hokusai::Rect.new(x, y, width, height)
107
- end
108
-
109
- def hovered?(input)
110
- input.hovered?(self)
111
- end
112
-
113
- def reverse?
114
- reverse
115
- end
116
- end
117
-
118
- # Color = Struct.new(:red, :green, :blue, :alpha) do
119
- class Color
120
- attr_reader :red, :green, :blue, :alpha
121
- def initialize(red, green, blue, alpha = 255)
122
- @red = red.freeze
123
- @green = green.freeze
124
- @blue = blue.freeze
125
- @alpha = alpha.freeze
126
- end
127
-
128
- alias_method :r, :red
129
- alias_method :b, :blue
130
- alias_method :g, :green
131
- alias_method :a, :alpha
132
-
133
- def self.convert(value)
134
- case value
135
- when String
136
- value = value.split(",").map(&:to_i)
137
- when Array
138
- when Color
139
- return value
140
- else
141
- raise Hokusai::Error.new("Unsupported conversion type #{value.class} for Hokusai::Color")
142
- end
143
-
144
- new(value[0], value[1], value[2], value[3] || 255)
145
- end
146
-
147
- def hash
148
- [self.class, r, g, b, a].hash
149
- end
150
- end
151
- end
@@ -1,168 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hokusai
4
- KEY_CODES = {
5
- null: 0, apostrophe: 39, comma: 44, minus: 45, period: 46,
6
- slash: 47, zero: 48, one: 49, two: 50, three: 51, four: 52,
7
- five: 53, six: 54, seven: 55, eight: 56, nine: 57, semicolon: 59,
8
- equal: 61, a: 65, b: 66, c: 67, d: 68, e: 69, f: 70, g: 71, h: 72,
9
- i: 73, j: 74, k: 75, l: 76, m: 77, n: 78, o: 79, p: 80, q: 81, r: 82,
10
- s: 83, t: 84, u: 85, v: 86, w: 87, x: 88, y: 89, z: 90, left_bracket: 91,
11
- backslash: 92, right_bracket: 93, grave: 96, space: 32, escape: 256,
12
- enter: 257, tab: 258, backspace: 259, insert: 260, delete: 261, right: 262,
13
- left: 263, down: 264, up: 265, page_up: 266, page_down: 267, home: 268, end: 269,
14
- caps_lock: 280, scroll_lock: 281, num_lock: 282, print_screen: 283, pause: 284,
15
- f1: 290, f2: 291, f3: 292, f4: 293, f5: 294, f6: 295, f7: 296, f8: 297,
16
- f9: 298, f10: 299, f11: 300, f12: 301, left_shift: 340, left_control: 341,
17
- left_alt: 342, left_super: 343, right_shift: 344, right_control: 345, right_alt: 346,
18
- right_super: 347, kb_menu: 348, kp_0: 320, kp_1: 321, kp_2: 322, kp_3: 323,
19
- kp_4: 324, kp_5: 325, kp_6: 326, kp_7: 327, kp_8: 328, kp_9: 329, kp_decimal: 330,
20
- kp_divide: 331, kp_multiply: 332, kp_subtract: 333, kp_add: 334, kp_enter: 335,
21
- kp_equal: 336, back: 4, menu: 5, volume_up: 24, volume_down: 25
22
- }
23
-
24
- class Keyboard
25
- attr_accessor :shift, :control, :super, :alt
26
- attr_reader :keys, :pressed, :released
27
-
28
- def initialize
29
- @shift = false
30
- @control = false
31
- @super = false
32
- @alt = false
33
-
34
- @keys = {}
35
- @pressed = []
36
- @released = []
37
-
38
- # populate the key states
39
- KEY_CODES.each do |symbol, code|
40
- @keys[symbol] = { code: code, symbol: symbol, up: false, down: false, pressed: false, released: false }
41
- end
42
- end
43
-
44
- def code
45
- pressed[0]&.[](:code)
46
- end
47
-
48
- def char
49
- pressed[0]&.[](:char)
50
- end
51
-
52
- def ctrl
53
- @control
54
- end
55
-
56
- def reset
57
- @pressed.clear
58
- @released.clear
59
-
60
- @shift = false
61
- @control = false
62
- @super = false
63
- @alt = false
64
- end
65
-
66
-
67
- def key_is_letter?(symbol)
68
- symbol == :a || symbol == :b || symbol == :c || symbol == :d ||
69
- symbol == :e || symbol == :f || symbol == :g || symbol == :h ||
70
- symbol == :i || symbol == :j || symbol == :k || symbol == :l ||
71
- symbol == :m || symbol == :n || symbol == :o || symbol == :p ||
72
- symbol == :q || symbol == :r || symbol == :s || symbol == :t ||
73
- symbol == :u || symbol == :v || symbol == :w || symbol == :x ||
74
- symbol == :y || symbol == :z
75
- end
76
-
77
- def char_code_from_key(key, shift)
78
- code = keys[key][:code]
79
-
80
- if !shift && key_is_letter?(key)
81
- code += 32
82
- elsif shift && key == :apostrophe
83
- code = 34
84
- elsif shift && key == :comma
85
- code = 60
86
- elsif shift && key == :minus
87
- code = 95
88
- elsif shift && key == :period
89
- code = 62
90
- elsif shift && key == :slash
91
- code = 63
92
- elsif shift && key == :zero
93
- code = 41
94
- elsif shift && key == :one
95
- code = 33
96
- elsif shift && key == :two
97
- code = 64
98
- elsif shift && key == :three
99
- code = 35
100
- elsif shift && key == :four
101
- code = 36
102
- elsif shift && key == :five
103
- code = 37
104
- elsif shift && key == :six
105
- code = 94
106
- elsif shift && key == :seven
107
- code = 38
108
- elsif shift && key == :eight
109
- code = 42
110
- elsif shift && key == :nine
111
- code = 40
112
- elsif shift && key == :semicolon
113
- code = 58
114
- elsif shift && key == :equal
115
- code = 43
116
- elsif shift && key == :left_bracket
117
- code = 123
118
- elsif shift && key == :backslash
119
- code = 124
120
- elsif shift && key == :right_bracket
121
- code = 125
122
- elsif shift && key == :grave
123
- code = 126
124
- end
125
-
126
- return code if code <= 256
127
- end
128
-
129
- def set(key, down)
130
- if down
131
- case key
132
- when :left_shift, :right_shift
133
- @shift = true
134
- when :left_control, :right_control
135
- @control = true
136
- when :left_super, :right_super
137
- @super = true
138
- when :left_alt, :right_alt
139
- @alt = true
140
- end
141
- end
142
-
143
- if down && keys[key][:up]
144
- keys[key][:pressed] = true
145
- keys[key][:released]= false
146
-
147
- nkey = keys[key].dup
148
- nkey.merge!({ char: char_code_from_key(key, shift)&.chr })
149
-
150
- pressed << nkey
151
- elsif !down && keys[key][:down]
152
- keys[key][:pressed] = false
153
- keys[key][:released] = true
154
-
155
- nkey = keys[key].dup
156
- nkey.merge!({ char: char_code_from_key(key, shift)&.chr })
157
-
158
- released << nkey
159
- else
160
- keys[key][:pressed] = false
161
- keys[key][:released] = false
162
- end
163
-
164
- keys[key][:down] = down
165
- keys[key][:up] = !down
166
- end
167
- end
168
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hokusai
4
- class MouseButton
5
- attr_accessor :up, :down, :clicked, :released
6
-
7
- def initialize
8
- @up = false
9
- @down = false
10
- @clicked = false
11
- @released = false
12
- end
13
- end
14
-
15
- class Mouse
16
- attr_reader :pos, :delta, :left, :right, :middle, :scroll
17
- attr_accessor :scroll_delta
18
-
19
- def initialize
20
- @pos = Vec2.new(0.0, 0.0)
21
- @delta = Vec2.new(0.0, 0.0)
22
- @scroll = 0.0
23
- @scroll_delta = 0.0
24
- @left = MouseButton.new
25
- @middle = MouseButton.new
26
- @right = MouseButton.new
27
- end
28
-
29
- def scroll=(val)
30
- last = scroll
31
- new_y = (last >= val) ? last - val : val - last
32
- self.scroll_delta = new_y
33
- @scroll = val
34
- end
35
- end
36
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hokusai
4
- class Vec2
5
- attr_accessor :x, :y
6
- def initialize(x, y)
7
- @x = x
8
- @y = y
9
- end
10
- end
11
-
12
- class Rect
13
- attr_accessor :x, :y, :width, :height
14
-
15
- def initialize(x, y, width, height)
16
- @x = x
17
- @y = y
18
- @width = width
19
- @height = height
20
- end
21
- def to_hoku_rect
22
- @hoku_rect ||= LibHokusai::HmlRect.create(x, y, width, height)
23
- end
24
-
25
- def includes_y?(y)
26
- LibHokusai.hoku_rect_includes_y(to_hoku_rect, y)
27
- end
28
-
29
- def includes_x?(x)
30
- LibHokusai.hoku_rect_includes_x(to_hoku_rect, x)
31
- end
32
-
33
- def move_x_left(times = 1)
34
- LibHokusai.hoku_rect_x_left(to_hoku_rect, times)
35
- end
36
-
37
- def move_x_right(times = 1)
38
- LibHokusai.hoku_rect_x_right(to_hoku_rect, times)
39
- end
40
-
41
- def move_y_up(times = 1)
42
- LibHokusai.hoku_rect_y_up(to_hoku_rect, times)
43
- end
44
-
45
- def move_y_down(times = 1)
46
- LibHokusai.hoku_rect_y_down(to_hoku_rect, times)
47
- end
48
-
49
- def self.from_hoku_rect(rect)
50
- self.x = rect[:x]
51
- self.y = rect[:y]
52
- self.width = rect[:w]
53
- self.height = rect[:h]
54
- end
55
- end
56
- end
@@ -1,181 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Hokusai
4
- class Touch
5
- attr_accessor :stack, :archive
6
-
7
- def initialize
8
- @stack = []
9
- @archive = []
10
- @tapped = false
11
- @swiped = false
12
- @pinched = false
13
- # @file = File.open("touch.log", "w")
14
- end
15
-
16
- def tapped?
17
- @tapped
18
- end
19
-
20
- def swiped?
21
- @swiped
22
- end
23
-
24
- def pinched?
25
- @pinched
26
- end
27
-
28
- def longtapping?(stuff = "ok")
29
- log("#{touching?} - #{elapsed(token)} - #{stuff}") if touching?
30
- touching? && elapsed(token) > 5
31
- end
32
-
33
- def longtapped?
34
- @longtapped
35
- end
36
-
37
- def touching?
38
- type == :down || type == :move
39
- end
40
-
41
- def duration
42
- if longtapping?
43
- return elapsed(token)
44
- end
45
-
46
- first, last = archive[-2..-1]
47
-
48
- last[:start] - first[:start]
49
- end
50
-
51
- def distance
52
- raise Hokusai::Error.new("Archive is empty") if archive.empty?
53
- first, last = archive[-2..-1]
54
-
55
- x = last[:x] - first[:x]
56
- y = last[:y] - first[:y]
57
-
58
- [x, y]
59
- end
60
-
61
- def direction
62
- raise Hokusai::Error.new("Archive is empty") if archive.empty?
63
-
64
- first, last = archive[-2..-1]
65
-
66
- x = last[:x] - first[:x]
67
- y = last[:y] - first[:y]
68
-
69
- if x.abs > y.abs
70
- # swiping left/right
71
- last[:x] > first[:x] ? :right : :left
72
- else
73
- # swiping up/down
74
- last[:y] > first[:y] ? :down : :up
75
- end
76
- end
77
-
78
- def angle
79
- raise Hokusai::Error.new("Archive is empty") if archive.empty?
80
-
81
- last, first = archive[-2..-1]
82
-
83
- x = last[:x] - first[:x]
84
- y = last[:y] - first[:y]
85
-
86
- (Math.atan2(x, y) * (-180 / Math::PI)).round(0).to_i
87
- end
88
-
89
- def log(str)
90
- # Thread.new do
91
- # @file.write_nonblock("#{str}\n")
92
- # end
93
- end
94
-
95
- def record(finger, x, y)
96
- log("recording #{token}")
97
- if type == :down
98
- push(:move, finger, x, y)
99
- log("state is move")
100
- elsif type == :move
101
- stack.last[:x] = x
102
- stack.last[:y] = y
103
-
104
- log("updated state move")
105
- else
106
- @longtapped = false
107
- @swiped = false
108
- @tapped = false
109
- push(:down, finger, x, y)
110
- log("state is down")
111
- end
112
- end
113
-
114
- def clear
115
- # log("clearing")
116
- if type == :move
117
- log("elapsed: #{elapsed(token)}")
118
- if elapsed(token) > 300 && within(10.0)
119
- @longtapped = true
120
- log('longtap')
121
- elsif within(10.0)
122
- @tapped = true
123
- else
124
- @swiped = true
125
- log('swipe')
126
- end
127
- elsif type == :down
128
- @tapped = true
129
- log('tap')
130
- else
131
- @longtapped = false
132
- @swiped = false
133
- @tapped = false
134
- end
135
-
136
- self.archive = stack.dup
137
- stack.clear
138
- end
139
-
140
- def elapsed(token)
141
- Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) - token[:start]
142
- end
143
-
144
- def within(threshold)
145
- move = stack.last
146
- down = stack[-2]
147
-
148
- t1 = (move[:x] - down[:x]).abs
149
- t2 = (move[:y] - down[:y]).abs
150
-
151
- t1 < threshold && t2 < threshold
152
- end
153
-
154
- def pop
155
- stack.pop
156
- end
157
-
158
- def push(type, finger, x, y)
159
- log("push: #{type}")
160
- stack << {
161
- type: type,
162
- i: finger,
163
- x: x,
164
- y: y,
165
- start: Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
166
- }
167
- end
168
-
169
- def index
170
- token&.[](:finger)
171
- end
172
-
173
- def type
174
- token&.[](:type)
175
- end
176
-
177
- def token
178
- @stack.last
179
- end
180
- end
181
- end