hokusai-zero 0.2.6.pre.android → 0.2.6.pre.pinephone2

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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +0 -2
  4. data/ast/src/core/input.c +135 -0
  5. data/ast/src/core/input.h +32 -0
  6. data/ast/test/hokusai.c +2 -0
  7. data/ast/test/input.c +44 -0
  8. data/hokusai.gemspec +1 -2
  9. data/ui/examples/drag.rb +154 -0
  10. data/ui/examples/embedded.rb +58 -0
  11. data/ui/examples/game.rb +143 -0
  12. data/ui/examples/overlay.rb +233 -0
  13. data/ui/examples/provider.rb +56 -0
  14. data/ui/examples/shader/test.rb +145 -0
  15. data/ui/examples/shader.rb +100 -0
  16. data/ui/examples/wiki.rb +82 -0
  17. data/ui/lib/lib_hokusai.rb +20 -1
  18. data/ui/spec/spec_helper.rb +1 -1
  19. data/ui/src/hokusai/assets/arrow-down-line.png +0 -0
  20. data/ui/src/hokusai/assets/arrow-down-wide-line.png +0 -0
  21. data/ui/src/hokusai/automation/server.rb +2 -3
  22. data/ui/src/hokusai/backends/embedded/config.rb +48 -0
  23. data/ui/src/hokusai/backends/embedded/font.rb +112 -0
  24. data/ui/src/hokusai/backends/embedded/keys.rb +124 -0
  25. data/ui/src/hokusai/backends/embedded.rb +540 -0
  26. data/ui/src/hokusai/backends/raylib.rb +80 -5
  27. data/ui/src/hokusai/blocks/color_picker.rb +1080 -0
  28. data/ui/src/hokusai/blocks/shader_begin.rb +22 -0
  29. data/ui/src/hokusai/blocks/shader_end.rb +12 -0
  30. data/ui/src/hokusai/blocks/texture.rb +23 -0
  31. data/ui/src/hokusai/commands/rect.rb +10 -1
  32. data/ui/src/hokusai/commands/shader.rb +33 -0
  33. data/ui/src/hokusai/commands/texture.rb +26 -0
  34. data/ui/src/hokusai/commands.rb +22 -0
  35. data/ui/src/hokusai/event.rb +2 -1
  36. data/ui/src/hokusai/events/touch.rb +66 -0
  37. data/ui/src/hokusai/painter.rb +22 -0
  38. data/ui/src/hokusai/types.rb +89 -0
  39. data/ui/src/hokusai.rb +4 -9
  40. data/xmake.lua +1 -1
  41. metadata +25 -22
  42. data/ui/src/hokusai/assets/chevron-down.svg +0 -1
@@ -0,0 +1,22 @@
1
+ class Hokusai::Blocks::ShaderBegin < Hokusai::Block
2
+ template <<~EOF
3
+ [template]
4
+ slot
5
+ EOF
6
+
7
+ computed :fragment_shader, default: nil
8
+ computed :vertex_shader, default: nil
9
+ computed :uniforms, default: []
10
+
11
+ def render(canvas)
12
+ draw do
13
+ shader_begin do |command|
14
+ command.vertex_shader = vertex_shader
15
+ command.fragment_shader = fragment_shader
16
+ command.uniforms = uniforms
17
+ end
18
+ end
19
+
20
+ yield canvas
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ class Hokusai::Blocks::ShaderEnd < Hokusai::Block
2
+ template <<~EOF
3
+ [template]
4
+ virtual
5
+ EOF
6
+
7
+ def render(canvas)
8
+ draw do
9
+ shader_end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ class Hokusai::Blocks::Texture < Hokusai::Block
2
+ template <<~EOF
3
+ [template]
4
+ virtual
5
+ EOF
6
+
7
+ computed :width, default: nil, convert: proc(&:to_i)
8
+ computed :height, default: nil, convert: proc(&:to_i)
9
+ computed :x, default: nil
10
+ computed :y, default: nil
11
+ computed :rotation, default: nil
12
+ computed :scale, default: 100.0
13
+
14
+
15
+ def render(canvas)
16
+ draw do
17
+ texture(x || canvas.x, y || canvas.y, width || canvas.width, height || canvas.height) do |command|
18
+ command.rotation = rotation if rotation
19
+ command.scale = scale
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,7 +2,7 @@ module Hokusai
2
2
  class Commands::Rect < Commands::Base
3
3
  attr_reader :x, :y, :width, :height,
4
4
  :rounding, :color, :outline,
5
- :outline_color, :padding
5
+ :outline_color, :padding, :gradient
6
6
 
7
7
  def initialize(x, y, width, height)
8
8
  @x = x.to_f
@@ -14,6 +14,7 @@ module Hokusai
14
14
  @color = Color.new(0, 0, 0, 0)
15
15
  @outline_color = Color.new(0, 0, 0, 255)
16
16
  @padding = Padding.new(0.0, 0.0, 0.0, 0.0)
17
+ @gradient = nil
17
18
  end
18
19
 
19
20
  def hash
@@ -44,6 +45,14 @@ module Hokusai
44
45
  height
45
46
  end
46
47
 
48
+ def gradient=(colors)
49
+ unless colors.is_a?(Array) && colors.size == 4 && colors.all? { |color| color.is_a?(Hokusai::Color) }
50
+ raise Hokusai::Error.new("Gradient must be an array of 4 Hokuai::Color")
51
+ end
52
+
53
+ @gradient = colors
54
+ end
55
+
47
56
  # Sets padding for the rectangle
48
57
  # `value` is an array with padding declarations
49
58
  # at [top, right, bottom, left]
@@ -0,0 +1,33 @@
1
+ module Hokusai
2
+ class Commands::ShaderBegin < Commands::Base
3
+ attr_reader :vertex_shader, :fragment_shader, :uniforms
4
+
5
+ def initialize
6
+ @uniforms = []
7
+ @vertex_shader = nil
8
+ @fragment_shader = nil
9
+ end
10
+
11
+ def vertex_shader=(content)
12
+ @vertex_shader = content
13
+ end
14
+
15
+ def fragment_shader=(content)
16
+ @fragment_shader = content
17
+ end
18
+
19
+ def uniforms=(values)
20
+ @uniforms = values
21
+ end
22
+
23
+ def hash
24
+ [self.class, vertex_shader, fragment_shader].hash
25
+ end
26
+ end
27
+
28
+ class Commands::ShaderEnd < Commands::Base;
29
+ def hash
30
+ [self.class].hash
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module Hokusai
2
+ class Commands::Texture < Commands::Base
3
+ attr_reader :x, :y, :width, :height, :rotation, :scale
4
+
5
+ def initialize(x, y, width, height)
6
+ @x = x
7
+ @y = y
8
+ @width = width
9
+ @height = height
10
+ @rotation = 0.0
11
+ @scale = 10.0
12
+ end
13
+
14
+ def rotation=(value)
15
+ @rotation = value
16
+ end
17
+
18
+ def scale=(value)
19
+ @scale = value
20
+ end
21
+
22
+ def hash
23
+ [self.class, x, y, width, height].hash
24
+ end
25
+ end
26
+ end
@@ -4,6 +4,8 @@ require_relative "./commands/image"
4
4
  require_relative "./commands/rect"
5
5
  require_relative "./commands/scissor"
6
6
  require_relative "./commands/text"
7
+ require_relative "./commands/shader"
8
+ require_relative "./commands/texture"
7
9
 
8
10
  module Hokusai
9
11
  # A proxy class for invoking various UI commands
@@ -81,6 +83,26 @@ module Hokusai
81
83
  queue << Commands::ScissorEnd.new
82
84
  end
83
85
 
86
+ def shader_begin
87
+ command = Commands::ShaderBegin.new
88
+
89
+ yield command
90
+
91
+ queue << command
92
+ end
93
+
94
+ def shader_end
95
+ queue << Commands::ShaderEnd.new
96
+ end
97
+
98
+ def texture(x, y, w, h)
99
+ command = Commands::Texture.new(x, y, w, h)
100
+
101
+ yield command
102
+
103
+ queue << command
104
+ end
105
+
84
106
  # Draws text
85
107
  #
86
108
  # @param [String] the text content
@@ -65,4 +65,5 @@ module Hokusai
65
65
  end
66
66
 
67
67
  require_relative './events/keyboard'
68
- require_relative './events/mouse'
68
+ require_relative './events/mouse'
69
+ require_relative './events/touch'
@@ -0,0 +1,66 @@
1
+ module Hokusai
2
+ class TouchEvent < Event
3
+ extend Forwardable
4
+
5
+ def_delegators :@touch, :tapped?, :swiped?, :longtapped?, :touching?,
6
+ :duration, :direction, :angle, :position, :last_position,
7
+ :touch_len, :touch_count, :timer
8
+
9
+ attr_reader :input
10
+
11
+ def initialize(input, state)
12
+ @input = input
13
+ @state = state
14
+ @touch = input.touch
15
+ end
16
+
17
+ def hovered(canvas)
18
+ input.hovered?(canvas)
19
+ end
20
+
21
+ def to_json
22
+ {
23
+ keypress: {
24
+ hold: hold,
25
+ hold_duration: hold_duration.to_s,
26
+ }
27
+ }.to_json
28
+ end
29
+ end
30
+
31
+ class TapHoldEvent < TouchEvent
32
+ name "taphold"
33
+
34
+ def capture(block, canvas)
35
+ if longtapped? && hovered(canvas)
36
+ block.node.meta.focus
37
+
38
+ if matches(block)
39
+ captures << block
40
+ end
41
+ elsif touching?
42
+ block.node.meta.blur
43
+ end
44
+ end
45
+ end
46
+
47
+ class PinchEvent < TouchEvent
48
+ name "pinch"
49
+
50
+ def capture(block, canvas)
51
+ if false && matches(block)
52
+ captures << block
53
+ end
54
+ end
55
+ end
56
+
57
+ class SwipeEvent < TouchEvent
58
+ name "swipe"
59
+
60
+ def capture(block, canvas)
61
+ if swiped? && matches(block)
62
+ captures << block
63
+ end
64
+ end
65
+ end
66
+ end
@@ -45,6 +45,16 @@ module Hokusai
45
45
  keyup: KeyUpEvent.new(input, state),
46
46
  keypress: KeyPressEvent.new(input, state)
47
47
  }
48
+
49
+ add_touch_events(events, input, state) unless input.touch.nil?
50
+ end
51
+
52
+ def add_touch_events(events, input, state)
53
+ events.merge!({
54
+ taphold: TapHoldEvent.new(input, state),
55
+ pinch: PinchEvent.new(input, state),
56
+ swipe: SwipeEvent.new(input, state),
57
+ })
48
58
  end
49
59
 
50
60
  def on_before_render(&block)
@@ -170,6 +180,12 @@ module Hokusai
170
180
  events[:mouseout].bubble
171
181
  events[:mousedown].bubble
172
182
  events[:mouseup].bubble
183
+
184
+ unless input.touch.nil?
185
+ events[:taphold].bubble
186
+ events[:pinch].bubble
187
+ events[:swipe].bubble
188
+ end
173
189
  end
174
190
 
175
191
  after_render&.call
@@ -265,6 +281,12 @@ module Hokusai
265
281
  events[:keyup].capture(block, canvas)
266
282
  events[:keypress].capture(block, canvas)
267
283
  end
284
+
285
+ unless input.touch.nil?
286
+ events[:taphold].capture(block, canvas)
287
+ events[:pinch].capture(block, canvas)
288
+ events[:swipe].capture(block, canvas)
289
+ end
268
290
  end
269
291
  end
270
292
  end
@@ -240,6 +240,89 @@ module Hokusai
240
240
  end
241
241
  end
242
242
 
243
+ class Touch
244
+ attr_reader :raw
245
+
246
+ [
247
+ :touch_len, :touch_count, :touching_now, :timer,
248
+ ].each do |key|
249
+ define_method(key) do
250
+ raw[:touch][key]
251
+ end
252
+ end
253
+
254
+ def swiped?
255
+ LibHokusai.hoku_input_touch_swiped(raw)
256
+ end
257
+
258
+ def longtapped?
259
+ LibHokusai.hoku_input_touch_longtapped(raw)
260
+ end
261
+
262
+ # return [Intger] duration in milliseconds
263
+ def duration
264
+ LibHokusai.hoku_input_touch_duration(raw)
265
+ end
266
+
267
+ def touching?
268
+ touching_now
269
+ end
270
+
271
+ def tapped?
272
+ LibHokusai.hoku_input_touch_tapped(raw)
273
+ end
274
+
275
+ def position(index=0)
276
+ touches[index]
277
+ end
278
+
279
+ def last_position(index=0)
280
+ last_touches[index]
281
+ end
282
+
283
+ def angle(index = 0)
284
+ return nil unless swiped?
285
+
286
+ pos = position(index)
287
+ lpos = last_position(index)
288
+
289
+ x = position.x - last_position.x
290
+ y = position.y - last_position.y
291
+
292
+ (Math.atan2(x, y) * (180 / Math::PI)).round(0).to_i
293
+ end
294
+
295
+ def direction(index=0)
296
+ return nil unless swiped?
297
+
298
+ pos = position(index)
299
+ lpos = last_position(index)
300
+
301
+ x = position.x - last_position.x
302
+ y = position.y - last_position.y
303
+
304
+ if x.abs > y.abs
305
+ # swiping left/right
306
+ position.x > last_position.x ? :right : :left
307
+ else
308
+ # swiping up/down
309
+ position.y > last_position.y ? :up : :down
310
+ end
311
+ end
312
+
313
+ def last_touches
314
+ @raw[:last_touch_positions].read_array_of_type(LibHokusai::HmlDoubleVec2, :read_pointer, touch_len)
315
+ end
316
+
317
+ def touches
318
+ @raw[:touch_positions].read_array_of_type(LibHokusai::HmlDoubleVec2, :read_pointer, touch_len)
319
+ end
320
+
321
+ def initialize(raw)
322
+ @raw = raw
323
+ end
324
+ end
325
+
243
326
  class Input
244
327
  attr_reader :raw
245
328
 
@@ -251,6 +334,12 @@ module Hokusai
251
334
  @raw = raw
252
335
  end
253
336
 
337
+ def touch
338
+ return nil if @raw[:touch].null?
339
+
340
+ Touch.new(@raw)
341
+ end
342
+
254
343
  def keyboard
255
344
  Keyboard.new(@raw[:keyboard])
256
345
  end
data/ui/src/hokusai.rb CHANGED
@@ -38,20 +38,15 @@ require_relative './hokusai/blocks/variable'
38
38
  require_relative './hokusai/blocks/titlebar/osx'
39
39
  require_relative './hokusai/blocks/modal'
40
40
  require_relative './hokusai/blocks/dropdown'
41
-
42
- require "concurrent"
41
+ require_relative './hokusai/blocks/shader_begin'
42
+ require_relative './hokusai/blocks/shader_end'
43
+ require_relative './hokusai/blocks/texture'
44
+ require_relative './hokusai/blocks/color_picker'
43
45
 
44
46
  # A backend agnostic library for authoring
45
47
  # desktop applications
46
48
  # @author skinnyjames
47
49
  module Hokusai
48
- ThreadPool = Concurrent::ThreadPoolExecutor.new(
49
- min_threads: 5,
50
- max_threads: 5,
51
- max_queue: 20,
52
- fallback_policy: :caller_runs
53
- )
54
-
55
50
  SHADER_UNIFORM_FLOAT = 0 # Shader uniform type: float
56
51
  SHADER_UNIFORM_VEC2 = 1 # Shader uniform type: vec2 (2 float)
57
52
  SHADER_UNIFORM_VEC3 = 2 # Shader uniform type: vec3 (3 float)
data/xmake.lua CHANGED
@@ -159,7 +159,7 @@ target("test-ast")
159
159
  )
160
160
  -- add_cflags("-Wall -Werror")
161
161
  after_build(function(target)
162
- os.exec("./%s -t markdown", target:targetfile())
162
+ os.exec("./%s -t input", target:targetfile())
163
163
  -- os.exec("leaks -atExit -- %s", target:targetfile())
164
164
  end)
165
165
  target_end()
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hokusai-zero
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6.pre.android
4
+ version: 0.2.6.pre.pinephone2
5
5
  platform: ruby
6
6
  authors:
7
7
  - skinnyjames
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-06-28 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: ffi
@@ -24,20 +23,6 @@ dependencies:
24
23
  - - "~>"
25
24
  - !ruby/object:Gem::Version
26
25
  version: '1.16'
27
- - !ruby/object:Gem::Dependency
28
- name: concurrent-ruby
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 1.3.4
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 1.3.4
41
26
  - !ruby/object:Gem::Dependency
42
27
  name: raylib-bindings
43
28
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +79,6 @@ dependencies:
94
79
  - - ">="
95
80
  - !ruby/object:Gem::Version
96
81
  version: '0'
97
- description:
98
82
  email: zero@skinnyjames.net
99
83
  executables: []
100
84
  extensions:
@@ -130,6 +114,7 @@ files:
130
114
  - ast/test/fixtures/test.ui
131
115
  - ast/test/greatest.h
132
116
  - ast/test/hokusai.c
117
+ - ast/test/input.c
133
118
  - ast/test/parser.c
134
119
  - ast/test/text.c
135
120
  - docs.sh
@@ -181,17 +166,25 @@ files:
181
166
  - ui/examples/buddy.rb
182
167
  - ui/examples/clock.rb
183
168
  - ui/examples/counter.rb
169
+ - ui/examples/drag.rb
184
170
  - ui/examples/dynamic.rb
171
+ - ui/examples/embedded.rb
185
172
  - ui/examples/foobar.rb
186
173
  - ui/examples/forum.rb
187
174
  - ui/examples/forum/file.rb
188
175
  - ui/examples/forum/music.rb
189
176
  - ui/examples/forum/post.rb
177
+ - ui/examples/game.rb
178
+ - ui/examples/overlay.rb
179
+ - ui/examples/provider.rb
180
+ - ui/examples/shader.rb
181
+ - ui/examples/shader/test.rb
190
182
  - ui/examples/spreadsheet.rb
191
183
  - ui/examples/spreadsheet/csv.rb
192
184
  - ui/examples/stock.rb
193
185
  - ui/examples/stock_decider/option.rb
194
186
  - ui/examples/tic_tac_toe.rb
187
+ - ui/examples/wiki.rb
195
188
  - ui/lib/lib_hokusai.rb
196
189
  - ui/spec/hokusai/ast_spec.rb
197
190
  - ui/spec/hokusai/automation/keys_transcoder_spec.rb
@@ -208,8 +201,9 @@ files:
208
201
  - ui/spec/hokusai_spec.rb
209
202
  - ui/spec/spec_helper.rb
210
203
  - ui/src/hokusai.rb
204
+ - ui/src/hokusai/assets/arrow-down-line.png
205
+ - ui/src/hokusai/assets/arrow-down-wide-line.png
211
206
  - ui/src/hokusai/assets/arrow-drop-down-line.png
212
- - ui/src/hokusai/assets/chevron-down.svg
213
207
  - ui/src/hokusai/assets/close-large-line.png
214
208
  - ui/src/hokusai/ast.rb
215
209
  - ui/src/hokusai/automation.rb
@@ -227,6 +221,10 @@ files:
227
221
  - ui/src/hokusai/automation/keys_transcoder.rb
228
222
  - ui/src/hokusai/automation/selector.rb
229
223
  - ui/src/hokusai/automation/server.rb
224
+ - ui/src/hokusai/backends/embedded.rb
225
+ - ui/src/hokusai/backends/embedded/config.rb
226
+ - ui/src/hokusai/backends/embedded/font.rb
227
+ - ui/src/hokusai/backends/embedded/keys.rb
230
228
  - ui/src/hokusai/backends/raylib.rb
231
229
  - ui/src/hokusai/backends/raylib/config.rb
232
230
  - ui/src/hokusai/backends/raylib/font.rb
@@ -242,6 +240,7 @@ files:
242
240
  - ui/src/hokusai/blocks/checkbox.rb
243
241
  - ui/src/hokusai/blocks/circle.rb
244
242
  - ui/src/hokusai/blocks/clipped.rb
243
+ - ui/src/hokusai/blocks/color_picker.rb
245
244
  - ui/src/hokusai/blocks/cursor.rb
246
245
  - ui/src/hokusai/blocks/dropdown.rb
247
246
  - ui/src/hokusai/blocks/dynamic.rb
@@ -257,8 +256,11 @@ files:
257
256
  - ui/src/hokusai/blocks/scissor_end.rb
258
257
  - ui/src/hokusai/blocks/scrollbar.rb
259
258
  - ui/src/hokusai/blocks/selectable.rb
259
+ - ui/src/hokusai/blocks/shader_begin.rb
260
+ - ui/src/hokusai/blocks/shader_end.rb
260
261
  - ui/src/hokusai/blocks/svg.rb
261
262
  - ui/src/hokusai/blocks/text.rb
263
+ - ui/src/hokusai/blocks/texture.rb
262
264
  - ui/src/hokusai/blocks/titlebar/osx.rb
263
265
  - ui/src/hokusai/blocks/toggle.rb
264
266
  - ui/src/hokusai/blocks/variable.rb
@@ -269,12 +271,15 @@ files:
269
271
  - ui/src/hokusai/commands/image.rb
270
272
  - ui/src/hokusai/commands/rect.rb
271
273
  - ui/src/hokusai/commands/scissor.rb
274
+ - ui/src/hokusai/commands/shader.rb
272
275
  - ui/src/hokusai/commands/text.rb
276
+ - ui/src/hokusai/commands/texture.rb
273
277
  - ui/src/hokusai/diff.rb
274
278
  - ui/src/hokusai/error.rb
275
279
  - ui/src/hokusai/event.rb
276
280
  - ui/src/hokusai/events/keyboard.rb
277
281
  - ui/src/hokusai/events/mouse.rb
282
+ - ui/src/hokusai/events/touch.rb
278
283
  - ui/src/hokusai/font.rb
279
284
  - ui/src/hokusai/meta.rb
280
285
  - ui/src/hokusai/mounting/loop_entry.rb
@@ -297,7 +302,6 @@ licenses:
297
302
  - MIT
298
303
  metadata:
299
304
  source_code_uri: https://codeberg.org/skinnyjames/hokusai
300
- post_install_message:
301
305
  rdoc_options: []
302
306
  require_paths:
303
307
  - ui/src
@@ -312,8 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
312
316
  - !ruby/object:Gem::Version
313
317
  version: '0'
314
318
  requirements: []
315
- rubygems_version: 3.5.22
316
- signing_key:
319
+ rubygems_version: 3.6.7
317
320
  specification_version: 4
318
321
  summary: A Ruby library for writing GUI applications
319
322
  test_files: []
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><title>finite-icons</title><path d="M13.60851,6.08611L8.35425,11.339,3.06908,6.05389a0.5,0.5,0,0,1,0-.70711l0.539-.539a0.5,0.5,0,0,1,.70711,0l4.03907,4.039L12.36249,4.8399a0.5,0.5,0,0,1,.70705.00006l0.539,0.539A0.5,0.5,0,0,1,13.60851,6.08611Z" fill="#231f20"/></svg>