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

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 (39) 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 +85 -0
  5. data/ast/src/core/input.h +31 -0
  6. data/hokusai.gemspec +1 -2
  7. data/ui/examples/drag.rb +154 -0
  8. data/ui/examples/embedded.rb +59 -0
  9. data/ui/examples/game.rb +143 -0
  10. data/ui/examples/overlay.rb +233 -0
  11. data/ui/examples/provider.rb +56 -0
  12. data/ui/examples/shader/test.rb +145 -0
  13. data/ui/examples/shader.rb +100 -0
  14. data/ui/examples/wiki.rb +82 -0
  15. data/ui/lib/lib_hokusai.rb +22 -1
  16. data/ui/spec/spec_helper.rb +1 -1
  17. data/ui/src/hokusai/assets/arrow-down-line.png +0 -0
  18. data/ui/src/hokusai/assets/arrow-down-wide-line.png +0 -0
  19. data/ui/src/hokusai/automation/server.rb +2 -3
  20. data/ui/src/hokusai/backends/embedded/config.rb +47 -0
  21. data/ui/src/hokusai/backends/embedded/font.rb +112 -0
  22. data/ui/src/hokusai/backends/embedded/keys.rb +124 -0
  23. data/ui/src/hokusai/backends/embedded.rb +564 -0
  24. data/ui/src/hokusai/backends/raylib.rb +80 -5
  25. data/ui/src/hokusai/blocks/color_picker.rb +1080 -0
  26. data/ui/src/hokusai/blocks/shader_begin.rb +22 -0
  27. data/ui/src/hokusai/blocks/shader_end.rb +12 -0
  28. data/ui/src/hokusai/blocks/texture.rb +23 -0
  29. data/ui/src/hokusai/commands/rect.rb +10 -1
  30. data/ui/src/hokusai/commands/shader.rb +33 -0
  31. data/ui/src/hokusai/commands/texture.rb +26 -0
  32. data/ui/src/hokusai/commands.rb +22 -0
  33. data/ui/src/hokusai/event.rb +2 -1
  34. data/ui/src/hokusai/events/embedded.rb +66 -0
  35. data/ui/src/hokusai/painter.rb +22 -0
  36. data/ui/src/hokusai/types.rb +29 -0
  37. data/ui/src/hokusai.rb +4 -9
  38. metadata +24 -22
  39. data/ui/src/hokusai/assets/chevron-down.svg +0 -1
@@ -0,0 +1,233 @@
1
+ require_relative "../src/hokusai"
2
+ require_relative "../src/hokusai/backends/raylib"
3
+
4
+ class DropdownItem < Hokusai::Block
5
+ style <<~EOF
6
+ [style]
7
+ textStyle {
8
+ padding: padding(5.0, 5.0, 5.0, 5.0);
9
+ size: 23;
10
+ color: rgb(255,255,255);
11
+ cursor: "pointer";
12
+ }
13
+ EOF
14
+
15
+ template <<~EOF
16
+ [template]
17
+ text#second {
18
+ :content="content"
19
+ ...textStyle
20
+ @click="emit_option"
21
+ @height_updated="udpate_height"
22
+ }
23
+ EOF
24
+
25
+ uses(text: Hokusai::Blocks::Text)
26
+
27
+ computed! :content
28
+ computed! :index
29
+
30
+ def udpate_height(height)
31
+ node.portal.meta.set_prop(:height, height)
32
+ emit("height", height, index)
33
+ end
34
+
35
+ def emit_option(e)
36
+ emit("option", content)
37
+ end
38
+ end
39
+
40
+ class Dropdown < Hokusai::Block
41
+ style <<-EOF
42
+ [style]
43
+ panelStyle {
44
+ z: 1;
45
+ width: 200;
46
+ height: 300;
47
+ background: rgb(67, 64, 92);
48
+ }
49
+
50
+ labelStyle {
51
+ size: 22;
52
+ content: "Please choose your fruit?";
53
+ }
54
+ EOF
55
+
56
+ template <<~EOF
57
+ [template]
58
+ vblock { @click="toggle_dropdown" height="70"}
59
+ label { ...labelStyle }
60
+ label { :content="selected" size="25" }
61
+ [if="toggled"]
62
+ panel#first { ...panelStyle @click="stop"}
63
+ [for="option in options"]
64
+ item {
65
+ :height="get_height(index)"
66
+ :content="option"
67
+ :key="index"
68
+ :index="index"
69
+ @option="select"
70
+ @height="update_height"
71
+ }
72
+ EOF
73
+
74
+ uses(label: Hokusai::Blocks::Label, vblock: Hokusai::Blocks::Vblock, item: DropdownItem, panel: Hokusai::Blocks::Panel)
75
+
76
+ attr_reader :toggled
77
+
78
+ computed! :options
79
+
80
+ def list_height
81
+ @heights ||= {}
82
+ @heights.values.reduce(&:+) || 0.0
83
+ end
84
+
85
+ def get_height(index)
86
+ @heights ||= {}
87
+ @heights[index] || 0.0
88
+ end
89
+
90
+ def update_height(height, index)
91
+ @heights ||= {}
92
+ @heights[index] = height
93
+ end
94
+
95
+ def stop(e)
96
+ end
97
+
98
+ def toggle_dropdown(_)
99
+ @toggled = !@toggled
100
+ end
101
+
102
+ def select(option)
103
+ @selected = option
104
+ @toggled = false
105
+ end
106
+
107
+ # def options
108
+ # %w[apple pear mango pineapple orange pear bananana kiwi grapes melon lemon lime]
109
+ # end
110
+
111
+ def selected
112
+ @selected || options.first
113
+ end
114
+
115
+ def initialize(**args)
116
+ @toggled = true
117
+
118
+ super
119
+ end
120
+ end
121
+
122
+ class Modal < Hokusai::Block
123
+ template <<~EOF
124
+ [template]
125
+ hblock#top
126
+ empty
127
+ empty#topempty
128
+ text { @click="emit_close" content="X" size="40" color="255,255,255}
129
+ hblock#middle { height="300"}
130
+ slot
131
+ hblock#last
132
+ empty#lastempty
133
+ EOF
134
+
135
+ uses(vblock: Hokusai::Blocks::Vblock, empty: Hokusai::Blocks::Empty, hblock: Hokusai::Blocks::Hblock, text: Hokusai::Blocks::Label)
136
+
137
+ computed :color, default: [0, 0, 0, 200], convert: Hokusai::Color
138
+
139
+ def emit_close(event)
140
+ emit("close")
141
+
142
+ event.stop
143
+ end
144
+
145
+ def render(canvas)
146
+ draw do
147
+ rect(canvas.x, canvas.y, canvas.width, canvas.height) do |command|
148
+ command.color = color
149
+ end
150
+ end
151
+
152
+ yield canvas
153
+ end
154
+ end
155
+
156
+ class Thing < Hokusai::Block
157
+ style <<~EOF
158
+ [style]
159
+ textStyle {
160
+ size: 30;
161
+ color: rgb(0, 0, 0);
162
+ content: "Hello modal!";
163
+ }
164
+
165
+ otherText {
166
+ size: 25;
167
+ content: "Hello World";
168
+ }
169
+ contentStyle {
170
+ height: 300.0;
171
+ width: 300.0;
172
+ background: rgb(255, 255, 255, 255);
173
+ }
174
+ backgroundStyle {
175
+ background: rgb(43, 151, 117);
176
+ }
177
+ modalStyle {
178
+ z: 1;
179
+ position: "absolute";
180
+ }
181
+ EOF
182
+
183
+ template <<~EOF
184
+ [template]
185
+ vblock#topnot
186
+ hblock#not{ ...backgroundStyle }
187
+ text#not { ...otherText @click="open_modal" }
188
+ dropdown { :options="outer_options" }
189
+ hblock { background="233,0,0" }
190
+ text#second { content="Second" }
191
+ modal {
192
+ @close="close"
193
+ :active="modal_open"
194
+ }
195
+ vblock { ...contentStyle }
196
+ dropdown { :options="inner_options" }
197
+ color_picker
198
+ text#last { size="30" content="last"}
199
+ EOF
200
+
201
+ attr_reader :modal_open
202
+
203
+ def log(event)
204
+ pp ["clicked!"]
205
+ end
206
+
207
+ def outer_options
208
+ %w[sam betty fred candace justin lucy annabelle nick janessa sean]
209
+ end
210
+
211
+ def inner_options
212
+ %w[apple pear mango pineapple orange pear bananana kiwi grapes melon lemon lime]
213
+ end
214
+
215
+ def open_modal(event)
216
+ @modal_open = true
217
+ end
218
+
219
+ def close
220
+ @modal_open = false
221
+ end
222
+
223
+ uses(
224
+ color_picker: Hokusai::Blocks::ColorPicker, modal: Hokusai::Blocks::Modal, dropdown: Hokusai::Blocks::Dropdown, vblock: Hokusai::Blocks::Vblock, text: Hokusai::Blocks::Text,empty: Hokusai::Blocks::Empty, hblock: Hokusai::Blocks::Hblock)
225
+ end
226
+
227
+ Hokusai::Backends::RaylibBackend.run(Thing) do |config|
228
+ config.after_load do
229
+ font = Hokusai::Backends::RaylibBackend::Font.from("#{__dir__}/assets/Inter-Regular.ttf")
230
+ Hokusai.fonts.register "inter", font
231
+ Hokusai.fonts.activate "inter"
232
+ end
233
+ end
@@ -0,0 +1,56 @@
1
+ require_relative "../src/hokusai"
2
+ require_relative "../src/hokusai/backends/raylib"
3
+
4
+ class Child < Hokusai::Block
5
+ template <<~EOF
6
+ [template]
7
+ text { :content="get_content" @selected="handle_selected" @height_updated="update_height"}
8
+ EOF
9
+
10
+ uses(
11
+ vblock: Hokusai::Blocks::Vblock,
12
+ text: Hokusai::Blocks::Text,
13
+ input: Hokusai::Blocks::Input
14
+ )
15
+
16
+ def update_height(height)
17
+ node.meta.set_prop(:height, height)
18
+ end
19
+
20
+ def handle_selected(start, stop)
21
+ pp [start, stop]
22
+ end
23
+
24
+ def get_content
25
+ @file ||= File.read(__FILE__)
26
+ end
27
+ end
28
+
29
+ class ProviderExample < Hokusai::Block
30
+ template <<~EOF
31
+ [template]
32
+ selectable
33
+ panel
34
+ text { :content="get_content" }
35
+ EOF
36
+
37
+ uses(
38
+ vblock: Hokusai::Blocks::Vblock,
39
+ selectable: Hokusai::Blocks::Selectable,
40
+ panel: Hokusai::Blocks::Panel,
41
+ child: Child,
42
+ text: Hokusai::Blocks::Text
43
+ )
44
+
45
+ def get_content
46
+ @file ||= File.read(__FILE__)
47
+ end
48
+ end
49
+
50
+
51
+ Hokusai::Backends::RaylibBackend.run(ProviderExample) do |config|
52
+ config.width = 500
53
+ config.height = 500
54
+ config.title = "Provider application"
55
+ end
56
+
@@ -0,0 +1,145 @@
1
+ require_relative "../../src/hokusai"
2
+ require_relative "../../src/hokusai/backends/raylib"
3
+ require "date"
4
+
5
+ class ShaderWrapper < Hokusai::Block
6
+ template <<~EOF
7
+ [template]
8
+ shader_begin {
9
+ @mousemove="update_value"
10
+ :vertex_shader="vertex_shader"
11
+ :uniforms="uniforms"
12
+ }
13
+ slot
14
+ shader_end
15
+ EOF
16
+
17
+ uses(
18
+ shader_begin: Hokusai::Blocks::ShaderBegin,
19
+ shader_end: Hokusai::Blocks::ShaderEnd,
20
+ texture: Hokusai::Blocks::Texture
21
+ )
22
+
23
+ def update_value(event)
24
+ @pos = (event.pos.x + event.pos.y) / 1000
25
+ end
26
+
27
+ def uniforms
28
+ return unless @start && @pos
29
+ done = Process.clock_gettime(Process::CLOCK_MONOTONIC)
30
+ elapsed = (done - @start).round(3)
31
+
32
+ {
33
+ millis: [elapsed / 2, Hokusai::SHADER_UNIFORM_FLOAT]
34
+ }
35
+ end
36
+
37
+ def on_mounted
38
+ @start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
39
+ end
40
+
41
+ def fragment_shader
42
+ <<-EOF
43
+ #version 330
44
+ in vec4 fragColor;
45
+ out vec4 finalColor;
46
+
47
+ void main() {
48
+ finalColor = fragColor; //vec4(0., 1., 0., 1.);
49
+ }
50
+ EOF
51
+ end
52
+
53
+ def vertex_shader
54
+ <<-EOF
55
+ #version 330
56
+ in vec3 vertexPosition;
57
+ in vec2 vertexTexCoord;
58
+ in vec4 vertexColor;
59
+
60
+ uniform mat4 mvp;
61
+ uniform float millis;
62
+
63
+ out vec2 fragTexCoord;
64
+ out vec4 fragColor;
65
+
66
+ void main() {
67
+ fragTexCoord = vertexTexCoord;
68
+ fragColor = vertexColor;
69
+ vec4 position = mvp * vec4(vertexPosition, 1.);
70
+
71
+ position.x += sin(millis + position.y * 8) / 8;
72
+ gl_Position = position;
73
+ }
74
+ EOF
75
+ end
76
+
77
+ def render(canvas)
78
+ canvas.vertical = true
79
+ @x = canvas.x
80
+
81
+ yield canvas
82
+ end
83
+ end
84
+
85
+ class ShaderTest < Hokusai::Block
86
+ style <<~EOF
87
+ [style]
88
+ circleStyle {
89
+ color: rgb(47, 112, 106);
90
+ }
91
+
92
+ textStyle {
93
+ content: "Whoa, coool dude.";
94
+ size: 15.0;
95
+ }
96
+ EOF
97
+
98
+ template <<~EOF
99
+ [template]
100
+ hblock
101
+ empty
102
+ hblock
103
+ hblock
104
+ empty
105
+ hblock
106
+ wrapper
107
+ image { :source="addy_png" :width="500" :height="400" }
108
+ text { ...textStyle }
109
+ circle {
110
+ :radius="50.0"
111
+ ...circleStyle
112
+ }
113
+ hblock
114
+ empty
115
+ hblock
116
+ empty
117
+
118
+ EOF
119
+
120
+ uses(
121
+ wrapper: ShaderWrapper,
122
+ picker: Hokusai::Blocks::ColorPicker,
123
+ image: Hokusai::Blocks::Image,
124
+ text: Hokusai::Blocks::Text,
125
+ circle: Hokusai::Blocks::Circle,
126
+ vblock: Hokusai::Blocks::Vblock,
127
+ hblock: Hokusai::Blocks::Hblock,
128
+ empty: Hokusai::Blocks::Empty
129
+ )
130
+
131
+ def addy_png
132
+ "#{__dir__}/../assets/addy.png"
133
+ end
134
+ end
135
+
136
+
137
+ Hokusai::Backends::RaylibBackend.run(ShaderTest) do |config|
138
+ config.width = 900
139
+ config.height = 800
140
+ config.after_load do
141
+ font = Hokusai::Backends::RaylibBackend::Font.from("#{__dir__}/assets/Inter-Regular.ttf")
142
+ Hokusai.fonts.register "inter", font
143
+ Hokusai.fonts.activate "inter"
144
+ end
145
+ end
@@ -0,0 +1,100 @@
1
+ require_relative "../src/hokusai"
2
+ require_relative "../src/hokusai/backends/raylib"
3
+
4
+ class ShaderExample < Hokusai::Block
5
+ style <<~EOF
6
+ [style]
7
+ textureThing {
8
+ width: 500;
9
+ height: 900;
10
+ scale: 100.0;
11
+ }
12
+ EOF
13
+
14
+ template <<~EOF
15
+ [template]
16
+ colorpicker
17
+ shader_begin {
18
+ @mousemove="change_rotation"
19
+ @click="switch_color"
20
+ :fragment_shader="fragment_shader"
21
+ :uniforms="uniforms"
22
+ }
23
+ texture {
24
+ ...textureThing
25
+ :rotation="rotate"
26
+ }
27
+ shader_end
28
+ EOF
29
+
30
+ uses(
31
+ colorpicker: Hokusai::Blocks::ColorPicker,
32
+ shader_begin: Hokusai::Blocks::ShaderBegin,
33
+ shader_end: Hokusai::Blocks::ShaderEnd,
34
+ texture: Hokusai::Blocks::Texture,
35
+ rect: Hokusai::Blocks::Rect,
36
+ vblock: Hokusai::Blocks::Vblock
37
+ )
38
+
39
+ attr_reader :rotate
40
+
41
+ def initialize(**args)
42
+ @color = [1.0, 0.0, 0.0, 1.0]
43
+ @position = [0.0, 100.0, 0.0, 1.0]
44
+
45
+ super
46
+ end
47
+
48
+ def change_rotation(event)
49
+ @rotate = event.delta[:y]
50
+ end
51
+
52
+ def switch_color(event)
53
+ @color = [
54
+ [0.3, 0.3, 0.3, 1.0],
55
+ [0.0, 1.0, 0.0, 1.0],
56
+ [0.0, 0.0, 1.0, 1.0]
57
+ ].sample
58
+ end
59
+
60
+ # def move_mouse(event)
61
+ # @position[0] = [0.0, 0.3, 0.6, 0.9, 1.0].sample
62
+ # end
63
+
64
+ def vertex_shader
65
+ <<-EOF
66
+ #version 330 core
67
+
68
+ uniform vec4 position;
69
+
70
+ void main() {
71
+ gl_Position = position;
72
+ }
73
+ EOF
74
+ end
75
+
76
+ def fragment_shader
77
+ <<-EOF
78
+ #version 330 core
79
+
80
+ in vec4 position;
81
+ out vec4 FragColor;
82
+
83
+ uniform vec4 color;
84
+
85
+ void main() {
86
+ FragColor = color;
87
+ }
88
+ EOF
89
+ end
90
+
91
+ def uniforms
92
+ [
93
+ ["color", @color, Hokusai::SHADER_UNIFORM_VEC4]
94
+ ]
95
+ end
96
+ end
97
+
98
+ Hokusai::Backends::RaylibBackend.run(ShaderExample) do |config|
99
+ config.background = Raylib::BLUE
100
+ end
@@ -0,0 +1,82 @@
1
+ require "wikipedia"
2
+ require_relative "../src/hokusai"
3
+ require_relative "../src/hokusai/backends/raylib"
4
+
5
+ module Wiki
6
+ class Widget < Hokusai::Block
7
+ style <<-EOF
8
+ [style]
9
+ wikiStyle {
10
+ color: rgb(49, 49, 49);
11
+ size: 20;
12
+ markdown: true;
13
+ padding: padding(5.0, 10.0, 5.0, 10.0);
14
+ }
15
+ search {
16
+ height: 45;
17
+ background: rgb(239, 243, 255);
18
+ }
19
+ EOF
20
+ template <<-EOF
21
+ [template]
22
+ selectable
23
+ vblock
24
+ vblock {
25
+ ...search
26
+ }
27
+ label {
28
+ content="Search by Term"
29
+ }
30
+ input {
31
+ size="25"
32
+ @change="update_term"
33
+ }
34
+ [if="summary"]
35
+ panel
36
+ text {
37
+ @selected="handle_selected"
38
+ :content="summary"
39
+ ...wikiStyle
40
+ }
41
+ EOF
42
+
43
+ uses(
44
+ selectable: Hokusai::Blocks::Selectable,
45
+ vblock: Hokusai::Blocks::Vblock,
46
+ text: Hokusai::Blocks::Text,
47
+ label: Hokusai::Blocks::Label,
48
+ input: Hokusai::Blocks::Input,
49
+ panel: Hokusai::Blocks::Panel,
50
+ )
51
+
52
+ attr_reader :summary
53
+
54
+ def update_term(term)
55
+ page = Wikipedia.find(term)
56
+
57
+ @summary = <<~EOF
58
+ **[#{term}](#{page.fullurl})**
59
+
60
+ #{page.summary}
61
+ EOF
62
+
63
+ @summary
64
+ end
65
+
66
+ def handle_selected(start, stop)
67
+ pp [start, stop]
68
+ end
69
+ end
70
+ end
71
+
72
+ Hokusai::Backends::RaylibBackend.run(Wiki::Widget) do |config|
73
+ config.after_load do
74
+ font = Hokusai::Backends::RaylibBackend::Font.from_ext("#{__dir__}/assets/Inter-Regular.ttf", 160)
75
+ Hokusai.fonts.register "inter", font
76
+ Hokusai.fonts.activate "inter"
77
+ end
78
+
79
+ config.width = 500
80
+ config.height = 500
81
+ config.title = "Wiki Widget"
82
+ end
@@ -245,6 +245,22 @@ module LibHokusai
245
245
  :collecting, :bool
246
246
  end
247
247
 
248
+ enum :hml_drag_direction, [:up, :down, :left, :right]
249
+ enum :hml_pinch_direction, [:in, :out]
250
+
251
+ class HmlInputEmbedded < FFI::Struct
252
+ layout :hold, :bool,
253
+ :hold_duration, :int,
254
+ :drag, :bool,
255
+ :drag_direction, :hml_drag_direction,
256
+ :drag_pos, HmlVec2.ptr,
257
+ :drag_angle, :float,
258
+ :pinch, :bool,
259
+ :pinch_direction, :hml_pinch_direction,
260
+ :pinch_pos, HmlVec2.ptr,
261
+ :pinch_angle, :float
262
+ end
263
+
248
264
  class HmlInputMouseButton < FFI::Struct
249
265
  layout :down, :bool,
250
266
  :up, :bool,
@@ -293,7 +309,8 @@ module LibHokusai
293
309
 
294
310
  class HmlInput < FFI::Struct
295
311
  layout :keyboard, HmlInputKeyboard.ptr,
296
- :mouse, HmlInputMouse.ptr
312
+ :mouse, HmlInputMouse.ptr,
313
+ :embedded, HmlInputEmbedded.ptr
297
314
  end
298
315
 
299
316
  def LibHokusai.const_missing( sym )
@@ -308,6 +325,10 @@ module LibHokusai
308
325
  attach_function :hoku_input_set_mouse_position, [HmlInput.by_ref, HmlVec2.by_ref], :void
309
326
  attach_function :hoku_input_mouse_set_scroll, [HmlInput.by_ref, :float], :void
310
327
  attach_function :hoku_input_mouse_set_button, [HmlInput.by_ref, HmlInputMouseButton.by_ref, :int], :void
328
+ attach_function :hoku_input_embedded_set_hold, [HmlInput.by_ref, :bool, :int], :void
329
+ attach_function :hoku_input_embedded_set_drag, [HmlInput.by_ref, :bool, :hml_drag_direction, :float, :float, :float], :void
330
+ attach_function :hoku_input_embedded_set_pinch, [HmlInput.by_ref, :bool, :hml_pinch_direction, :float, :float, :float], :void
331
+ attach_function :hoku_input_attach_embedded, [HmlInput.by_ref], :int
311
332
 
312
333
  attach_function :hoku_input_is_clicked, [HmlInput.by_ref, HmlRect.by_ref], :bool
313
334
  attach_function :hoku_input_is_hovered, [HmlInput.by_ref, HmlRect.by_ref], :bool
@@ -44,7 +44,7 @@ def with_app(app, &block)
44
44
  client = nil
45
45
  error = nil
46
46
 
47
- Hokusai::ThreadPool.post do
47
+ Thread.new do
48
48
  client = Hokusai::Automation::Client.start
49
49
 
50
50
  yield client
@@ -99,15 +99,14 @@ module Hokusai
99
99
  app = App.new(driver)
100
100
 
101
101
  @socket = Thin::Server.new(*args, app)
102
- Hokusai::ThreadPool.post do
102
+
103
+ Thread.new do
103
104
  @socket.start
104
105
  end
105
106
  end
106
107
 
107
108
  def self.stop
108
109
  @socket.stop
109
-
110
- Hokusai::ThreadPool.prune_pool
111
110
  end
112
111
  end
113
112
  end