hokusai-zero 0.2.5 → 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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +0 -2
  4. data/README.md +1 -1
  5. data/ast/src/core/input.c +85 -0
  6. data/ast/src/core/input.h +31 -0
  7. data/ast/src/core/util.c +23 -23
  8. data/ast/src/core/util.h +7 -7
  9. data/ext/extconf.rb +7 -3
  10. data/hokusai.gemspec +1 -2
  11. data/ui/examples/drag.rb +154 -0
  12. data/ui/examples/embedded.rb +59 -0
  13. data/ui/examples/game.rb +143 -0
  14. data/ui/examples/overlay.rb +233 -0
  15. data/ui/examples/provider.rb +56 -0
  16. data/ui/examples/shader/test.rb +145 -0
  17. data/ui/examples/shader.rb +100 -0
  18. data/ui/examples/wiki.rb +82 -0
  19. data/ui/lib/lib_hokusai.rb +29 -8
  20. data/ui/spec/spec_helper.rb +1 -1
  21. data/ui/src/hokusai/assets/arrow-down-line.png +0 -0
  22. data/ui/src/hokusai/assets/arrow-down-wide-line.png +0 -0
  23. data/ui/src/hokusai/automation/server.rb +2 -3
  24. data/ui/src/hokusai/backends/embedded/config.rb +47 -0
  25. data/ui/src/hokusai/backends/embedded/font.rb +112 -0
  26. data/ui/src/hokusai/backends/embedded/keys.rb +124 -0
  27. data/ui/src/hokusai/backends/embedded.rb +564 -0
  28. data/ui/src/hokusai/backends/raylib.rb +80 -5
  29. data/ui/src/hokusai/blocks/color_picker.rb +1080 -0
  30. data/ui/src/hokusai/blocks/shader_begin.rb +22 -0
  31. data/ui/src/hokusai/blocks/shader_end.rb +12 -0
  32. data/ui/src/hokusai/blocks/texture.rb +23 -0
  33. data/ui/src/hokusai/commands/rect.rb +10 -1
  34. data/ui/src/hokusai/commands/shader.rb +33 -0
  35. data/ui/src/hokusai/commands/texture.rb +26 -0
  36. data/ui/src/hokusai/commands.rb +22 -0
  37. data/ui/src/hokusai/event.rb +2 -1
  38. data/ui/src/hokusai/events/embedded.rb +66 -0
  39. data/ui/src/hokusai/painter.rb +22 -0
  40. data/ui/src/hokusai/types.rb +29 -0
  41. data/ui/src/hokusai.rb +4 -9
  42. metadata +24 -22
  43. data/ui/src/hokusai/assets/chevron-down.svg +0 -1
@@ -0,0 +1,143 @@
1
+ require_relative "../src/hokusai"
2
+ require_relative "../src/hokusai/backends/raylib"
3
+ require 'ostruct'
4
+
5
+ TILES = [
6
+ ["Power Supply", 500],
7
+ ["Power Distribution", 400],
8
+ ["Farm", 100],
9
+ ["Medicine Production", 50],
10
+ ["Science Research", 400],
11
+ ["Lumberyard", 200],
12
+ ["Art Gallery", 20],
13
+ ["School", 100],
14
+ ["Commercial transportation", 300],
15
+ ["Mechanical Automation", 700],
16
+ ["Tailor shop", 50],
17
+ ["Housing Construction", 200],
18
+ ["Commerical Building Construction", 300],
19
+ ["Restaraunt", 50],
20
+ ["Furniture manufacturing", 200],
21
+ ["Cotton mill", 200],
22
+ ["Metals processing", 400],
23
+ ["Forestry center", 400],
24
+ ["Bar", 50],
25
+ ["Healthcare", 100]
26
+ ]
27
+
28
+
29
+ class Game < Hokusai::Block
30
+ style <<-EOF
31
+ [style]
32
+ bg {
33
+ color: rgb(173, 207, 224);
34
+ width: 100;
35
+ height: 100;
36
+ outline: outline(1.0, 1.0, 1.0, 1.0);
37
+ outline_color: rgb(0, 0, 0);
38
+ }
39
+ board {
40
+ height: 500;
41
+ width: 500;
42
+ }
43
+ height {
44
+ height: 100;
45
+ }
46
+ textPadding {
47
+ padding: padding(10.0, 5.0, 10.0, 10.0);
48
+ }
49
+ EOF
50
+ template <<~EOF
51
+ [template]
52
+ vblock { ...board }
53
+ hblock
54
+ [for="tile in top"]
55
+ rect { :key="top_key(tile)" ...bg }
56
+ text { :content="tile" ...textPadding}
57
+ [for="i in middle"]
58
+ hblock {...height :key="get(i)"}
59
+ rect {...bg}
60
+ text { :key="get(i)" :content="get(i)" ...textPadding }
61
+ empty
62
+ empty
63
+ empty
64
+ rect {...bg }
65
+ text { :key="get_next(i)" :content="get_next(i)" ...textPadding}
66
+ hblock
67
+ [for="tile in bottom"]
68
+ rect { ...bg :key="bottom_key(tile)" }
69
+ text { :key="tile" :content="tile" ...textPadding }
70
+ EOF
71
+
72
+ uses(
73
+ hblock: Hokusai::Blocks::Hblock,
74
+ vblock: Hokusai::Blocks::Vblock,
75
+ text: Hokusai::Blocks::Text,
76
+ empty: Hokusai::Blocks::Empty,
77
+ rect: Hokusai::Blocks::Rect
78
+ )
79
+
80
+ attr_reader :tiles
81
+
82
+ def get(i)
83
+ tiles[i[0]].title
84
+ end
85
+
86
+ def get_next(i)
87
+ tiles[i[1]].title
88
+ end
89
+
90
+ def middle
91
+ (5..10).each_slice(2).to_a
92
+ end
93
+
94
+ def bottom_key(t)
95
+ "bottom-#{t}"
96
+ end
97
+
98
+ def top_key(t)
99
+ "top-#{t}"
100
+ end
101
+
102
+ def top
103
+ tiles.take(5).map(&:title)
104
+ end
105
+
106
+ def bottom
107
+ a = tiles[-5, 5].map(&:title)
108
+ a
109
+ end
110
+
111
+ def after_updated
112
+ @tiles = TILES.map do |(label, cost)|
113
+ os = OpenStruct.new
114
+ os.title = label
115
+ os.cost = cost
116
+ os
117
+ end
118
+ end
119
+
120
+ def initialize(**args)
121
+ @tiles = TILES.map do |(label, cost)|
122
+ os = OpenStruct.new
123
+ os.title = label
124
+ os.cost = cost
125
+ os
126
+ end
127
+
128
+ super
129
+ end
130
+ end
131
+
132
+
133
+ Hokusai::Backends::RaylibBackend.run(Game) do |config|
134
+ config.width = 500
135
+ config.height = 500
136
+
137
+ config.after_load do
138
+ font = Hokusai::Backends::RaylibBackend::Font.from_ext("#{__dir__}/assets/OpenSans-Regular.ttf", 160)
139
+ Hokusai.fonts.register "opensans", font
140
+ Hokusai.fonts.activate "opensans"
141
+ end
142
+ end
143
+
@@ -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