hokusai-zero 0.2.6.pre.pinephone → 0.2.6.pre.pinephone3
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/ast/src/core/input.c +0 -85
- data/ast/src/core/input.h +0 -32
- data/hokusai.gemspec +1 -1
- data/ui/examples/embedded.rb +0 -1
- data/ui/examples/forum/file.rb +1 -1
- data/ui/examples/forum/post.rb +0 -1
- data/ui/examples/forum.rb +7 -7
- data/ui/examples/keyboard.rb +47 -0
- data/ui/examples/shader/test.rb +28 -18
- data/ui/examples/spreadsheet.rb +12 -11
- data/ui/lib/lib_hokusai.rb +19 -39
- data/ui/spec/hokusai/e2e/keyboard_spec.rb +52 -0
- data/ui/src/hokusai/assets/icons/outline/arrow-big-up.svg +19 -0
- data/ui/src/hokusai/assets/icons/outline/backspace.svg +20 -0
- data/ui/src/hokusai/backends/raylib.rb +7 -5
- data/ui/src/hokusai/backends/sdl2/config.rb +9 -6
- data/ui/src/hokusai/backends/sdl2/font.rb +3 -1
- data/ui/src/hokusai/backends/sdl2.rb +164 -65
- data/ui/src/hokusai/blocks/input.rb +1 -1
- data/ui/src/hokusai/blocks/keyboard.rb +234 -0
- data/ui/src/hokusai/blocks/slider.rb +139 -0
- data/ui/src/hokusai/commands/rect.rb +2 -2
- data/ui/src/hokusai/event.rb +1 -1
- data/ui/src/hokusai/events/{embedded.rb → touch.rb} +12 -18
- data/ui/src/hokusai/painter.rb +5 -5
- data/ui/src/hokusai/types.rb +180 -17
- data/ui/src/hokusai/util/wrap_stream.rb +197 -0
- data/ui/src/hokusai.rb +61 -30
- data/xmake.lua +1 -1
- metadata +9 -6
- data/ui/src/hokusai/backends/embedded/config.rb +0 -47
- data/ui/src/hokusai/backends/embedded/font.rb +0 -112
- data/ui/src/hokusai/backends/embedded/keys.rb +0 -124
- data/ui/src/hokusai/backends/embedded.rb +0 -564
@@ -16,8 +16,7 @@ module Hokusai::Backends
|
|
16
16
|
yield(config)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
backend.run(block)
|
19
|
+
backend.run(app)
|
21
20
|
end
|
22
21
|
|
23
22
|
def self.cursors
|
@@ -30,6 +29,17 @@ module Hokusai::Backends
|
|
30
29
|
}
|
31
30
|
end
|
32
31
|
|
32
|
+
def hml_vec2(x, y)
|
33
|
+
if @hml_vec2.nil?
|
34
|
+
@hml_vec2 = LibHokusai::HmlVec2.create(x, y)
|
35
|
+
else
|
36
|
+
@hml_vec2[:x] = x
|
37
|
+
@hml_vec2[:y] = y
|
38
|
+
end
|
39
|
+
|
40
|
+
@hml_vec2
|
41
|
+
end
|
42
|
+
|
33
43
|
def self.stopped
|
34
44
|
@stopped ||= false
|
35
45
|
end
|
@@ -56,7 +66,19 @@ module Hokusai::Backends
|
|
56
66
|
yield @config
|
57
67
|
end
|
58
68
|
|
59
|
-
def
|
69
|
+
def get_size(window)
|
70
|
+
w = FFI::MemoryPointer.new :int
|
71
|
+
h = FFI::MemoryPointer.new :int
|
72
|
+
|
73
|
+
SDL.GL_GetDrawableSize(window, w, h)
|
74
|
+
|
75
|
+
res = { width: w.read_int, height: h.read_int }
|
76
|
+
w.free
|
77
|
+
h.free
|
78
|
+
res
|
79
|
+
end
|
80
|
+
|
81
|
+
def run(app)
|
60
82
|
resize = true
|
61
83
|
self.render_width = config.width
|
62
84
|
self.render_height = config.height
|
@@ -80,6 +102,7 @@ module Hokusai::Backends
|
|
80
102
|
image_libpath: "#{SDL_PATH}/libSDL2_image.so"
|
81
103
|
)
|
82
104
|
end
|
105
|
+
|
83
106
|
SDL.Init(config.init_flags)
|
84
107
|
SDL.TTF_Init
|
85
108
|
|
@@ -87,43 +110,73 @@ module Hokusai::Backends
|
|
87
110
|
SDL.SetWindowPosition(window, SDL::WINDOWPOS_CENTERED_MASK, SDL::WINDOWPOS_CENTERED_MASK)
|
88
111
|
renderer = SDL.CreateRenderer(window, -1, SDL::RENDERER_TARGETTEXTURE | SDL::RENDERER_ACCELERATED)
|
89
112
|
|
113
|
+
size = get_size(window)
|
114
|
+
SDL.RenderSetScale(renderer, size[:width] / render_width, size[:height] / render_height);
|
115
|
+
|
90
116
|
Hokusai.fonts.register "default", SDLBackend::Font.from("#{__dir__}/sdl2/Monaco.ttf", 121)
|
91
117
|
Hokusai.fonts.activate "default"
|
92
118
|
config.after_load_cb&.call
|
93
119
|
|
94
120
|
register_command_handlers(renderer, window)
|
121
|
+
block = app.mount
|
95
122
|
# MemoryProfiler.start if ENV["PROFILE"]
|
96
123
|
|
97
124
|
ptr = FFI::MemoryPointer.new :pointer
|
98
125
|
LibHokusai.hoku_input_init(ptr)
|
99
126
|
raw = LibHokusai::HmlInput.new(ptr.get_pointer(0))
|
100
127
|
input = Hokusai::Input.new(raw)
|
128
|
+
|
129
|
+
if config.touch
|
130
|
+
input.support_touch!
|
131
|
+
end
|
132
|
+
|
101
133
|
canvas = Hokusai::Canvas.new(render_width.to_f, render_height.to_f)
|
102
134
|
event = SDL::Event.new
|
103
135
|
|
104
136
|
loop do
|
105
|
-
SDL.
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
SDL.RenderPresent(renderer)
|
137
|
+
if SDL.PollEvent(event)
|
138
|
+
self.class.stopped = true if event[:common][:type] == SDL::QUIT || self.class.stopped
|
139
|
+
|
140
|
+
process_input(input, event)
|
141
|
+
if config.touch
|
142
|
+
if input.touch.touching?
|
143
|
+
token = input.touch.token
|
144
|
+
|
145
|
+
LibHokusai.hoku_input_set_mouse_position(input.raw, hml_vec2(token[:x], token[:y]))
|
146
|
+
end
|
147
|
+
|
148
|
+
# translate taps to clicks
|
149
|
+
if input.touch.tapped?
|
150
|
+
button = mouse_button(clicked: true, down: true, released: false, up: false)
|
151
|
+
LibHokusai.hoku_input_mouse_set_button(input.raw, button, 0)
|
152
|
+
else
|
153
|
+
button = mouse_button(clicked: false, down: false, released: true, up: true)
|
154
|
+
LibHokusai.hoku_input_mouse_set_button(input.raw, button, 0)
|
155
|
+
end
|
156
|
+
end
|
126
157
|
end
|
158
|
+
|
159
|
+
break if self.class.stopped
|
160
|
+
# since we are using wait event, we need to process the render twice
|
161
|
+
# once to capture all events, and once after updating block state.
|
162
|
+
SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_BLEND)
|
163
|
+
SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
|
164
|
+
SDL.RenderClear(renderer)
|
165
|
+
canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
|
166
|
+
painter = Hokusai::Painter.new(block, input)
|
167
|
+
painter.render(canvas, resize)
|
168
|
+
|
169
|
+
SDL.RenderPresent(renderer)
|
170
|
+
block.update
|
171
|
+
|
172
|
+
# SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_NONE)
|
173
|
+
# SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
|
174
|
+
# SDL.RenderClear(renderer)
|
175
|
+
# canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
|
176
|
+
# painter = Hokusai::Painter.new(block, input)
|
177
|
+
# painter.render(canvas, resize, capture: false)
|
178
|
+
# SDL.RenderPresent(renderer)
|
179
|
+
SDL.Delay(10)
|
127
180
|
end
|
128
181
|
|
129
182
|
LibHokusai.hoku_input_free(input.raw)
|
@@ -157,52 +210,78 @@ module Hokusai::Backends
|
|
157
210
|
end
|
158
211
|
|
159
212
|
def reset_keys(input)
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
213
|
+
if !input.keyboard_override
|
214
|
+
LibHokusai.hoku_input_keyboard_start(input.raw)
|
215
|
+
Modifiers.each do |(sdlk, hkey)|
|
216
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
|
217
|
+
end
|
164
218
|
|
165
|
-
|
166
|
-
|
167
|
-
|
219
|
+
Keys.values.each do |hkey|
|
220
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
|
221
|
+
end
|
168
222
|
|
169
|
-
|
223
|
+
LibHokusai.hoku_input_keyboard_stop(input.raw)
|
224
|
+
end
|
170
225
|
end
|
171
226
|
|
172
227
|
def process_input(input, event)
|
173
228
|
reset_keys(input)
|
174
229
|
|
230
|
+
t = event[:common][:type]
|
231
|
+
if config.touch && t != SDL::FINGERDOWN && t != SDL::WINDOWEVENT && t != SDL::FINGERUP && t != SDL::FINGERMOTION && t != SDL::MOUSEMOTION && t != SDL::POLLSENTINEL
|
232
|
+
input.touch.clear
|
233
|
+
end
|
234
|
+
|
175
235
|
case event[:common][:type]
|
176
|
-
when SDL::
|
177
|
-
|
178
|
-
|
179
|
-
hkey = Keys[code]
|
236
|
+
when SDL::FINGERDOWN
|
237
|
+
x = event[:tfinger][:x] * render_width
|
238
|
+
y = event[:tfinger][:y] * render_height
|
180
239
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
240
|
+
input.touch.record(0, x, y)
|
241
|
+
return true
|
242
|
+
when SDL::FINGERUP
|
243
|
+
input.touch.clear
|
244
|
+
return true
|
245
|
+
when SDL::FINGERMOTION
|
246
|
+
x = event[:tfinger][:x] * render_width
|
247
|
+
y = event[:tfinger][:y] * render_height
|
248
|
+
|
249
|
+
input.touch.record(0, x, y)
|
250
|
+
return true
|
251
|
+
when SDL::KEYDOWN
|
252
|
+
if !input.keyboard_override
|
253
|
+
modifier = event[:key][:keysym][:mod]
|
254
|
+
code = event[:key][:keysym][:sym]
|
255
|
+
hkey = Keys[code]
|
256
|
+
|
257
|
+
LibHokusai.hoku_input_keyboard_start(input.raw)
|
258
|
+
Modifiers.each do |(sdlk, hkey)|
|
259
|
+
if modifier & sdlk == sdlk
|
260
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, true)
|
261
|
+
end
|
185
262
|
end
|
186
|
-
end
|
187
263
|
|
188
|
-
|
189
|
-
|
264
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, true) unless hkey.nil?
|
265
|
+
LibHokusai.hoku_input_keyboard_stop(input.raw)
|
266
|
+
end
|
190
267
|
|
191
268
|
return true
|
192
269
|
when SDL::KEYUP
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
270
|
+
if !input.keyboard_override
|
271
|
+
modifier = event[:key][:keysym][:mod]
|
272
|
+
code = event[:key][:keysym][:sym]
|
273
|
+
hkey = Keys[code]
|
274
|
+
|
275
|
+
LibHokusai.hoku_input_keyboard_start(input.raw)
|
276
|
+
Modifiers.each do |(sdlk, hkey)|
|
277
|
+
if modifier & sdlk == sdlk
|
278
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
|
279
|
+
end
|
201
280
|
end
|
202
|
-
end
|
203
281
|
|
204
|
-
|
205
|
-
|
282
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false) unless hkey.nil?
|
283
|
+
LibHokusai.hoku_input_keyboard_stop(input.raw)
|
284
|
+
end
|
206
285
|
return true
|
207
286
|
when SDL::WINDOWEVENT
|
208
287
|
if event[:window][:event] == SDL::WINDOWEVENT_RESIZED
|
@@ -257,20 +336,34 @@ module Hokusai::Backends
|
|
257
336
|
clicked = event[:button][:clicks] > 0
|
258
337
|
button = mouse_button(down: true, clicked: clicked)
|
259
338
|
|
260
|
-
|
261
|
-
|
339
|
+
LibHokusai.hoku_input_mouse_set_scroll(input.raw, 0.0)
|
340
|
+
input.raw[:mouse][:delta][:y] = 0.0
|
262
341
|
|
263
342
|
LibHokusai.hoku_input_mouse_set_button(input.raw, button, event[:button][:which])
|
264
343
|
return true
|
265
344
|
when SDL::MOUSEBUTTONUP
|
266
345
|
button = mouse_button(up: true)
|
267
346
|
#
|
268
|
-
|
269
|
-
|
347
|
+
LibHokusai.hoku_input_mouse_set_scroll(input.raw, 0.0)
|
348
|
+
input.raw[:mouse][:delta][:y] = 0.0
|
270
349
|
|
271
350
|
LibHokusai.hoku_input_mouse_set_button(input.raw, button, event[:button][:which])
|
272
351
|
return true
|
273
352
|
when SDL::TEXTINPUT
|
353
|
+
char = event[:text][:text].to_s
|
354
|
+
LibHokusai.hoku_input_keyboard_start(input.raw)
|
355
|
+
|
356
|
+
Modifiers.each do |(sdlk, hkey)|
|
357
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
|
358
|
+
end
|
359
|
+
LibHokusai.hoku_input_keyboard_set_key(input.raw, char.to_sym, true)
|
360
|
+
LibHokusai.hoku_input_keyboard_stop(input.raw)
|
361
|
+
|
362
|
+
return true
|
363
|
+
when SDL::TEXTEDITING
|
364
|
+
# start = event[:edit][:start]
|
365
|
+
# len = event[:edit][:length]
|
366
|
+
# text = event[:edit][:text]
|
274
367
|
return false
|
275
368
|
else
|
276
369
|
false
|
@@ -410,16 +503,21 @@ module Hokusai::Backends
|
|
410
503
|
self.class.images[command.source]
|
411
504
|
else
|
412
505
|
file = File.read(command.source)
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
if surface_ptr.null?
|
506
|
+
SDL.SetHint(SDL::HINT_RENDER_SCALE_QUALITY, "0");
|
507
|
+
texture = SDL.IMG_LoadTexture(renderer, command.source)
|
508
|
+
if texture.null?
|
417
509
|
raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
|
418
510
|
end
|
419
511
|
|
420
|
-
|
512
|
+
# rw = SDL.RWFromConstMem(file, file.size)
|
513
|
+
# surface_ptr = SDL.IMG_LoadSVG_RW(rw)
|
514
|
+
# if surface_ptr.null?
|
515
|
+
# raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
|
516
|
+
# end
|
517
|
+
|
518
|
+
# texture = SDL.CreateTextureFromSurface(renderer, surface_ptr)
|
421
519
|
self.class.images[command.source] = texture
|
422
|
-
SDL.FreeSurface(surface_ptr)
|
520
|
+
# SDL.FreeSurface(surface_ptr)
|
423
521
|
texture
|
424
522
|
end
|
425
523
|
end
|
@@ -431,6 +529,7 @@ module Hokusai::Backends
|
|
431
529
|
|
432
530
|
Hokusai::Commands::Rect.on_draw do |command|
|
433
531
|
next unless inside_scissor(command.x, command.y, command.height)
|
532
|
+
next if command.color.a == 0
|
434
533
|
# draw background first
|
435
534
|
x, y, w, h = [command.x, command.y, command.width, command.height]
|
436
535
|
|
@@ -506,7 +605,6 @@ module Hokusai::Backends
|
|
506
605
|
rounding = command.rounding
|
507
606
|
|
508
607
|
if command.rounding > 0
|
509
|
-
pp command.color
|
510
608
|
SDL.roundedBoxRGBA(renderer, x, y, x + w, y + h, (command.rounding).ceil.to_i, command.color.r, command.color.g, command.color.b, command.color.a)
|
511
609
|
else
|
512
610
|
rect = SDL::Rect.new
|
@@ -515,6 +613,7 @@ module Hokusai::Backends
|
|
515
613
|
rect[:w] = w
|
516
614
|
rect[:h] = h
|
517
615
|
|
616
|
+
SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_BLEND)
|
518
617
|
SDL.SetRenderDrawColor(renderer, command.color.r, command.color.g, command.color.b, command.color.a)
|
519
618
|
SDL.RenderFillRect(renderer, rect)
|
520
619
|
end
|
@@ -87,7 +87,7 @@ class Hokusai::Blocks::Input < Hokusai::Block
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def dynamic_keypress_handle(event)
|
90
|
-
return unless node.meta.focused
|
90
|
+
return unless node.meta.focused || event.input.keyboard_override
|
91
91
|
case event
|
92
92
|
when proc(&:ctrl), proc(&:super)
|
93
93
|
if event.char == "z"
|
@@ -0,0 +1,234 @@
|
|
1
|
+
module Hokusai::Blocks
|
2
|
+
class Key < Hokusai::Block
|
3
|
+
template <<~EOF
|
4
|
+
[template]
|
5
|
+
empty {
|
6
|
+
@mousedown="set_down"
|
7
|
+
@mouseup="set_up"
|
8
|
+
cursor="pointer"
|
9
|
+
}
|
10
|
+
EOF
|
11
|
+
|
12
|
+
uses(empty: Hokusai::Blocks::Empty)
|
13
|
+
|
14
|
+
computed! :value
|
15
|
+
computed! :icons
|
16
|
+
computed :size, default: 24, convert: proc(&:to_i)
|
17
|
+
computed :background, default: Hokusai::Color.new(70, 70, 70), convert: Hokusai::Color
|
18
|
+
computed :color, default: Hokusai::Color.new(244, 244, 244), convert: Hokusai::Color
|
19
|
+
computed :background_down, default: Hokusai::Color.new(33,33,33), convert: Hokusai::Color
|
20
|
+
computed :margin, default: Hokusai::Padding.new(3.0, 2.5, 3.0, 2.5), convert: Hokusai::Padding
|
21
|
+
|
22
|
+
attr_accessor :down
|
23
|
+
|
24
|
+
def initialize(**args)
|
25
|
+
@down = false
|
26
|
+
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_down(event)
|
31
|
+
if !down
|
32
|
+
emit("clicked", value[0], event)
|
33
|
+
|
34
|
+
self.down = true
|
35
|
+
else
|
36
|
+
emit("released", value[0], event)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_up(event)
|
41
|
+
self.down = false
|
42
|
+
emit("released", value[0], event)
|
43
|
+
end
|
44
|
+
|
45
|
+
def render(canvas)
|
46
|
+
hpad = (canvas.width - size) / 2
|
47
|
+
vpad = (canvas.height - margin.height - size) / 2
|
48
|
+
|
49
|
+
draw do
|
50
|
+
if icon = icons[value[0]]
|
51
|
+
rect(canvas.x + margin.left, canvas.y + margin.top, canvas.width - margin.width, canvas.height - margin.height) do |command|
|
52
|
+
command.color = icon[:background]# down ? background_down : background
|
53
|
+
command.round = 6.0
|
54
|
+
end
|
55
|
+
|
56
|
+
svg(icon[:file], canvas.x + icon[:size] / 3, canvas.y + icon[:size] / 3, icon[:size], icon[:size]) do |command|
|
57
|
+
command.color = icon[:color]
|
58
|
+
end
|
59
|
+
else
|
60
|
+
rect(canvas.x + margin.left, canvas.y + margin.top, canvas.width - margin.width, canvas.height - margin.height) do |command|
|
61
|
+
command.color = down ? background_down : background
|
62
|
+
command.round = 6.0
|
63
|
+
end
|
64
|
+
|
65
|
+
text(value[1].to_s, canvas.x + hpad + margin.width, canvas.y + margin.height) do |command|
|
66
|
+
command.color = color
|
67
|
+
command.size = size
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
yield canvas
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class KeyboardRow < Hokusai::Block
|
77
|
+
style <<~EOF
|
78
|
+
[style]
|
79
|
+
keyboardStyle {
|
80
|
+
background: rgb(28, 28, 28);
|
81
|
+
}
|
82
|
+
keyStyle {
|
83
|
+
background: rgb(46, 46, 46);
|
84
|
+
color: rgb(208, 205, 218);
|
85
|
+
background_down: rgb(37, 37, 37);
|
86
|
+
}
|
87
|
+
EOF
|
88
|
+
|
89
|
+
template <<~EOF
|
90
|
+
[template]
|
91
|
+
hblock { ...keyboardStyle }
|
92
|
+
[for="number in keys"]
|
93
|
+
key {
|
94
|
+
...keyStyle
|
95
|
+
:width="width(number)"
|
96
|
+
:icons="icons"
|
97
|
+
:key="loop_key(number)"
|
98
|
+
:value="number"
|
99
|
+
@clicked="emit_key"
|
100
|
+
@released="emit_released"
|
101
|
+
}
|
102
|
+
EOF
|
103
|
+
|
104
|
+
uses(
|
105
|
+
hblock: Hblock,
|
106
|
+
vblock: Vblock,
|
107
|
+
key: Key
|
108
|
+
)
|
109
|
+
|
110
|
+
computed! :keys
|
111
|
+
computed! :icons
|
112
|
+
|
113
|
+
# def on_mounted
|
114
|
+
# node.meta.set_prop(:height, 48.0)
|
115
|
+
# end
|
116
|
+
|
117
|
+
def width(key)
|
118
|
+
if icon = icons[key[0]]
|
119
|
+
icon[:width]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def loop_key(value)
|
124
|
+
"key-#{value}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def emit_key(key, event)
|
128
|
+
emit("key", key, event)
|
129
|
+
end
|
130
|
+
|
131
|
+
def emit_released(key, event)
|
132
|
+
emit("released", key, event)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
class Keyboard < Hokusai::Block
|
137
|
+
style <<~EOF
|
138
|
+
[style]
|
139
|
+
kstyle {
|
140
|
+
padding: padding(10.0, 5.0, 10.0, 5.0);
|
141
|
+
background: rgb(28, 28, 28);
|
142
|
+
}
|
143
|
+
EOF
|
144
|
+
|
145
|
+
template <<~EOF
|
146
|
+
[template]
|
147
|
+
vblock { ...kstyle }
|
148
|
+
[for="row in key_rows"]
|
149
|
+
row {
|
150
|
+
:icons="icons"
|
151
|
+
@released="handle_released"
|
152
|
+
@key="handle_keypress"
|
153
|
+
:key="index"
|
154
|
+
:keys="row"
|
155
|
+
}
|
156
|
+
EOF
|
157
|
+
|
158
|
+
uses(
|
159
|
+
vblock: Hokusai::Blocks::Vblock,
|
160
|
+
row: KeyboardRow
|
161
|
+
)
|
162
|
+
|
163
|
+
|
164
|
+
def self.icons
|
165
|
+
{
|
166
|
+
:shift => {
|
167
|
+
file: Hokusai.asset("icons/outline/arrow-big-up.svg"),
|
168
|
+
width: 54.0,
|
169
|
+
size: 30,
|
170
|
+
background: Hokusai::Color.new(50, 109, 70),
|
171
|
+
color: Hokusai::Color.new(172, 224, 189)
|
172
|
+
},
|
173
|
+
:backspace => {
|
174
|
+
file: Hokusai.asset("icons/outline/backspace.svg"),
|
175
|
+
width: 54.0,
|
176
|
+
size: 30,
|
177
|
+
background: Hokusai::Color.new(50, 109, 70),
|
178
|
+
color: Hokusai::Color.new(172, 224, 189)
|
179
|
+
}
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
computed :icons, default: icons
|
184
|
+
computed :row_height, default: 48.0, convert: proc(&:to_f)
|
185
|
+
|
186
|
+
def on_mounted
|
187
|
+
node.meta.set_prop(:height, row_height * 5.0 + 20)
|
188
|
+
end
|
189
|
+
|
190
|
+
def space_row
|
191
|
+
[[:comma, ","], [:space, ''], [:period, "."]]
|
192
|
+
end
|
193
|
+
|
194
|
+
def key_rows
|
195
|
+
[number_keys, querty_keys, asdf_keys, zxcv_keys, space_row]
|
196
|
+
end
|
197
|
+
|
198
|
+
def handle_released(key, event)
|
199
|
+
event.input.keyboard_override = false
|
200
|
+
end
|
201
|
+
|
202
|
+
def handle_keypress(key, event)
|
203
|
+
event.input.keyboard_override = true
|
204
|
+
LibHokusai.hoku_input_keyboard_start(event.input.raw)
|
205
|
+
LibHokusai.hoku_input_keyboard_set_key(event.input.raw, key.to_sym, true)
|
206
|
+
LibHokusai.hoku_input_keyboard_stop(event.input.raw)
|
207
|
+
end
|
208
|
+
|
209
|
+
def zxcv_keys
|
210
|
+
@zxcv_keys ||= begin
|
211
|
+
keys = %w[z x c v b n m]
|
212
|
+
middle = keys.zip(keys)
|
213
|
+
middle << [:backspace, :backspace]
|
214
|
+
middle.unshift([:shift, :shift])
|
215
|
+
middle
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def asdf_keys
|
220
|
+
keys = %w[a s d f g h j k l]
|
221
|
+
@asdf_keys ||= keys.zip(keys)
|
222
|
+
end
|
223
|
+
|
224
|
+
def querty_keys
|
225
|
+
keys = %w[q w e r t y u i o p]
|
226
|
+
@querty_keys ||= keys.zip(keys)
|
227
|
+
end
|
228
|
+
|
229
|
+
def number_keys
|
230
|
+
keys = [[:one,1],[:two, 2], [:three,3], [:four,4],[:five, 5], [:six,6], [:seven,7], [:eight,8],[:nine,9], [:zero, 0]]
|
231
|
+
@number_keys ||= keys
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|