hokusai-zero 0.1.1
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 +7 -0
- data/Dockerfile +26 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +91 -0
- data/LICENSE +21 -0
- data/README.md +28 -0
- data/ast/genheader +3 -0
- data/ast/include/hashmap.c +1151 -0
- data/ast/include/hashmap.c.license +20 -0
- data/ast/include/hashmap.h +54 -0
- data/ast/src/core/ast.c +448 -0
- data/ast/src/core/ast.h +259 -0
- data/ast/src/core/common.h +24 -0
- data/ast/src/core/component.c +85 -0
- data/ast/src/core/component.h +35 -0
- data/ast/src/core/hml.c +665 -0
- data/ast/src/core/hml.h +11 -0
- data/ast/src/core/input.c +458 -0
- data/ast/src/core/input.h +118 -0
- data/ast/src/core/style.c +101 -0
- data/ast/src/core/style.h +41 -0
- data/ast/src/core/text.c +784 -0
- data/ast/src/core/text.h +93 -0
- data/ast/src/core/util.c +140 -0
- data/ast/src/core/util.h +48 -0
- data/ast/src/hokusai.c +6 -0
- data/ast/src/hokusai.h +6 -0
- data/ast/test/fixtures/test.ui +13 -0
- data/ast/test/greatest.h +1266 -0
- data/ast/test/hokusai.c +14 -0
- data/ast/test/parser.c +234 -0
- data/ast/test/text.c +116 -0
- data/ext/extconf.rb +27 -0
- data/grammar/Cargo.lock +80 -0
- data/grammar/Cargo.toml +26 -0
- data/grammar/binding.gyp +20 -0
- data/grammar/bindings/node/binding.cc +28 -0
- data/grammar/bindings/node/index.js +19 -0
- data/grammar/bindings/rust/build.rs +40 -0
- data/grammar/bindings/rust/lib.rs +52 -0
- data/grammar/corpus/1_document.txt +131 -0
- data/grammar/corpus/2_selectors.txt +58 -0
- data/grammar/corpus/3_spaces.txt +69 -0
- data/grammar/corpus/4_errors.txt +10 -0
- data/grammar/corpus/5_macros.txt +175 -0
- data/grammar/corpus/6_styles.txt +81 -0
- data/grammar/grammar.js +275 -0
- data/grammar/package-lock.json +34 -0
- data/grammar/package.json +33 -0
- data/grammar/src/grammar.json +1269 -0
- data/grammar/src/node-types.json +474 -0
- data/grammar/src/parser.c +5772 -0
- data/grammar/src/scanner.c +258 -0
- data/grammar/src/tree_sitter/parser.h +230 -0
- data/grammar/src/tree_sitter/scanner.h +12 -0
- data/grammar/test.nml +10 -0
- data/hokusai.gemspec +19 -0
- data/ui/examples/assets/DigitalDisplay.ttf +0 -0
- data/ui/examples/assets/OpenSans-Regular.ttf +0 -0
- data/ui/examples/assets/addy.png +0 -0
- data/ui/examples/assets/baby_sean.png +0 -0
- data/ui/examples/assets/football-troll.png +0 -0
- data/ui/examples/assets/gear.png +0 -0
- data/ui/examples/assets/icecold.ttf +0 -0
- data/ui/examples/assets/science-troll.png +0 -0
- data/ui/examples/buddy.rb +31 -0
- data/ui/examples/clock.rb +58 -0
- data/ui/examples/counter.rb +123 -0
- data/ui/examples/dynamic.rb +147 -0
- data/ui/examples/foobar.rb +236 -0
- data/ui/examples/stock.rb +115 -0
- data/ui/examples/stock_decider/option.rb +74 -0
- data/ui/examples/tic_tac_toe.rb +246 -0
- data/ui/lib/lib_hokusai.rb +425 -0
- data/ui/spec/hokusai/ast_spec.rb +88 -0
- data/ui/spec/hokusai/automation/keys_transcoder_spec.rb +50 -0
- data/ui/spec/hokusai/automation/selector_spec.rb +68 -0
- data/ui/spec/hokusai/block_spec.rb +126 -0
- data/ui/spec/hokusai/directives_spec.rb +327 -0
- data/ui/spec/hokusai/e2e/client_spec.rb +58 -0
- data/ui/spec/hokusai/e2e/meta_spec.rb +42 -0
- data/ui/spec/hokusai/publisher_spec.rb +38 -0
- data/ui/spec/hokusai/slots_spec.rb +150 -0
- data/ui/spec/hokusai/util/piece_table_spec.rb +90 -0
- data/ui/spec/hokusai_spec.rb +0 -0
- data/ui/spec/spec_helper.rb +30 -0
- data/ui/src/hokusai/ast.rb +446 -0
- data/ui/src/hokusai/automation/client.rb +167 -0
- data/ui/src/hokusai/automation/constants.rb +98 -0
- data/ui/src/hokusai/automation/converters/selector_converter.rb +61 -0
- data/ui/src/hokusai/automation/driver.rb +54 -0
- data/ui/src/hokusai/automation/driver_command_queue.rb +50 -0
- data/ui/src/hokusai/automation/driver_commands/base.rb +79 -0
- data/ui/src/hokusai/automation/driver_commands/get_attribute.rb +41 -0
- data/ui/src/hokusai/automation/driver_commands/invoke.rb +33 -0
- data/ui/src/hokusai/automation/driver_commands/locate.rb +48 -0
- data/ui/src/hokusai/automation/driver_commands/trigger_keyboard.rb +94 -0
- data/ui/src/hokusai/automation/driver_commands/trigger_mouse.rb +213 -0
- data/ui/src/hokusai/automation/keys_transcoder.rb +128 -0
- data/ui/src/hokusai/automation/selector.rb +39 -0
- data/ui/src/hokusai/automation/server.rb +114 -0
- data/ui/src/hokusai/automation.rb +3 -0
- data/ui/src/hokusai/backends/raylib/config.rb +47 -0
- data/ui/src/hokusai/backends/raylib/font.rb +113 -0
- data/ui/src/hokusai/backends/raylib/keys.rb +124 -0
- data/ui/src/hokusai/backends/raylib.rb +449 -0
- data/ui/src/hokusai/backends/sdl2/Monaco.ttf +0 -0
- data/ui/src/hokusai/backends/sdl2/color.rb +12 -0
- data/ui/src/hokusai/backends/sdl2/config.rb +31 -0
- data/ui/src/hokusai/backends/sdl2/font.rb +127 -0
- data/ui/src/hokusai/backends/sdl2/keys.rb +119 -0
- data/ui/src/hokusai/backends/sdl2.rb +529 -0
- data/ui/src/hokusai/block.rb +237 -0
- data/ui/src/hokusai/blocks/button.rb +100 -0
- data/ui/src/hokusai/blocks/checkbox.rb +51 -0
- data/ui/src/hokusai/blocks/circle.rb +28 -0
- data/ui/src/hokusai/blocks/clipped.rb +23 -0
- data/ui/src/hokusai/blocks/cursor.rb +49 -0
- data/ui/src/hokusai/blocks/dynamic.rb +37 -0
- data/ui/src/hokusai/blocks/empty.rb +10 -0
- data/ui/src/hokusai/blocks/hblock.rb +35 -0
- data/ui/src/hokusai/blocks/image.rb +18 -0
- data/ui/src/hokusai/blocks/input.rb +200 -0
- data/ui/src/hokusai/blocks/label.rb +39 -0
- data/ui/src/hokusai/blocks/panel.rb +126 -0
- data/ui/src/hokusai/blocks/rect.rb +24 -0
- data/ui/src/hokusai/blocks/scissor_begin.rb +18 -0
- data/ui/src/hokusai/blocks/scissor_end.rb +12 -0
- data/ui/src/hokusai/blocks/scrollbar.rb +103 -0
- data/ui/src/hokusai/blocks/selectable.rb +77 -0
- data/ui/src/hokusai/blocks/svg.rb +20 -0
- data/ui/src/hokusai/blocks/text.rb +214 -0
- data/ui/src/hokusai/blocks/titlebar/osx.rb +145 -0
- data/ui/src/hokusai/blocks/toggle.rb +55 -0
- data/ui/src/hokusai/blocks/vblock.rb +35 -0
- data/ui/src/hokusai/commands/base.rb +22 -0
- data/ui/src/hokusai/commands/circle.rb +47 -0
- data/ui/src/hokusai/commands/image.rb +45 -0
- data/ui/src/hokusai/commands/rect.rb +158 -0
- data/ui/src/hokusai/commands/scissor.rb +22 -0
- data/ui/src/hokusai/commands/text.rb +92 -0
- data/ui/src/hokusai/commands.rb +87 -0
- data/ui/src/hokusai/diff.rb +124 -0
- data/ui/src/hokusai/error.rb +3 -0
- data/ui/src/hokusai/event.rb +54 -0
- data/ui/src/hokusai/events/keyboard.rb +84 -0
- data/ui/src/hokusai/events/mouse.rb +172 -0
- data/ui/src/hokusai/font.rb +280 -0
- data/ui/src/hokusai/meta.rb +152 -0
- data/ui/src/hokusai/mounting/loop_entry.rb +230 -0
- data/ui/src/hokusai/mounting/mount_entry.rb +74 -0
- data/ui/src/hokusai/mounting/update_entry.rb +101 -0
- data/ui/src/hokusai/node.rb +98 -0
- data/ui/src/hokusai/node_mounter.rb +102 -0
- data/ui/src/hokusai/painter.rb +214 -0
- data/ui/src/hokusai/publisher.rb +32 -0
- data/ui/src/hokusai/style.rb +72 -0
- data/ui/src/hokusai/types.rb +266 -0
- data/ui/src/hokusai/util/clamping_iterator.rb +202 -0
- data/ui/src/hokusai/util/piece_table.rb +111 -0
- data/ui/src/hokusai/util/selection.rb +145 -0
- data/ui/src/hokusai.rb +120 -0
- data/ui/vendor/.gitkeep +0 -0
- data/vendor/.gitkeep +0 -0
- data/xmake.lua +192 -0
- metadata +222 -0
@@ -0,0 +1,172 @@
|
|
1
|
+
module Hokusai
|
2
|
+
class MouseEvent < Event
|
3
|
+
extend Forwardable
|
4
|
+
|
5
|
+
attr_reader :input, :state
|
6
|
+
|
7
|
+
def initialize(input, state)
|
8
|
+
@input = input
|
9
|
+
@mouse = input.mouse
|
10
|
+
@left = @mouse.left
|
11
|
+
@right = @mouse.right
|
12
|
+
@middle = @mouse.middle
|
13
|
+
@state = state
|
14
|
+
end
|
15
|
+
|
16
|
+
def mouse
|
17
|
+
@mouse
|
18
|
+
end
|
19
|
+
|
20
|
+
def pos
|
21
|
+
mouse.pos
|
22
|
+
end
|
23
|
+
|
24
|
+
def delta
|
25
|
+
mouse.delta
|
26
|
+
end
|
27
|
+
|
28
|
+
def scroll
|
29
|
+
mouse.scroll
|
30
|
+
end
|
31
|
+
|
32
|
+
def scroll_delta
|
33
|
+
mouse.scroll_delta
|
34
|
+
end
|
35
|
+
|
36
|
+
def left
|
37
|
+
@left
|
38
|
+
end
|
39
|
+
|
40
|
+
def right
|
41
|
+
@right
|
42
|
+
end
|
43
|
+
|
44
|
+
def middle
|
45
|
+
@middle
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_json
|
49
|
+
hash = {}
|
50
|
+
hash[:pos] = { x: pos.x, y: pos.y }
|
51
|
+
|
52
|
+
[:left, :right, :middle].each do |button|
|
53
|
+
hash[button] = {
|
54
|
+
down: send(button).down,
|
55
|
+
up: send(button).up,
|
56
|
+
clicked: send(button).clicked,
|
57
|
+
released: send(button).released
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
hash[:scroll] = scroll
|
62
|
+
hash[:scroll_delta] = scroll_delta
|
63
|
+
|
64
|
+
hash.to_json
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def hovered(canvas)
|
70
|
+
LibHokusai.hoku_input_is_hovered(input.raw, canvas.to_hoku_rect)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class MouseMoveEvent < MouseEvent
|
75
|
+
name "mousemove"
|
76
|
+
|
77
|
+
def capture(block, _)
|
78
|
+
if matches(block) #&& (delta.y != 0.0000000000 && delta.x != 0.0000000000)
|
79
|
+
captures << block
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class ClickEvent < MouseEvent
|
85
|
+
name "click"
|
86
|
+
|
87
|
+
def capture(block, canvas)
|
88
|
+
if left[:clicked] && clicked(canvas)
|
89
|
+
block.node.meta.focus
|
90
|
+
|
91
|
+
if matches(block)
|
92
|
+
captures << block
|
93
|
+
end
|
94
|
+
elsif left[:clicked]
|
95
|
+
block.node.meta.blur
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def clicked(canvas)
|
100
|
+
LibHokusai.hoku_input_is_clicked(input.raw, canvas.to_hoku_rect)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class MouseUpEvent < MouseEvent
|
105
|
+
name "mouseup"
|
106
|
+
|
107
|
+
def capture(block, _)
|
108
|
+
if left[:up] && matches(block)
|
109
|
+
captures << block
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
class MouseDownEvent < MouseEvent
|
115
|
+
name "mousedown"
|
116
|
+
|
117
|
+
def capture(block, _)
|
118
|
+
if left[:down] && matches(block)
|
119
|
+
captures << block
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class WheelEvent < MouseEvent
|
125
|
+
name "wheel"
|
126
|
+
|
127
|
+
def capture(block, _)
|
128
|
+
if matches(block) && scroll_delta != 0.0
|
129
|
+
captures << block
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class HoverEvent < MouseEvent
|
135
|
+
name "hover"
|
136
|
+
|
137
|
+
def capture(block, _)
|
138
|
+
captures << block
|
139
|
+
end
|
140
|
+
|
141
|
+
def bubble
|
142
|
+
while block = captures.pop
|
143
|
+
block.emit(name, self)
|
144
|
+
|
145
|
+
cursor = block.node.meta.get_prop(:cursor)&.to_sym
|
146
|
+
|
147
|
+
if !state.set && cursor == :manual
|
148
|
+
state.set = true
|
149
|
+
end
|
150
|
+
|
151
|
+
if !state.set && cursor && cursor != :manual
|
152
|
+
Hokusai.set_mouse_cursor(cursor)
|
153
|
+
state.set = true
|
154
|
+
end
|
155
|
+
|
156
|
+
break if stopped
|
157
|
+
end
|
158
|
+
|
159
|
+
if !state.nil? && !state.set
|
160
|
+
Hokusai.set_mouse_cursor(:default)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class MouseOutEvent < MouseEvent
|
166
|
+
name "mouseout"
|
167
|
+
|
168
|
+
def capture(block, _)
|
169
|
+
captures << block if matches(block)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
module Hokusai
|
2
|
+
class Font
|
3
|
+
def clamp(text, size, width, initial_offset = 0.0)
|
4
|
+
raise Hokusai::Error.new("Font #clamp not implemented")
|
5
|
+
end
|
6
|
+
|
7
|
+
def clamp_markdown(text, size, width, initial_offset = 0.0)
|
8
|
+
raise Hokusai::Error.new("Font #clamp not implemented")
|
9
|
+
end
|
10
|
+
|
11
|
+
def height
|
12
|
+
raise Hokusai::Error.new("Font #height not implemented")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Clamping
|
17
|
+
class Char
|
18
|
+
attr_reader :raw
|
19
|
+
def initialize(raw)
|
20
|
+
@raw = raw
|
21
|
+
end
|
22
|
+
|
23
|
+
def width
|
24
|
+
raw[:width]
|
25
|
+
end
|
26
|
+
|
27
|
+
def offset
|
28
|
+
raw[:offset]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Group
|
33
|
+
attr_reader :raw
|
34
|
+
|
35
|
+
def initialize(raw)
|
36
|
+
@raw = raw
|
37
|
+
end
|
38
|
+
|
39
|
+
def offset
|
40
|
+
@offset ||= raw[:offset]
|
41
|
+
end
|
42
|
+
|
43
|
+
def size
|
44
|
+
@size ||= raw[:size]
|
45
|
+
end
|
46
|
+
|
47
|
+
def width
|
48
|
+
chars.sum(&:width)
|
49
|
+
end
|
50
|
+
|
51
|
+
def type
|
52
|
+
@type ||= raw[:type]
|
53
|
+
end
|
54
|
+
|
55
|
+
def normal?
|
56
|
+
@normal ||= type == LibHokusai::GROUP_NORMAL
|
57
|
+
end
|
58
|
+
|
59
|
+
def bold?
|
60
|
+
@bold ||= ((type & LibHokusai::GROUP_BOLD) != 0)
|
61
|
+
end
|
62
|
+
|
63
|
+
def italics?
|
64
|
+
@italics ||= ((type & LibHokusai::GROUP_ITALICS) != 0)
|
65
|
+
end
|
66
|
+
|
67
|
+
def link?
|
68
|
+
@link ||= ((type & LibHokusai::GROUP_LINK) != 0)
|
69
|
+
end
|
70
|
+
|
71
|
+
def code?
|
72
|
+
@code ||= type & LibHokusai::GROUP_CODE
|
73
|
+
end
|
74
|
+
|
75
|
+
def link
|
76
|
+
@href ||= raw[:payload].read_string
|
77
|
+
end
|
78
|
+
|
79
|
+
def chars
|
80
|
+
return @chars unless @chars.nil?
|
81
|
+
|
82
|
+
@chars = []
|
83
|
+
each_char do |char|
|
84
|
+
@chars << char
|
85
|
+
end
|
86
|
+
|
87
|
+
@chars
|
88
|
+
end
|
89
|
+
|
90
|
+
def each_char
|
91
|
+
char = raw[:chars]
|
92
|
+
i = 0
|
93
|
+
|
94
|
+
while !char.null?
|
95
|
+
yield Char.new(char), i
|
96
|
+
i += 1
|
97
|
+
char = char[:next_char]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class Segment
|
103
|
+
attr_reader :raw
|
104
|
+
|
105
|
+
def initialize(raw)
|
106
|
+
@raw = raw
|
107
|
+
end
|
108
|
+
|
109
|
+
def width(range = (offset...offset + size))
|
110
|
+
chars[range]&.sum(&:width) || 0.0
|
111
|
+
end
|
112
|
+
|
113
|
+
def offset
|
114
|
+
raw[:offset]
|
115
|
+
end
|
116
|
+
|
117
|
+
def size
|
118
|
+
raw[:size]
|
119
|
+
end
|
120
|
+
|
121
|
+
def chars
|
122
|
+
return @chars unless @chars.nil?
|
123
|
+
|
124
|
+
@chars = []
|
125
|
+
each_char do |char|
|
126
|
+
@chars << char
|
127
|
+
end
|
128
|
+
|
129
|
+
@chars
|
130
|
+
end
|
131
|
+
|
132
|
+
def each_char
|
133
|
+
char = raw[:chars]
|
134
|
+
i = 0
|
135
|
+
|
136
|
+
while !char.null?
|
137
|
+
yield Char.new(char), i
|
138
|
+
i += 1
|
139
|
+
char = char[:next_char]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def groups
|
144
|
+
return @groups unless @groups.nil?
|
145
|
+
|
146
|
+
@groups = []
|
147
|
+
each_group do |group|
|
148
|
+
@groups << group
|
149
|
+
end
|
150
|
+
|
151
|
+
@groups
|
152
|
+
end
|
153
|
+
|
154
|
+
def each_group
|
155
|
+
group = raw[:groups]
|
156
|
+
i = 0
|
157
|
+
until group.null?
|
158
|
+
yield Group.new(group), i
|
159
|
+
i.succ
|
160
|
+
group = group[:next_group]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def select_end
|
165
|
+
raw[:select_end]
|
166
|
+
end
|
167
|
+
|
168
|
+
def select_begin
|
169
|
+
raw[:select_begin]
|
170
|
+
end
|
171
|
+
|
172
|
+
def select_begin=(val)
|
173
|
+
raw[:select_begin] = val
|
174
|
+
end
|
175
|
+
|
176
|
+
def select_end=(val)
|
177
|
+
raw[:select_end] = val.nil? ? select_begin : val
|
178
|
+
end
|
179
|
+
|
180
|
+
def has_selection?
|
181
|
+
!select_end.nil? && !select_begin.nil?
|
182
|
+
end
|
183
|
+
|
184
|
+
def char_is_selected(char)
|
185
|
+
return false if select_begin.nil? || select_end.nil?
|
186
|
+
|
187
|
+
(select_begin..select_end).include?(char.offset)
|
188
|
+
end
|
189
|
+
|
190
|
+
def make_selection(start, stop)
|
191
|
+
self.select_begin = start
|
192
|
+
self.select_end = stop
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
attr_reader :raw, :markdown
|
197
|
+
|
198
|
+
def initialize(raw, markdown: false)
|
199
|
+
@markdown = markdown
|
200
|
+
@raw = raw
|
201
|
+
end
|
202
|
+
|
203
|
+
def segments
|
204
|
+
return @segments unless @segments.nil?
|
205
|
+
|
206
|
+
@segments = []
|
207
|
+
each_segment do |segment|
|
208
|
+
@segments << segment
|
209
|
+
end
|
210
|
+
|
211
|
+
@segments
|
212
|
+
end
|
213
|
+
|
214
|
+
def debug
|
215
|
+
LibHokusai.hoku_text_clamp_debug(raw)
|
216
|
+
end
|
217
|
+
|
218
|
+
def each_segment
|
219
|
+
segment = raw[:segments]
|
220
|
+
i = 0
|
221
|
+
|
222
|
+
until segment.null?
|
223
|
+
yield Segment.new(segment), i
|
224
|
+
i += 1
|
225
|
+
|
226
|
+
|
227
|
+
segment = segment[:next_segment]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def text(segment)
|
232
|
+
raw[:text][segment.offset, segment.size]
|
233
|
+
end
|
234
|
+
|
235
|
+
def [](offset, size)
|
236
|
+
raw[:text][offset, size]
|
237
|
+
end
|
238
|
+
|
239
|
+
def to_a
|
240
|
+
segments.map do |segment|
|
241
|
+
text(segment)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
class FontRegistry
|
247
|
+
attr_reader :fonts, :active_font
|
248
|
+
|
249
|
+
def initialize
|
250
|
+
@fonts = {}
|
251
|
+
@active_font = nil
|
252
|
+
end
|
253
|
+
|
254
|
+
def register(name, font)
|
255
|
+
raise Hokusai::Error.new("Font #{name} already registered") if fonts[name]
|
256
|
+
|
257
|
+
fonts[name] = font
|
258
|
+
end
|
259
|
+
|
260
|
+
def active_font_name
|
261
|
+
raise Hokusai::Error.new("No active font") if active_font.nil?
|
262
|
+
|
263
|
+
active_font
|
264
|
+
end
|
265
|
+
|
266
|
+
def activate(name)
|
267
|
+
raise Hokusai::Error.new("Font #{name} is not registered") unless fonts[name]
|
268
|
+
|
269
|
+
@active_font = name
|
270
|
+
end
|
271
|
+
|
272
|
+
def get(name)
|
273
|
+
fonts[name]
|
274
|
+
end
|
275
|
+
|
276
|
+
def active
|
277
|
+
fonts[active_font]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
require_relative "./publisher"
|
2
|
+
|
3
|
+
module Hokusai
|
4
|
+
class Meta
|
5
|
+
attr_reader :focused, :parent, :target, :updater,
|
6
|
+
:props, :publisher
|
7
|
+
|
8
|
+
def self.commands
|
9
|
+
@commands ||= Commands.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@focused = false
|
14
|
+
@parent = nil
|
15
|
+
@target = nil
|
16
|
+
@updater = nil
|
17
|
+
@props = nil
|
18
|
+
@publisher = Publisher.new
|
19
|
+
@children = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def node_count
|
23
|
+
count = children?&.size || 0
|
24
|
+
|
25
|
+
children?&.each do |child|
|
26
|
+
count += child.node.meta.node_count
|
27
|
+
end
|
28
|
+
|
29
|
+
count
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_child?(index)
|
33
|
+
return nil if @children.nil?
|
34
|
+
|
35
|
+
get_child(index)
|
36
|
+
end
|
37
|
+
|
38
|
+
def children=(values)
|
39
|
+
@children = values
|
40
|
+
end
|
41
|
+
|
42
|
+
def children?
|
43
|
+
return nil if @children.nil?
|
44
|
+
|
45
|
+
@children
|
46
|
+
end
|
47
|
+
|
48
|
+
def <<(child)
|
49
|
+
children! << child
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_child(index)
|
53
|
+
children![index]
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_child(index, value)
|
57
|
+
children![index] = value
|
58
|
+
end
|
59
|
+
|
60
|
+
def children!
|
61
|
+
@children ||= []
|
62
|
+
end
|
63
|
+
|
64
|
+
def props!
|
65
|
+
@props ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_prop?(name)
|
69
|
+
return nil if @props.nil?
|
70
|
+
|
71
|
+
get_prop(name)
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_prop(name, value)
|
75
|
+
@props ||= {}
|
76
|
+
|
77
|
+
@props[name] = value
|
78
|
+
end
|
79
|
+
|
80
|
+
def get_prop(name)
|
81
|
+
@props ||= {}
|
82
|
+
|
83
|
+
@props[name]
|
84
|
+
end
|
85
|
+
|
86
|
+
def focus
|
87
|
+
@focused = true
|
88
|
+
|
89
|
+
children?&.each do |child|
|
90
|
+
child.node.meta.focus
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def blur
|
95
|
+
@focused = false
|
96
|
+
|
97
|
+
children?&.each do |child|
|
98
|
+
child.node.meta.blur
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def on_update(target, &block)
|
103
|
+
@target = target
|
104
|
+
@updater = block
|
105
|
+
end
|
106
|
+
|
107
|
+
def update(block)
|
108
|
+
# pp props
|
109
|
+
# if parent_block = parent
|
110
|
+
if target_block = target
|
111
|
+
if updater_block = updater
|
112
|
+
# Hokusai::Pool.post do
|
113
|
+
block.public_send(:before_updated) if block.respond_to?(:before_updated)
|
114
|
+
|
115
|
+
updater_block.call(block, target_block, target_block)
|
116
|
+
block.public_send(:after_updated) if block.respond_to?(:after_updated)
|
117
|
+
|
118
|
+
# end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
# end
|
122
|
+
|
123
|
+
children?&.each do |child|
|
124
|
+
child.update
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def has_ast?(ast, index)
|
129
|
+
if portal = children![index]&.node&.portal
|
130
|
+
return portal.ast.object_id == ast.object_id
|
131
|
+
end
|
132
|
+
|
133
|
+
false
|
134
|
+
end
|
135
|
+
#
|
136
|
+
# def destroy
|
137
|
+
# children.each do |child|
|
138
|
+
# child.before_destroy if child.respond_to?(:before_destroy)
|
139
|
+
# child.node.destroy
|
140
|
+
# end
|
141
|
+
# end
|
142
|
+
|
143
|
+
def child_delete(index)
|
144
|
+
if child = children![index]
|
145
|
+
child.before_destroy if child.respond_to?(:before_destroy)
|
146
|
+
child.node.destroy
|
147
|
+
|
148
|
+
children!.delete_at(index)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|