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.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/ast/src/core/input.c +85 -0
- data/ast/src/core/input.h +31 -0
- data/hokusai.gemspec +1 -2
- data/ui/examples/drag.rb +154 -0
- data/ui/examples/embedded.rb +59 -0
- data/ui/examples/game.rb +143 -0
- data/ui/examples/overlay.rb +233 -0
- data/ui/examples/provider.rb +56 -0
- data/ui/examples/shader/test.rb +145 -0
- data/ui/examples/shader.rb +100 -0
- data/ui/examples/wiki.rb +82 -0
- data/ui/lib/lib_hokusai.rb +22 -1
- 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/automation/server.rb +2 -3
- data/ui/src/hokusai/backends/embedded/config.rb +47 -0
- data/ui/src/hokusai/backends/embedded/font.rb +112 -0
- data/ui/src/hokusai/backends/embedded/keys.rb +124 -0
- data/ui/src/hokusai/backends/embedded.rb +564 -0
- data/ui/src/hokusai/backends/raylib.rb +80 -5
- data/ui/src/hokusai/blocks/color_picker.rb +1080 -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/texture.rb +23 -0
- data/ui/src/hokusai/commands/rect.rb +10 -1
- 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/embedded.rb +66 -0
- data/ui/src/hokusai/painter.rb +22 -0
- data/ui/src/hokusai/types.rb +29 -0
- data/ui/src/hokusai.rb +4 -9
- metadata +24 -22
- 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
|
data/ui/examples/wiki.rb
ADDED
@@ -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
|
data/ui/lib/lib_hokusai.rb
CHANGED
@@ -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
|
data/ui/spec/spec_helper.rb
CHANGED
Binary file
|
Binary file
|
@@ -99,15 +99,14 @@ module Hokusai
|
|
99
99
|
app = App.new(driver)
|
100
100
|
|
101
101
|
@socket = Thin::Server.new(*args, app)
|
102
|
-
|
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
|