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.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/ast/src/core/input.c +135 -0
- data/ast/src/core/input.h +32 -0
- data/ast/test/hokusai.c +2 -0
- data/ast/test/input.c +44 -0
- data/hokusai.gemspec +1 -2
- data/ui/examples/drag.rb +154 -0
- data/ui/examples/embedded.rb +58 -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 +20 -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 +48 -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 +540 -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/touch.rb +66 -0
- data/ui/src/hokusai/painter.rb +22 -0
- data/ui/src/hokusai/types.rb +89 -0
- data/ui/src/hokusai.rb +4 -9
- data/xmake.lua +1 -1
- metadata +25 -22
- data/ui/src/hokusai/assets/chevron-down.svg +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6b346169398fdc8ace4e949627b34928b44230de71c120dc1b7ec2e3cb377c5
|
4
|
+
data.tar.gz: 444a5c3581cc74ca1537f2682cd0a1fd3859164f92a773af738a3fea434d579f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9e491ff21f1ed5532ae4b265c2084f3599a1c242f68cd14974d9ccd2f0b9cc8d39897ff38795183460641aea0b62984fcf3cdcaea1432bc076b0bf4844e12c7
|
7
|
+
data.tar.gz: 80a602eff3310633a24f4edc99b7191d2d367a1a826e0f591ac4bece88119088551566cf82779f138f757c5fcd8c651efae8be1188b0c77c2131725aa016de87
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,7 +8,6 @@ GIT
|
|
8
8
|
GEM
|
9
9
|
remote: https://www.rubygems.org/
|
10
10
|
specs:
|
11
|
-
concurrent-ruby (1.3.5)
|
12
11
|
daemons (1.4.1)
|
13
12
|
diff-lcs (1.6.1)
|
14
13
|
domain_name (0.6.20240107)
|
@@ -77,7 +76,6 @@ PLATFORMS
|
|
77
76
|
x86_64-linux
|
78
77
|
|
79
78
|
DEPENDENCIES
|
80
|
-
concurrent-ruby
|
81
79
|
ffi!
|
82
80
|
memory_profiler
|
83
81
|
mini_portile2 (~> 2.0.0)
|
data/ast/src/core/input.c
CHANGED
@@ -4,6 +4,134 @@
|
|
4
4
|
#include "input.h"
|
5
5
|
#include <stdio.h>
|
6
6
|
|
7
|
+
#define NANO_TO_MILLISECONDS 1000000
|
8
|
+
|
9
|
+
int hoku_input_touch_init(hoku_input_touch** embedded, int max_touch_positions)
|
10
|
+
{
|
11
|
+
hoku_input_touch* out = malloc(sizeof(hoku_input_touch));
|
12
|
+
if (!out) return -1;
|
13
|
+
|
14
|
+
out->last_touch_positions = malloc(sizeof(hoku_dvec2*) * max_touch_positions);
|
15
|
+
if (out->last_touch_positions == NULL) return -1;
|
16
|
+
|
17
|
+
out->touch_positions = malloc(sizeof(hoku_dvec2*) * max_touch_positions);
|
18
|
+
if (out->touch_positions == NULL) return -1;
|
19
|
+
|
20
|
+
for (int i=0; i < max_touch_positions; i++)
|
21
|
+
{
|
22
|
+
out->last_touch_positions[i] = malloc(sizeof(hoku_dvec2));
|
23
|
+
if (out->last_touch_positions[i] == NULL) return -1;
|
24
|
+
out->last_touch_positions[i]->x = -1.0;
|
25
|
+
out->last_touch_positions[i]->y = -1.0;
|
26
|
+
|
27
|
+
|
28
|
+
out->touch_positions[i] = malloc(sizeof(hoku_dvec2));
|
29
|
+
if (out->touch_positions[i] == NULL) return -1;
|
30
|
+
out->touch_positions[i]->x = -1.0;
|
31
|
+
out->touch_positions[i]->y = -1.0;
|
32
|
+
}
|
33
|
+
|
34
|
+
out->touch_len = max_touch_positions;
|
35
|
+
out->touch_count = 0;
|
36
|
+
out->touching_now = false;
|
37
|
+
out->timer = 0;
|
38
|
+
|
39
|
+
*embedded = out;
|
40
|
+
return 0;
|
41
|
+
}
|
42
|
+
|
43
|
+
long hoku_input_touch_duration(hoku_input* input)
|
44
|
+
{
|
45
|
+
return input->touch->timer * NANO_TO_MILLISECONDS;
|
46
|
+
}
|
47
|
+
|
48
|
+
bool hoku_input_touch_tapped(hoku_input* input)
|
49
|
+
{
|
50
|
+
if (input->touch->touching_now == false && input->touch->last_touch_positions[0] != NULL) return true;
|
51
|
+
|
52
|
+
return false;
|
53
|
+
}
|
54
|
+
|
55
|
+
bool hoku_input_touch_swiped(hoku_input* input, float threshold)
|
56
|
+
{
|
57
|
+
if (input->touch->touching_now == false)
|
58
|
+
{
|
59
|
+
hoku_dvec2* last = input->touch->last_touch_positions[0];
|
60
|
+
hoku_dvec2* now = input->touch->touch_positions[0];
|
61
|
+
|
62
|
+
if (last->x == -1.0 || last->y == -1.0) return false;
|
63
|
+
if (last == NULL || now == NULL) return false;
|
64
|
+
|
65
|
+
return (abs((int)(now->x - last->x)) >= threshold || abs((int)(now->y - last->y)) >= threshold);
|
66
|
+
}
|
67
|
+
|
68
|
+
return false;
|
69
|
+
}
|
70
|
+
|
71
|
+
bool hoku_input_touch_pinched(hoku_input* input)
|
72
|
+
{
|
73
|
+
return false;
|
74
|
+
}
|
75
|
+
|
76
|
+
bool hoku_input_touch_longtapped(hoku_input* input, int threshold)
|
77
|
+
{
|
78
|
+
if (input->touch->touching_now && input->touch->timer > 0l)
|
79
|
+
{
|
80
|
+
hoku_dvec2* last = input->touch->last_touch_positions[0];
|
81
|
+
hoku_dvec2* now = input->touch->touch_positions[0];
|
82
|
+
|
83
|
+
return (abs((int)(now->x - last->x)) < threshold && abs((int)(now->y - last->y)) < threshold);
|
84
|
+
}
|
85
|
+
|
86
|
+
return false;
|
87
|
+
}
|
88
|
+
|
89
|
+
void hoku_input_clear_touch(hoku_input* input, int index)
|
90
|
+
{
|
91
|
+
input->touch->touching_now = false;
|
92
|
+
input->touch->timer = 0l;
|
93
|
+
}
|
94
|
+
|
95
|
+
int hoku_input_record_touch(hoku_input* input, int index, float x, float y)
|
96
|
+
{
|
97
|
+
struct timespec start;
|
98
|
+
if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) return -1;
|
99
|
+
|
100
|
+
if (!(input->touch->touching_now))
|
101
|
+
{
|
102
|
+
input->touch->last_touch_positions[index]->x = input->touch->touch_positions[index]->x;
|
103
|
+
input->touch->last_touch_positions[index]->y = input->touch->touch_positions[index]->y;
|
104
|
+
|
105
|
+
input->touch->timer = start.tv_nsec;
|
106
|
+
}
|
107
|
+
else
|
108
|
+
{
|
109
|
+
input->touch->timer = start.tv_nsec - input->touch->timer;
|
110
|
+
}
|
111
|
+
|
112
|
+
input->touch->touch_positions[index]->x = x;
|
113
|
+
input->touch->touch_positions[index]->y = y;
|
114
|
+
input->touch->touching_now = true;
|
115
|
+
|
116
|
+
return 0;
|
117
|
+
}
|
118
|
+
|
119
|
+
int hoku_input_attach_touch(hoku_input* input, int max_touch_count)
|
120
|
+
{
|
121
|
+
hoku_input_touch* touch;
|
122
|
+
if (hoku_input_touch_init(&touch, max_touch_count) == -1) return -1;
|
123
|
+
input->touch = touch;
|
124
|
+
|
125
|
+
return 0;
|
126
|
+
}
|
127
|
+
|
128
|
+
void hoku_input_touch_free(hoku_input_touch* embedded)
|
129
|
+
{
|
130
|
+
free(embedded->touch_positions);
|
131
|
+
free(embedded->last_touch_positions);
|
132
|
+
free(embedded);
|
133
|
+
}
|
134
|
+
|
7
135
|
static int hoku_keycodes[HOKU_KEY_MAX] = {
|
8
136
|
0,39,44,45,46,47,48,49,50,51,52,53,54,55,56,57,59,61,65,66,67,68,69,
|
9
137
|
70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,
|
@@ -273,6 +401,12 @@ void hoku_input_free(hoku_input* input)
|
|
273
401
|
{
|
274
402
|
hoku_input_keyboard_free(input->keyboard);
|
275
403
|
hoku_input_mouse_free(input->mouse);
|
404
|
+
|
405
|
+
if (input->touch)
|
406
|
+
{
|
407
|
+
hoku_input_touch_free(input->touch);
|
408
|
+
}
|
409
|
+
|
276
410
|
free(input);
|
277
411
|
}
|
278
412
|
|
@@ -298,6 +432,7 @@ int hoku_input_init(hoku_input** input)
|
|
298
432
|
return -1;
|
299
433
|
}
|
300
434
|
init->keyboard = keyboard;
|
435
|
+
init->touch = NULL;
|
301
436
|
|
302
437
|
*input = init;
|
303
438
|
return 0;
|
data/ast/src/core/input.h
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include "common.h"
|
5
5
|
#include <stdbool.h>
|
6
6
|
#include <stdlib.h>
|
7
|
+
#include <time.h>
|
7
8
|
|
8
9
|
typedef struct HmlInputMouseButton
|
9
10
|
{
|
@@ -87,13 +88,44 @@ typedef struct HmlInputKeyboard
|
|
87
88
|
bool collecting;
|
88
89
|
} hoku_input_keyboard;
|
89
90
|
|
91
|
+
typedef enum HmlDragDirection {
|
92
|
+
HOKU_DRAG_UP,
|
93
|
+
HOKU_DRAG_DOWN,
|
94
|
+
HOKU_DRAG_LEFT,
|
95
|
+
HOKU_DRAG_RIGHT
|
96
|
+
} hoku_drag_direction;
|
97
|
+
|
98
|
+
typedef enum HmlPinchDirection {
|
99
|
+
HOKU_PINCH_IN,
|
100
|
+
HOKU_PINCH_OUT
|
101
|
+
} hoku_pinch_direction;
|
102
|
+
|
103
|
+
typedef struct HmlInputTouch
|
104
|
+
{
|
105
|
+
int touch_len;
|
106
|
+
int touch_count;
|
107
|
+
bool touching_now;
|
108
|
+
long timer;
|
109
|
+
hoku_dvec2** last_touch_positions;
|
110
|
+
hoku_dvec2** touch_positions;
|
111
|
+
} hoku_input_touch;
|
112
|
+
|
90
113
|
typedef struct HmlInput
|
91
114
|
{
|
92
115
|
hoku_input_keyboard* keyboard;
|
93
116
|
hoku_input_mouse* mouse;
|
117
|
+
hoku_input_touch* touch;
|
94
118
|
} hoku_input;
|
95
119
|
|
96
120
|
|
121
|
+
long hoku_input_touch_duration(hoku_input* input);
|
122
|
+
bool hoku_input_touch_tapped(hoku_input* input);
|
123
|
+
bool hoku_input_touch_swiped(hoku_input* input, float threshold);
|
124
|
+
bool hoku_input_touch_longtapped(hoku_input* input, int threshold);
|
125
|
+
void hoku_input_clear_touch(hoku_input* input, int index);
|
126
|
+
int hoku_input_record_touch(hoku_input* input, int index, float x, float y);
|
127
|
+
int hoku_input_attach_touch(hoku_input* input, int max_touch_count);
|
128
|
+
|
97
129
|
int hoku_input_keyboard_init(hoku_input_keyboard** keyboard);
|
98
130
|
int hoku_input_mouse_init(hoku_input_mouse** mouse);
|
99
131
|
int hoku_input_init(hoku_input** input);
|
data/ast/test/hokusai.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "greatest.h"
|
2
2
|
#include "parser.c"
|
3
3
|
#include "text.c"
|
4
|
+
#include "input.c"
|
4
5
|
|
5
6
|
GREATEST_MAIN_DEFS();
|
6
7
|
|
@@ -9,6 +10,7 @@ int main(int argc, char** argv) {
|
|
9
10
|
|
10
11
|
RUN_SUITE(hoku_parser_suite);
|
11
12
|
RUN_SUITE(hoku_text_suite);
|
13
|
+
RUN_SUITE(hoku_input_suite);
|
12
14
|
|
13
15
|
GREATEST_MAIN_END();
|
14
16
|
}
|
data/ast/test/input.c
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#include "../src/core/input.c"
|
2
|
+
#include<unistd.h>
|
3
|
+
|
4
|
+
TEST test_hoku_input_touch_basic()
|
5
|
+
{
|
6
|
+
hoku_input* input;
|
7
|
+
int ret = hoku_input_init(&input);
|
8
|
+
ASSERT_EQ_FMT(ret, 0, "%d");
|
9
|
+
|
10
|
+
ret = hoku_input_attach_touch(input, 2);
|
11
|
+
ASSERT_EQ_FMT(ret, 0, "%d");
|
12
|
+
|
13
|
+
hoku_input_record_touch(input, 0, 1.0, 2.0);
|
14
|
+
hoku_input_clear_touch(input, 0);
|
15
|
+
|
16
|
+
bool tapped = hoku_input_touch_tapped(input);
|
17
|
+
bool swiped = hoku_input_touch_swiped(input, 4);
|
18
|
+
|
19
|
+
ASSERT_EQ_FMT(1, tapped, "%d");
|
20
|
+
ASSERT_EQ_FMT(0, swiped, "%d");
|
21
|
+
|
22
|
+
hoku_input_record_touch(input, 0, 1.0, 2.0);
|
23
|
+
usleep(1000);
|
24
|
+
hoku_input_record_touch(input, 0, 3.0, 1.0);
|
25
|
+
|
26
|
+
bool longtapped = hoku_input_touch_longtapped(input, 4);
|
27
|
+
|
28
|
+
hoku_input_clear_touch(input, 0);
|
29
|
+
swiped = hoku_input_touch_swiped(input, 1.0);
|
30
|
+
|
31
|
+
ASSERT_EQ_FMT(1, longtapped, "%d");
|
32
|
+
ASSERT_EQ_FMT(1, swiped, "%d");
|
33
|
+
// ASSERT_EQ_FMT(pinched, 0, "%d");
|
34
|
+
|
35
|
+
hoku_input_free(input);
|
36
|
+
|
37
|
+
PASS();
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
SUITE(hoku_input_suite)
|
42
|
+
{
|
43
|
+
RUN_TEST(test_hoku_input_touch_basic);
|
44
|
+
}
|
data/hokusai.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'hokusai-zero'
|
3
|
-
s.version = '0.2.6-
|
3
|
+
s.version = '0.2.6-pinephone2'
|
4
4
|
s.licenses = ['MIT']
|
5
5
|
s.summary = "A Ruby library for writing GUI applications"
|
6
6
|
s.authors = ["skinnyjames"]
|
@@ -16,7 +16,6 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.metadata = { "source_code_uri" => "https://codeberg.org/skinnyjames/hokusai" }
|
17
17
|
|
18
18
|
s.add_dependency "ffi", "~> 1.16"
|
19
|
-
s.add_dependency "concurrent-ruby", "~> 1.3.4"
|
20
19
|
s.add_dependency "raylib-bindings", "~> 0.7.9"
|
21
20
|
s.add_dependency "sdl2-bindings", "~> 0.2.3"
|
22
21
|
s.add_dependency "memory_profiler"
|
data/ui/examples/drag.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require_relative "../src/hokusai"
|
2
|
+
require_relative "../src/hokusai/backends/raylib"
|
3
|
+
require "ostruct"
|
4
|
+
|
5
|
+
class Item < Hokusai::Block
|
6
|
+
style <<~EOF
|
7
|
+
[style]
|
8
|
+
circleStyle {
|
9
|
+
cursor: "pointer";
|
10
|
+
}
|
11
|
+
EOF
|
12
|
+
template <<~EOF
|
13
|
+
[template]
|
14
|
+
empty {
|
15
|
+
...circleStyle
|
16
|
+
:color="color"
|
17
|
+
@mousedown="start_drag"
|
18
|
+
@mouseup="release_drag"
|
19
|
+
@mousemove="emit_drag"
|
20
|
+
}
|
21
|
+
EOF
|
22
|
+
|
23
|
+
uses(empty: Hokusai::Blocks::Empty)
|
24
|
+
|
25
|
+
computed :index
|
26
|
+
computed! :pos
|
27
|
+
computed! :color
|
28
|
+
|
29
|
+
attr_accessor :dragging
|
30
|
+
|
31
|
+
def initialize(**props)
|
32
|
+
@dragging = false
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def contains(p)
|
38
|
+
(((p.x - pos[0]) * (p.x - pos[0]) + (p.y - pos[1]) * (p.y - pos[1])) <= 40 * 40)
|
39
|
+
end
|
40
|
+
|
41
|
+
def start_drag(event)
|
42
|
+
if event.left.down && contains(event.pos)
|
43
|
+
|
44
|
+
self.dragging = true
|
45
|
+
node.meta.set_prop(:z, 2)
|
46
|
+
node.meta.set_prop(:position, "absolute")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def release_drag(event)
|
51
|
+
if dragging
|
52
|
+
emit("done", index)
|
53
|
+
self.dragging = false
|
54
|
+
|
55
|
+
node.meta.set_prop(:z, nil)
|
56
|
+
node.meta.set_prop(:position, nil)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def emit_drag(event)
|
61
|
+
if dragging && event.left.down
|
62
|
+
emit("drag", index, [event.pos.x, event.pos.y])
|
63
|
+
elsif dragging
|
64
|
+
emit("done", index)
|
65
|
+
|
66
|
+
self.dragging = false
|
67
|
+
node.meta.set_prop(:z, nil)
|
68
|
+
node.meta.set_prop(:position, nil)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def render(canvas)
|
73
|
+
canvas.x = canvas.x + (canvas.width / 2)
|
74
|
+
canvas.y = canvas.y + canvas.height / 2
|
75
|
+
|
76
|
+
circle(pos[0], pos[1], 40) do |command|
|
77
|
+
command.color = color
|
78
|
+
end
|
79
|
+
|
80
|
+
yield canvas
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
class Drag < Hokusai::Block
|
86
|
+
template <<~EOF
|
87
|
+
[template]
|
88
|
+
vblock { background="233,233,233" }
|
89
|
+
[for="thing in items"]
|
90
|
+
item {
|
91
|
+
:z="z(index)"
|
92
|
+
:key="key(index, thing)"
|
93
|
+
:index="index"
|
94
|
+
@drag="update_position"
|
95
|
+
@done="update_drag_state"
|
96
|
+
:pos="pos(thing)"
|
97
|
+
:color="color(thing)"
|
98
|
+
}
|
99
|
+
EOF
|
100
|
+
|
101
|
+
uses(
|
102
|
+
vblock: Hokusai::Blocks::Vblock,
|
103
|
+
item: Item
|
104
|
+
)
|
105
|
+
|
106
|
+
attr_reader :items
|
107
|
+
|
108
|
+
def z(index)
|
109
|
+
items[index].dragging ? 2 : nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def update_drag_state(index)
|
113
|
+
items[index].dragging = false
|
114
|
+
end
|
115
|
+
|
116
|
+
def key(index, thing)
|
117
|
+
"key-#{index}"
|
118
|
+
end
|
119
|
+
|
120
|
+
def pos(thing)
|
121
|
+
thing.position
|
122
|
+
end
|
123
|
+
|
124
|
+
def color(thing)
|
125
|
+
thing.color
|
126
|
+
end
|
127
|
+
|
128
|
+
def update_position(index, pos)
|
129
|
+
items[index].dragging = true
|
130
|
+
items[index].position = pos
|
131
|
+
end
|
132
|
+
|
133
|
+
def initialize(**args)
|
134
|
+
@items = [[0, 10, [222,222,0]], [100, 100, [0,222,222]], [300, 300, [0, 222, 0]]].map do |list|
|
135
|
+
item = OpenStruct.new
|
136
|
+
item.position = [list[0], list[1]]
|
137
|
+
item.color = Hokusai::Color.convert(list[2])
|
138
|
+
item.dragging = false
|
139
|
+
item
|
140
|
+
end
|
141
|
+
|
142
|
+
pp items
|
143
|
+
|
144
|
+
super
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
Hokusai::Backends::RaylibBackend.run(Drag) do |config|
|
149
|
+
config.after_load do
|
150
|
+
font = Hokusai::Backends::RaylibBackend::Font.from("#{__dir__}/assets/Inter-Regular.ttf")
|
151
|
+
Hokusai.fonts.register "inter", font
|
152
|
+
Hokusai.fonts.activate "inter"
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative "../src/hokusai"
|
2
|
+
require_relative "../src/hokusai/backends/embedded"
|
3
|
+
|
4
|
+
class App < Hokusai::Block
|
5
|
+
template <<~EOF
|
6
|
+
[template]
|
7
|
+
button {
|
8
|
+
@clicked="clear_text"
|
9
|
+
height="30"
|
10
|
+
content="clear"
|
11
|
+
}
|
12
|
+
panel {
|
13
|
+
@swipe="handle_swipe"
|
14
|
+
@taphold="handle_taphold"
|
15
|
+
@pinch="handle_pinch"
|
16
|
+
}
|
17
|
+
text {
|
18
|
+
:content="text"
|
19
|
+
:size="15"
|
20
|
+
}
|
21
|
+
EOF
|
22
|
+
|
23
|
+
uses(
|
24
|
+
button: Hokusai::Blocks::Button,
|
25
|
+
panel: Hokusai::Blocks::Panel,
|
26
|
+
text: Hokusai::Blocks::Text
|
27
|
+
)
|
28
|
+
|
29
|
+
attr_accessor :text
|
30
|
+
|
31
|
+
def initialize(**args)
|
32
|
+
@text = ""
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear_text(event)
|
38
|
+
self.text = ""
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_pinch(event)
|
42
|
+
self.text += "Pinch: #{event.pinch_direction} - #{event.pinch_pos.x}x#{event.pinch_pos.y} (#{event.pinch_angle})\n\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_swipe(event)
|
46
|
+
self.text += "Swipe: #{event.drag_direction} - #{event.drag_pos.x}x#{event.drag_pos.y} (#{event.drag_angle})\n\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
def handle_taphold(event)
|
50
|
+
self.text += "Taphold #{event.hold_duration}\n\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
Hokusai::Backends::EmbeddedBackend.run(App) do |config|
|
55
|
+
config.after_load do
|
56
|
+
Hokusai.maximize_window
|
57
|
+
end
|
58
|
+
end
|
data/ui/examples/game.rb
ADDED
@@ -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
|
+
|