hokusai-zero 0.2.6 → 0.2.7
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/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/README.md +1 -1
- data/ast/src/core/ast.c +3 -11
- data/ast/src/core/hml.c +212 -40
- data/ast/src/core/hml.h +1 -0
- data/ast/src/core/input.h +0 -1
- data/ast/src/core/log.c +87 -0
- data/ast/src/core/log.h +41 -0
- data/ast/src/core/util.c +23 -23
- data/ast/src/core/util.h +7 -7
- data/ast/test/parser.c +1 -0
- data/ext/extconf.rb +6 -6
- data/hokusai.gemspec +1 -2
- data/ui/examples/drag.rb +154 -0
- data/ui/examples/embedded.rb +58 -0
- 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/game.rb +143 -0
- data/ui/examples/keyboard.rb +47 -0
- data/ui/examples/overlay.rb +233 -0
- data/ui/examples/provider.rb +56 -0
- data/ui/examples/shader/test.rb +155 -0
- data/ui/examples/shader.rb +100 -0
- data/ui/examples/spreadsheet.rb +12 -11
- data/ui/examples/wiki.rb +82 -0
- data/ui/lib/lib_hokusai.rb +43 -24
- data/ui/spec/hokusai/e2e/keyboard_spec.rb +52 -0
- data/ui/spec/spec_helper.rb +1 -1
- data/ui/src/hokusai/assets/arrow-down-line.png +0 -0
- data/ui/src/hokusai/assets/arrow-down-wide-line.png +0 -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/automation/driver_commands/base.rb +2 -8
- data/ui/src/hokusai/automation/driver_commands/trigger_keyboard.rb +3 -6
- data/ui/src/hokusai/automation/driver_commands/trigger_mouse.rb +12 -5
- data/ui/src/hokusai/automation/server.rb +2 -3
- data/ui/src/hokusai/backends/raylib/config.rb +2 -1
- data/ui/src/hokusai/backends/raylib/font.rb +24 -3
- data/ui/src/hokusai/backends/raylib.rb +167 -36
- 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 +188 -93
- data/ui/src/hokusai/blocks/color_picker.rb +1080 -0
- data/ui/src/hokusai/blocks/input.rb +2 -2
- data/ui/src/hokusai/blocks/keyboard.rb +249 -0
- data/ui/src/hokusai/blocks/shader_begin.rb +22 -0
- data/ui/src/hokusai/blocks/shader_end.rb +12 -0
- data/ui/src/hokusai/blocks/slider.rb +139 -0
- data/ui/src/hokusai/blocks/texture.rb +23 -0
- data/ui/src/hokusai/commands/rect.rb +12 -3
- data/ui/src/hokusai/commands/shader.rb +33 -0
- data/ui/src/hokusai/commands/texture.rb +26 -0
- data/ui/src/hokusai/commands.rb +22 -0
- data/ui/src/hokusai/event.rb +2 -1
- data/ui/src/hokusai/events/keyboard.rb +11 -18
- data/ui/src/hokusai/events/mouse.rb +10 -8
- data/ui/src/hokusai/events/touch.rb +62 -0
- data/ui/src/hokusai/meta.rb +9 -4
- data/ui/src/hokusai/mounting/loop_entry.rb +1 -1
- data/ui/src/hokusai/mounting/update_entry.rb +7 -6
- data/ui/src/hokusai/painter.rb +31 -8
- data/ui/src/hokusai/types/display.rb +151 -0
- data/ui/src/hokusai/types/keyboard.rb +168 -0
- data/ui/src/hokusai/types/mouse.rb +36 -0
- data/ui/src/hokusai/types/primitives.rb +56 -0
- data/ui/src/hokusai/types/touch.rb +181 -0
- data/ui/src/hokusai/types.rb +20 -244
- data/ui/src/hokusai/util/wrap_stream.rb +193 -0
- data/ui/src/hokusai.rb +61 -35
- data/xmake.lua +2 -1
- metadata +34 -22
- data/ui/src/hokusai/assets/chevron-down.svg +0 -1
@@ -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,46 +110,77 @@ 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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
124
|
+
input = Hokusai::Input.new
|
125
|
+
|
126
|
+
if config.touch
|
127
|
+
input.support_touch!
|
128
|
+
end
|
129
|
+
|
101
130
|
canvas = Hokusai::Canvas.new(render_width.to_f, render_height.to_f)
|
102
131
|
event = SDL::Event.new
|
103
132
|
|
104
133
|
loop do
|
105
|
-
SDL.
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
134
|
+
if SDL.PollEvent(event)
|
135
|
+
self.class.stopped = true if event[:common][:type] == SDL::QUIT || self.class.stopped
|
136
|
+
|
137
|
+
process_input(input, event)
|
138
|
+
if config.touch
|
139
|
+
if input.touch.touching?
|
140
|
+
token = input.touch.token
|
141
|
+
|
142
|
+
input.mouse.pos.x = token[:x]
|
143
|
+
input.mouse.pos.y = token[:y]
|
144
|
+
end
|
145
|
+
|
146
|
+
# translate taps to clicks
|
147
|
+
if input.touch.tapped?
|
148
|
+
input.mouse.left.clicked = true
|
149
|
+
input.mouse.left.down = true
|
150
|
+
input.mouse.left.released = false
|
151
|
+
input.mouse.left.up = false
|
152
|
+
else
|
153
|
+
input.mouse.left.clicked = true
|
154
|
+
input.mouse.left.down = true
|
155
|
+
input.mouse.left.released = false
|
156
|
+
input.mouse.left.up = false
|
157
|
+
end
|
158
|
+
end
|
126
159
|
end
|
160
|
+
|
161
|
+
break if self.class.stopped
|
162
|
+
# since we are using wait event, we need to process the render twice
|
163
|
+
# once to capture all events, and once after updating block state.
|
164
|
+
SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_BLEND)
|
165
|
+
SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
|
166
|
+
SDL.RenderClear(renderer)
|
167
|
+
canvas.reset(0.0, 0.0, render_width.to_f, render_height.to_f)
|
168
|
+
painter = Hokusai::Painter.new(block, input)
|
169
|
+
painter.render(canvas, resize)
|
170
|
+
|
171
|
+
SDL.RenderPresent(renderer)
|
172
|
+
block.update
|
173
|
+
|
174
|
+
# SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_NONE)
|
175
|
+
# SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
|
176
|
+
# SDL.RenderClear(renderer)
|
177
|
+
# canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
|
178
|
+
# painter = Hokusai::Painter.new(block, input)
|
179
|
+
# painter.render(canvas, resize, capture: false)
|
180
|
+
# SDL.RenderPresent(renderer)
|
181
|
+
SDL.Delay(10)
|
127
182
|
end
|
128
183
|
|
129
|
-
LibHokusai.hoku_input_free(input.raw)
|
130
184
|
if ENV["PROFILE"]
|
131
185
|
# report = MemoryProfiler.stop
|
132
186
|
# report.pretty_print
|
@@ -157,52 +211,76 @@ module Hokusai::Backends
|
|
157
211
|
end
|
158
212
|
|
159
213
|
def reset_keys(input)
|
160
|
-
|
161
|
-
|
162
|
-
LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
|
163
|
-
end
|
214
|
+
if !input.keyboard_override
|
215
|
+
input.keyboard.reset
|
164
216
|
|
165
|
-
|
166
|
-
|
167
|
-
|
217
|
+
Modifiers.each do |(sdlk, hkey)|
|
218
|
+
input.keyboard.set(hkey, false)
|
219
|
+
end
|
168
220
|
|
169
|
-
|
221
|
+
Keys.values.each do |hkey|
|
222
|
+
input.keyboard.set(hkey, false)
|
223
|
+
end
|
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]
|
236
|
+
when SDL::FINGERDOWN
|
237
|
+
x = event[:tfinger][:x] * render_width
|
238
|
+
y = event[:tfinger][:y] * render_height
|
239
|
+
|
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
|
176
251
|
when SDL::KEYDOWN
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
252
|
+
if !input.keyboard_override
|
253
|
+
modifier = event[:key][:keysym][:mod]
|
254
|
+
code = event[:key][:keysym][:sym]
|
255
|
+
hkey = Keys[code]
|
256
|
+
|
257
|
+
input.keyboard.reset
|
258
|
+
|
259
|
+
Modifiers.each do |(sdlk, hkey)|
|
260
|
+
if modifier & sdlk == sdlk
|
261
|
+
input.keyboard.set(hkey, true)
|
262
|
+
end
|
185
263
|
end
|
186
|
-
end
|
187
264
|
|
188
|
-
|
189
|
-
|
265
|
+
input.keyboard.set(hkey, true) unless hkey.nil?
|
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
|
+
input.keyboard.reset
|
275
|
+
|
276
|
+
Modifiers.each do |(sdlk, hkey)|
|
277
|
+
if modifier & sdlk == sdlk
|
278
|
+
input.keyboard.set(hkey, false)
|
279
|
+
end
|
201
280
|
end
|
202
|
-
end
|
203
281
|
|
204
|
-
|
205
|
-
|
282
|
+
input.keyboard.set(hkey, false) unless hkey.nil?
|
283
|
+
end
|
206
284
|
return true
|
207
285
|
when SDL::WINDOWEVENT
|
208
286
|
if event[:window][:event] == SDL::WINDOWEVENT_RESIZED
|
@@ -223,54 +301,65 @@ module Hokusai::Backends
|
|
223
301
|
|
224
302
|
return true
|
225
303
|
when SDL::MOUSEMOTION
|
226
|
-
if input.
|
227
|
-
|
228
|
-
input.
|
229
|
-
input.
|
230
|
-
input.raw[:mouse][:scroll] = event[:motion][:y]
|
304
|
+
if input.mouse.delta.y > 0
|
305
|
+
input.mouse.delta.y = 0.0
|
306
|
+
input.mouse.scroll_delta = 0.0
|
307
|
+
input.mouse.scroll = event[:motion][:y]
|
231
308
|
end
|
232
309
|
|
233
|
-
|
234
|
-
|
235
|
-
LibHokusai.hoku_input_set_mouse_position(input.raw, hoku_mouse_pos)
|
310
|
+
input.mouse.pos.x = event[:motion][:x]
|
311
|
+
input.mouse.pos.y = event[:motion][:y]
|
236
312
|
|
237
313
|
# clear any click events
|
238
314
|
[[:left, 0], [:right, 2], [:middle, 1]].each do |(btn, i)|
|
239
|
-
|
240
|
-
button[:clicked] = false
|
241
|
-
LibHokusai.hoku_input_mouse_set_button(input.raw, button, i)
|
315
|
+
input.mouse.send(btn).clicked = false
|
242
316
|
end
|
243
317
|
|
244
318
|
return true
|
245
319
|
when SDL::MOUSEWHEEL
|
246
|
-
|
247
|
-
input.
|
320
|
+
input.mouse.scroll = event[:wheel][:preciseY]
|
321
|
+
input.mouse.delta.y = event[:wheel][:preciseY]
|
248
322
|
|
249
323
|
# clear any click events
|
250
324
|
[[:left, 0], [:right, 2], [:middle, 1]].each do |(btn, i)|
|
251
|
-
|
252
|
-
button[:clicked] = false
|
253
|
-
LibHokusai.hoku_input_mouse_set_button(input.raw, button, i)
|
325
|
+
input.mouse.send(btn).clicked = false
|
254
326
|
end
|
327
|
+
|
255
328
|
return true
|
256
329
|
when SDL::MOUSEBUTTONDOWN
|
257
330
|
clicked = event[:button][:clicks] > 0
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
331
|
+
btn = {
|
332
|
+
0 => :left,
|
333
|
+
1 => :middle,
|
334
|
+
2 => :right
|
335
|
+
}[event[:button][:which]]
|
336
|
+
|
337
|
+
input.mouse.send(btn).clicked = clicked
|
338
|
+
input.mouse.send(btn).down = true
|
339
|
+
input.mouse.send(btn).up = false
|
340
|
+
input.mouse.scroll = 0.0
|
341
|
+
input.mouse.delta.y = 0.0
|
262
342
|
|
263
|
-
LibHokusai.hoku_input_mouse_set_button(input.raw, button, event[:button][:which])
|
264
343
|
return true
|
265
344
|
when SDL::MOUSEBUTTONUP
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
345
|
+
btn = {
|
346
|
+
0 => :left,
|
347
|
+
1 => :middle,
|
348
|
+
2 => :right
|
349
|
+
}[event[:button][:which]]
|
350
|
+
|
351
|
+
input.mouse.send(btn).up = true
|
352
|
+
input.mouse.send(btn).down = false
|
353
|
+
input.mouse.scroll = 0.0
|
354
|
+
input.mouse.delta.y = 0.0
|
272
355
|
return true
|
273
356
|
when SDL::TEXTINPUT
|
357
|
+
|
358
|
+
return true
|
359
|
+
when SDL::TEXTEDITING
|
360
|
+
# start = event[:edit][:start]
|
361
|
+
# len = event[:edit][:length]
|
362
|
+
# text = event[:edit][:text]
|
274
363
|
return false
|
275
364
|
else
|
276
365
|
false
|
@@ -410,16 +499,21 @@ module Hokusai::Backends
|
|
410
499
|
self.class.images[command.source]
|
411
500
|
else
|
412
501
|
file = File.read(command.source)
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
if surface_ptr.null?
|
502
|
+
SDL.SetHint(SDL::HINT_RENDER_SCALE_QUALITY, "0");
|
503
|
+
texture = SDL.IMG_LoadTexture(renderer, command.source)
|
504
|
+
if texture.null?
|
417
505
|
raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
|
418
506
|
end
|
419
507
|
|
420
|
-
|
508
|
+
# rw = SDL.RWFromConstMem(file, file.size)
|
509
|
+
# surface_ptr = SDL.IMG_LoadSVG_RW(rw)
|
510
|
+
# if surface_ptr.null?
|
511
|
+
# raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
|
512
|
+
# end
|
513
|
+
|
514
|
+
# texture = SDL.CreateTextureFromSurface(renderer, surface_ptr)
|
421
515
|
self.class.images[command.source] = texture
|
422
|
-
SDL.FreeSurface(surface_ptr)
|
516
|
+
# SDL.FreeSurface(surface_ptr)
|
423
517
|
texture
|
424
518
|
end
|
425
519
|
end
|
@@ -431,6 +525,7 @@ module Hokusai::Backends
|
|
431
525
|
|
432
526
|
Hokusai::Commands::Rect.on_draw do |command|
|
433
527
|
next unless inside_scissor(command.x, command.y, command.height)
|
528
|
+
next if command.color.a == 0
|
434
529
|
# draw background first
|
435
530
|
x, y, w, h = [command.x, command.y, command.width, command.height]
|
436
531
|
|
@@ -506,7 +601,6 @@ module Hokusai::Backends
|
|
506
601
|
rounding = command.rounding
|
507
602
|
|
508
603
|
if command.rounding > 0
|
509
|
-
pp command.color
|
510
604
|
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
605
|
else
|
512
606
|
rect = SDL::Rect.new
|
@@ -515,6 +609,7 @@ module Hokusai::Backends
|
|
515
609
|
rect[:w] = w
|
516
610
|
rect[:h] = h
|
517
611
|
|
612
|
+
SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_BLEND)
|
518
613
|
SDL.SetRenderDrawColor(renderer, command.color.r, command.color.g, command.color.b, command.color.a)
|
519
614
|
SDL.RenderFillRect(renderer, rect)
|
520
615
|
end
|