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.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/Dockerfile +26 -0
  3. data/Gemfile +15 -0
  4. data/Gemfile.lock +91 -0
  5. data/LICENSE +21 -0
  6. data/README.md +28 -0
  7. data/ast/genheader +3 -0
  8. data/ast/include/hashmap.c +1151 -0
  9. data/ast/include/hashmap.c.license +20 -0
  10. data/ast/include/hashmap.h +54 -0
  11. data/ast/src/core/ast.c +448 -0
  12. data/ast/src/core/ast.h +259 -0
  13. data/ast/src/core/common.h +24 -0
  14. data/ast/src/core/component.c +85 -0
  15. data/ast/src/core/component.h +35 -0
  16. data/ast/src/core/hml.c +665 -0
  17. data/ast/src/core/hml.h +11 -0
  18. data/ast/src/core/input.c +458 -0
  19. data/ast/src/core/input.h +118 -0
  20. data/ast/src/core/style.c +101 -0
  21. data/ast/src/core/style.h +41 -0
  22. data/ast/src/core/text.c +784 -0
  23. data/ast/src/core/text.h +93 -0
  24. data/ast/src/core/util.c +140 -0
  25. data/ast/src/core/util.h +48 -0
  26. data/ast/src/hokusai.c +6 -0
  27. data/ast/src/hokusai.h +6 -0
  28. data/ast/test/fixtures/test.ui +13 -0
  29. data/ast/test/greatest.h +1266 -0
  30. data/ast/test/hokusai.c +14 -0
  31. data/ast/test/parser.c +234 -0
  32. data/ast/test/text.c +116 -0
  33. data/ext/extconf.rb +27 -0
  34. data/grammar/Cargo.lock +80 -0
  35. data/grammar/Cargo.toml +26 -0
  36. data/grammar/binding.gyp +20 -0
  37. data/grammar/bindings/node/binding.cc +28 -0
  38. data/grammar/bindings/node/index.js +19 -0
  39. data/grammar/bindings/rust/build.rs +40 -0
  40. data/grammar/bindings/rust/lib.rs +52 -0
  41. data/grammar/corpus/1_document.txt +131 -0
  42. data/grammar/corpus/2_selectors.txt +58 -0
  43. data/grammar/corpus/3_spaces.txt +69 -0
  44. data/grammar/corpus/4_errors.txt +10 -0
  45. data/grammar/corpus/5_macros.txt +175 -0
  46. data/grammar/corpus/6_styles.txt +81 -0
  47. data/grammar/grammar.js +275 -0
  48. data/grammar/package-lock.json +34 -0
  49. data/grammar/package.json +33 -0
  50. data/grammar/src/grammar.json +1269 -0
  51. data/grammar/src/node-types.json +474 -0
  52. data/grammar/src/parser.c +5772 -0
  53. data/grammar/src/scanner.c +258 -0
  54. data/grammar/src/tree_sitter/parser.h +230 -0
  55. data/grammar/src/tree_sitter/scanner.h +12 -0
  56. data/grammar/test.nml +10 -0
  57. data/hokusai.gemspec +19 -0
  58. data/ui/examples/assets/DigitalDisplay.ttf +0 -0
  59. data/ui/examples/assets/OpenSans-Regular.ttf +0 -0
  60. data/ui/examples/assets/addy.png +0 -0
  61. data/ui/examples/assets/baby_sean.png +0 -0
  62. data/ui/examples/assets/football-troll.png +0 -0
  63. data/ui/examples/assets/gear.png +0 -0
  64. data/ui/examples/assets/icecold.ttf +0 -0
  65. data/ui/examples/assets/science-troll.png +0 -0
  66. data/ui/examples/buddy.rb +31 -0
  67. data/ui/examples/clock.rb +58 -0
  68. data/ui/examples/counter.rb +123 -0
  69. data/ui/examples/dynamic.rb +147 -0
  70. data/ui/examples/foobar.rb +236 -0
  71. data/ui/examples/stock.rb +115 -0
  72. data/ui/examples/stock_decider/option.rb +74 -0
  73. data/ui/examples/tic_tac_toe.rb +246 -0
  74. data/ui/lib/lib_hokusai.rb +425 -0
  75. data/ui/spec/hokusai/ast_spec.rb +88 -0
  76. data/ui/spec/hokusai/automation/keys_transcoder_spec.rb +50 -0
  77. data/ui/spec/hokusai/automation/selector_spec.rb +68 -0
  78. data/ui/spec/hokusai/block_spec.rb +126 -0
  79. data/ui/spec/hokusai/directives_spec.rb +327 -0
  80. data/ui/spec/hokusai/e2e/client_spec.rb +58 -0
  81. data/ui/spec/hokusai/e2e/meta_spec.rb +42 -0
  82. data/ui/spec/hokusai/publisher_spec.rb +38 -0
  83. data/ui/spec/hokusai/slots_spec.rb +150 -0
  84. data/ui/spec/hokusai/util/piece_table_spec.rb +90 -0
  85. data/ui/spec/hokusai_spec.rb +0 -0
  86. data/ui/spec/spec_helper.rb +30 -0
  87. data/ui/src/hokusai/ast.rb +446 -0
  88. data/ui/src/hokusai/automation/client.rb +167 -0
  89. data/ui/src/hokusai/automation/constants.rb +98 -0
  90. data/ui/src/hokusai/automation/converters/selector_converter.rb +61 -0
  91. data/ui/src/hokusai/automation/driver.rb +54 -0
  92. data/ui/src/hokusai/automation/driver_command_queue.rb +50 -0
  93. data/ui/src/hokusai/automation/driver_commands/base.rb +79 -0
  94. data/ui/src/hokusai/automation/driver_commands/get_attribute.rb +41 -0
  95. data/ui/src/hokusai/automation/driver_commands/invoke.rb +33 -0
  96. data/ui/src/hokusai/automation/driver_commands/locate.rb +48 -0
  97. data/ui/src/hokusai/automation/driver_commands/trigger_keyboard.rb +94 -0
  98. data/ui/src/hokusai/automation/driver_commands/trigger_mouse.rb +213 -0
  99. data/ui/src/hokusai/automation/keys_transcoder.rb +128 -0
  100. data/ui/src/hokusai/automation/selector.rb +39 -0
  101. data/ui/src/hokusai/automation/server.rb +114 -0
  102. data/ui/src/hokusai/automation.rb +3 -0
  103. data/ui/src/hokusai/backends/raylib/config.rb +47 -0
  104. data/ui/src/hokusai/backends/raylib/font.rb +113 -0
  105. data/ui/src/hokusai/backends/raylib/keys.rb +124 -0
  106. data/ui/src/hokusai/backends/raylib.rb +449 -0
  107. data/ui/src/hokusai/backends/sdl2/Monaco.ttf +0 -0
  108. data/ui/src/hokusai/backends/sdl2/color.rb +12 -0
  109. data/ui/src/hokusai/backends/sdl2/config.rb +31 -0
  110. data/ui/src/hokusai/backends/sdl2/font.rb +127 -0
  111. data/ui/src/hokusai/backends/sdl2/keys.rb +119 -0
  112. data/ui/src/hokusai/backends/sdl2.rb +529 -0
  113. data/ui/src/hokusai/block.rb +237 -0
  114. data/ui/src/hokusai/blocks/button.rb +100 -0
  115. data/ui/src/hokusai/blocks/checkbox.rb +51 -0
  116. data/ui/src/hokusai/blocks/circle.rb +28 -0
  117. data/ui/src/hokusai/blocks/clipped.rb +23 -0
  118. data/ui/src/hokusai/blocks/cursor.rb +49 -0
  119. data/ui/src/hokusai/blocks/dynamic.rb +37 -0
  120. data/ui/src/hokusai/blocks/empty.rb +10 -0
  121. data/ui/src/hokusai/blocks/hblock.rb +35 -0
  122. data/ui/src/hokusai/blocks/image.rb +18 -0
  123. data/ui/src/hokusai/blocks/input.rb +200 -0
  124. data/ui/src/hokusai/blocks/label.rb +39 -0
  125. data/ui/src/hokusai/blocks/panel.rb +126 -0
  126. data/ui/src/hokusai/blocks/rect.rb +24 -0
  127. data/ui/src/hokusai/blocks/scissor_begin.rb +18 -0
  128. data/ui/src/hokusai/blocks/scissor_end.rb +12 -0
  129. data/ui/src/hokusai/blocks/scrollbar.rb +103 -0
  130. data/ui/src/hokusai/blocks/selectable.rb +77 -0
  131. data/ui/src/hokusai/blocks/svg.rb +20 -0
  132. data/ui/src/hokusai/blocks/text.rb +214 -0
  133. data/ui/src/hokusai/blocks/titlebar/osx.rb +145 -0
  134. data/ui/src/hokusai/blocks/toggle.rb +55 -0
  135. data/ui/src/hokusai/blocks/vblock.rb +35 -0
  136. data/ui/src/hokusai/commands/base.rb +22 -0
  137. data/ui/src/hokusai/commands/circle.rb +47 -0
  138. data/ui/src/hokusai/commands/image.rb +45 -0
  139. data/ui/src/hokusai/commands/rect.rb +158 -0
  140. data/ui/src/hokusai/commands/scissor.rb +22 -0
  141. data/ui/src/hokusai/commands/text.rb +92 -0
  142. data/ui/src/hokusai/commands.rb +87 -0
  143. data/ui/src/hokusai/diff.rb +124 -0
  144. data/ui/src/hokusai/error.rb +3 -0
  145. data/ui/src/hokusai/event.rb +54 -0
  146. data/ui/src/hokusai/events/keyboard.rb +84 -0
  147. data/ui/src/hokusai/events/mouse.rb +172 -0
  148. data/ui/src/hokusai/font.rb +280 -0
  149. data/ui/src/hokusai/meta.rb +152 -0
  150. data/ui/src/hokusai/mounting/loop_entry.rb +230 -0
  151. data/ui/src/hokusai/mounting/mount_entry.rb +74 -0
  152. data/ui/src/hokusai/mounting/update_entry.rb +101 -0
  153. data/ui/src/hokusai/node.rb +98 -0
  154. data/ui/src/hokusai/node_mounter.rb +102 -0
  155. data/ui/src/hokusai/painter.rb +214 -0
  156. data/ui/src/hokusai/publisher.rb +32 -0
  157. data/ui/src/hokusai/style.rb +72 -0
  158. data/ui/src/hokusai/types.rb +266 -0
  159. data/ui/src/hokusai/util/clamping_iterator.rb +202 -0
  160. data/ui/src/hokusai/util/piece_table.rb +111 -0
  161. data/ui/src/hokusai/util/selection.rb +145 -0
  162. data/ui/src/hokusai.rb +120 -0
  163. data/ui/vendor/.gitkeep +0 -0
  164. data/vendor/.gitkeep +0 -0
  165. data/xmake.lua +192 -0
  166. metadata +222 -0
@@ -0,0 +1,246 @@
1
+ require_relative "../src/hokusai"
2
+ require_relative "../src/hokusai/backends/raylib"
3
+ require_relative "../src/hokusai/backends/sdl2"
4
+
5
+ module TicTacToe
6
+ module Player
7
+ X = 0
8
+ O = 1
9
+ None = 2
10
+ end
11
+
12
+ class Square < Hokusai::Block
13
+ style <<-EOF
14
+ [style]
15
+ squareStyle {
16
+ outline: 3.0;
17
+ outline_color: rgb(233,233,233);
18
+ }
19
+ EOF
20
+
21
+ template <<-EOF
22
+ [template]
23
+ vblock {
24
+ @click="emit_position"
25
+ @hover="set_hover"
26
+ @mouseout="set_mouseout"
27
+ :background="compute_background"
28
+ ...squareStyle
29
+ }
30
+ label { height="13" :content="read_position" }
31
+ [if="has_player"]
32
+ image { :source="square_image" }
33
+ EOF
34
+
35
+ computed! :player
36
+ computed! :position
37
+
38
+ uses(
39
+ vblock: Hokusai::Blocks::Vblock,
40
+ image: Hokusai::Blocks::Image,
41
+ label: Hokusai::Blocks::Label
42
+ )
43
+
44
+ def compute_background
45
+ case player
46
+ when Player::X
47
+ [52,168,77]
48
+ when Player::O
49
+ [219,176,57]
50
+ when Player::None
51
+ @hover ? [55, 110, 155] : [47,98,140]
52
+ end
53
+ end
54
+
55
+ def set_hover(event)
56
+ @hover = true
57
+ end
58
+
59
+ def set_mouseout(event)
60
+ @hover = false
61
+ end
62
+
63
+ def read_position
64
+ position.inspect
65
+ end
66
+
67
+ def emit_position(click)
68
+ emit("position", position)
69
+ end
70
+
71
+ def has_player
72
+ player != Player::None
73
+ end
74
+
75
+ def square_image
76
+ case player
77
+ when Player::X
78
+ return "#{__dir__}/assets/science-troll.png"
79
+ when Player::O
80
+ return "#{__dir__}/assets/football-troll.png"
81
+ end
82
+ end
83
+ end
84
+
85
+ class Row < Hokusai::Block
86
+ template <<-EOF
87
+ [template]
88
+ hblock
89
+ [for="player in row"]
90
+ square { cursor="pointer" @position="emit_position" :player="player" :key="key(index)" :position="position(index)" }
91
+ EOF
92
+
93
+ uses(
94
+ square: Square,
95
+ hblock: Hokusai::Blocks::Hblock
96
+ )
97
+
98
+ computed! :row
99
+ computed! :row_index
100
+
101
+ def emit_position(pos)
102
+ emit("position", pos)
103
+ end
104
+
105
+ def key(index)
106
+ "player_#{row_index}_#{index}"
107
+ end
108
+
109
+ def position(index)
110
+ [row_index, index]
111
+ end
112
+
113
+ end
114
+
115
+ class App < Hokusai::Block
116
+ template <<-EOF
117
+ [template]
118
+ vblock
119
+ [if="has_winner"]
120
+ vblock { background="10,10,10,222" }
121
+ img { :source="winner_image"}
122
+ vblock
123
+ label { :content="winner_text" color="255,255,255", size="30"}
124
+ label { @click="restart" color="222,199,199" size="20" content="restart"}
125
+ [else]
126
+ vblock
127
+ [for="row in board"]
128
+ row { @position="update_game" :row="row" :key="key(index)" :row_index="index" }
129
+ EOF
130
+
131
+ uses(
132
+ row: Row,
133
+ vblock: Hokusai::Blocks::Vblock,
134
+ hblock: Hokusai::Blocks::Hblock,
135
+ label: Hokusai::Blocks::Label,
136
+ empty: Hokusai::Blocks::Empty,
137
+ img: Hokusai::Blocks::Image
138
+ )
139
+
140
+ attr_accessor :current_player, :board, :count
141
+
142
+ def initialize(**args)
143
+ @current_player = Player::X
144
+ @count = 0
145
+ super
146
+
147
+ restart
148
+ end
149
+
150
+ def restart(*args)
151
+ @board = [
152
+ [Player::None, Player::None, Player::None],
153
+ [Player::None, Player::None, Player::None],
154
+ [Player::None, Player::None, Player::None]
155
+ ]
156
+ self.count = 0
157
+ end
158
+
159
+ def key(index)
160
+ "row_#{index}"
161
+ end
162
+
163
+ def winner_image
164
+ case winner
165
+ when Player::X
166
+ return "#{__dir__}/assets/science-troll.png"
167
+ when Player::O
168
+ return "#{__dir__}/assets/football-troll.png"
169
+ else
170
+ return "#{__dir__}/assets/baby_sean.png"
171
+ end
172
+ end
173
+
174
+ def winner_text
175
+ case winner
176
+ when Player::X
177
+ "Player X won!"
178
+ when Player::O
179
+ "Player O won!"
180
+ else
181
+ "No winner"
182
+ end
183
+ end
184
+
185
+ def has_winner
186
+ count >= 9 || !check_win.nil?
187
+ end
188
+
189
+ def winner
190
+ check_win
191
+ end
192
+
193
+ def update_game(position)
194
+ row, col = position
195
+
196
+ self.count += 1
197
+
198
+ case current_player
199
+ when Player::X
200
+ board[row][col] = Player::X unless board[row][col] != Player::None
201
+ self.current_player = Player::O
202
+ when Player::O
203
+ board[row][col] = Player::O unless board[row][col] != Player::None
204
+ self.current_player = Player::X
205
+ end
206
+ end
207
+
208
+ def check_win
209
+ [Player::X, Player::O].each do |player|
210
+ (0...3).step do |i|
211
+ if board[i][0] == player && board[i][1] == player && board[i][2] == player
212
+ return player
213
+ end
214
+
215
+ if board[0][i] == player && board[1][i] == player && board[2][i] == player
216
+ return player
217
+ end
218
+
219
+ diagonal_left = board[0][0] == player && board[1][1] == player && board[2][2] == player
220
+ diagonal_right = board[2][0] == player && board[1][1] == player && board[0][2] == player
221
+
222
+ if diagonal_left || diagonal_right
223
+ return player
224
+ end
225
+ end
226
+ end
227
+
228
+ nil
229
+ end
230
+
231
+ def render(canvas)
232
+ if Hokusai.can_render(canvas)
233
+
234
+ emit("width", canvas.width)
235
+
236
+ yield canvas
237
+ end
238
+ end
239
+ end
240
+ end
241
+ #
242
+ # Hokusai::Backends::SDLBackend.run(TicTacToe::App) do |config|
243
+ # config.width = 500
244
+ # config.height = 500
245
+ # config.title = "Tic Tac Trollio"
246
+ # end
@@ -0,0 +1,425 @@
1
+ require "ffi"
2
+
3
+ module LibHokusai
4
+ class Error < StandardError; end
5
+ extend FFI::Library
6
+
7
+ case RbConfig::CONFIG['host_os']
8
+ when /darwin/
9
+ ffi_lib "#{__dir__}/../../vendor/lib/libhokusai.dylib"
10
+ when /linux/
11
+ ffi_lib "#{__dir__}/../../vendor/lib/libhokusai.so"
12
+ else
13
+ raise "Unsupported platform!"
14
+ end
15
+
16
+ typedef :pointer, :hashmap
17
+
18
+ def self.parse_template(name, template)
19
+ ptr = FFI::MemoryPointer.new :pointer
20
+ code = LibHokusai.hoku_ast_from_template(ptr, name, template)
21
+
22
+ raise LibHokusai::Error.new("Couldn't parse template") unless code.zero?
23
+
24
+ a_ptr = ptr.get_pointer(0)
25
+ LibHokusai::HmlAst.new FFI::AutoPointer.new(a_ptr, LibHokusai.method(:hoku_ast_free))
26
+ ensure
27
+ ptr.free
28
+ end
29
+
30
+ def self.parse_style(template)
31
+ ptr = FFI::MemoryPointer.new :pointer
32
+ pp template
33
+ code = LibHokusai.hoku_style_from_template(ptr, template)
34
+
35
+ raise LibHokusai::Error.new("Couldn't parse style template") unless code.zero?
36
+
37
+ a_ptr = ptr.get_pointer(0)
38
+ LibHokusai::HmlStyle.new FFI::AutoPointer.new(a_ptr, LibHokusai.method(:hoku_style_free))
39
+ ensure
40
+ ptr.free
41
+ end
42
+
43
+ enum :hml_style_type, [
44
+ :style_int,
45
+ :style_float,
46
+ :style_bool,
47
+ :style_string,
48
+ :style_func
49
+ ]
50
+
51
+ class HmlStyleAttribute < FFI::Struct
52
+ layout :name, :string,
53
+ :function_name, :string,
54
+ :value, :string,
55
+ :type, :hml_style_type,
56
+ :next, HmlStyleAttribute.ptr
57
+ end
58
+
59
+ class HmlStyle < FFI::Struct
60
+ layout :name, :string,
61
+ :attributes, HmlStyleAttribute.ptr,
62
+ :next, HmlStyle.ptr
63
+ end
64
+
65
+ class HmlAstFuncCall < FFI::Struct
66
+ layout :function, :string,
67
+ :args_len, :int,
68
+ :args, :pointer,
69
+ :strargs, :pointer
70
+ end
71
+
72
+ class HmlAstProp < FFI::Struct
73
+ layout :name, :string,
74
+ :computed, :bool,
75
+ :call, HmlAstFuncCall.ptr
76
+ end
77
+
78
+ class HmlAstEvent < FFI::Struct
79
+ layout :name, :string,
80
+ :call, HmlAstFuncCall.ptr
81
+ end
82
+
83
+ class HmlAstCondition < FFI::Struct
84
+ layout :not, :bool,
85
+ :call, HmlAstFuncCall.ptr
86
+ end
87
+
88
+ class HmlAstLoop < FFI::Struct
89
+ layout :name, :string,
90
+ :list_name, :string
91
+ end
92
+
93
+ class HmlAstClassList < FFI::Struct
94
+ layout :name, :string,
95
+ :next, HmlAstClassList.ptr
96
+ end
97
+
98
+ class HmlAstList < FFI::Struct; end
99
+
100
+ class HmlAst < FFI::Struct
101
+ layout :type, :string,
102
+ :id, :string,
103
+ :error, :string,
104
+ :has_slot, :bool,
105
+ :child_len, :int,
106
+ :styles, HmlStyle.ptr,
107
+ :style_list, HmlAstClassList.ptr,
108
+ :class_list, HmlAstClassList.ptr,
109
+ :cond, HmlAstCondition.ptr,
110
+ :loop, HmlAstLoop.ptr,
111
+ :props, :hashmap,
112
+ :events, :hashmap,
113
+ :parent, HmlAst.ptr,
114
+ :relations, HmlAstList.ptr,
115
+ :else_relations, HmlAstList.ptr,
116
+ :else_active, :int
117
+ end
118
+
119
+ class HmlAstList < FFI::Struct
120
+ layout :next_sibling, HmlAst.ptr,
121
+ :next_child, HmlAst.ptr
122
+ end
123
+
124
+
125
+ # fun hashmap_iter(map : Hashmap, i : LibC::SizeT*, item : Void**) : Bool
126
+ # ast methods
127
+ attach_function :hoku_ast_prop_init, [:pointer, :string], :int
128
+ attach_function :hoku_ast_class_list_includes, [:pointer, :string], :int
129
+ attach_function :hoku_ast_get_prop, [HmlAst.by_ref, HmlAstProp.by_ref], HmlAstProp.by_ref
130
+ attach_function :hoku_ast_get_event, [:pointer, :pointer], HmlAstEvent.by_ref
131
+ attach_function :hashmap_iter, [:hashmap, :pointer, :pointer], :bool
132
+ attach_function :hashmap_count, [:hashmap], :int
133
+ attach_function :hoku_ast_free, [:pointer], :void
134
+ attach_function :hoku_errored_ast, [HmlAst.by_ref], HmlAst.by_ref
135
+ attach_function :hoku_ast_from_template, [:pointer, :string, :string], :int
136
+ attach_function :hoku_style_from_template, [:pointer, :string], :int
137
+ attach_function :hoku_style_free, [:pointer], :void
138
+ attach_function :hoku_dump, [:pointer, :int], :void
139
+
140
+ enum :hml_input_key, [
141
+ :null, :apostrophe, :comma, :minus,
142
+ :period, :slash, :zero, :one, :two,
143
+ :three, :four, :five, :six, :seven,
144
+ :eight, :nine, :semicolon, :equal,
145
+ :a, :b, :c, :d, :e, :f, :g, :h, :i,
146
+ :j, :k, :l, :m, :n, :o, :p, :q, :r,
147
+ :s, :t, :u, :v, :w, :x, :y, :z,
148
+ :left_bracket, :backslash, :right_bracket,
149
+ :grave, :space, :escape, :enter, :tab,
150
+ :backspace, :insert, :delete, :right, :left,
151
+ :down, :up, :page_up, :page_down, :home,
152
+ :end, :caps_lock, :scroll_lock, :num_lock,
153
+ :print_screen, :pause, :f1, :f2, :f3, :f4,
154
+ :f5, :f6, :f7, :f8, :f9, :f10, :f11, :f12,
155
+ :left_shift, :left_control, :left_alt,
156
+ :left_super, :right_shift, :right_control, :right_alt,
157
+ :right_super, :kb_menu, :kp_0, :kp_1, :kp_2,
158
+ :kp_3, :kp_4, :kp_5, :kp_6, :kp_7, :kp_8, :kp_9,
159
+ :kp_decimal, :kp_divide, :kp_multiply, :kp_subtract, :kp_add,
160
+ :kp_enter, :kp_equal, :back, :menu, :volume_up, :volume_down,
161
+ :max
162
+ ]
163
+
164
+ enum :hml_input_select_type, [
165
+ :ACTIVE, 0x01,
166
+ :FROZEN, 0x02,
167
+ :NONE, 0x03
168
+ ]
169
+
170
+ class HmlVec2 < FFI::Struct
171
+ layout :x, :float,
172
+ :y, :float
173
+
174
+ def self.create(x, y)
175
+ new.tap do |instance|
176
+ instance[:x] = x
177
+ instance[:y] = y
178
+ end
179
+ end
180
+
181
+ def x
182
+ self[:x]
183
+ end
184
+
185
+ def y
186
+ self[:y]
187
+ end
188
+ end
189
+
190
+ class HmlDoubleVec2 < FFI::Struct
191
+ layout :x, :double,
192
+ :y, :double
193
+
194
+ def x
195
+ self[:x]
196
+ end
197
+
198
+ def y
199
+ self[:y]
200
+ end
201
+ end
202
+
203
+ class HmlRect < FFI::Struct
204
+ layout :x, :float,
205
+ :y, :float,
206
+ :w, :float,
207
+ :h, :float
208
+
209
+ def self.create(x, y, w, h)
210
+ new.tap do |instance|
211
+ instance[:x] = x
212
+ instance[:y] = y
213
+ instance[:w] = w
214
+ instance[:h] = h
215
+ end
216
+ end
217
+ end
218
+
219
+ class HmlInputKeyboardKey < FFI::Struct
220
+ layout :code, :int,
221
+ :down, :bool,
222
+ :up, :bool,
223
+ :released, :bool,
224
+ :pressed, :bool,
225
+ :key, :hml_input_key
226
+ end
227
+
228
+ class HmlInputKeyboardKeyWithChar < FFI::Struct
229
+ layout :key, HmlInputKeyboardKey,
230
+ :char_code, :int
231
+ end
232
+
233
+ class HmlInputKeyboard < FFI::Struct
234
+ layout :allocated_len, :int,
235
+ :pressed, HmlInputKeyboardKeyWithChar.ptr,
236
+ :pressed_len, :int,
237
+ :released, HmlInputKeyboardKeyWithChar.ptr,
238
+ :released_len, :int,
239
+ :shift, :bool,
240
+ :super, :bool,
241
+ :ctrl, :bool,
242
+ :alt, :bool,
243
+ :keys, HmlInputKeyboardKey.ptr,
244
+ :collecting, :bool
245
+ end
246
+
247
+ class HmlInputMouseButton < FFI::Struct
248
+ layout :down, :bool,
249
+ :up, :bool,
250
+ :clicked, :bool,
251
+ :released, :bool
252
+
253
+ def self.create(up: false, down: false, clicked: false, released: false)
254
+ @button ||= new
255
+ @button.tap do |instance|
256
+ instance[:down] = down
257
+ instance[:up] = up
258
+ instance[:clicked] = clicked
259
+ instance[:released] = released
260
+ end
261
+ @button
262
+ end
263
+
264
+ def down
265
+ self[:down]
266
+ end
267
+
268
+ def up
269
+ self[:up]
270
+ end
271
+
272
+ def clicked
273
+ self[:clicked]
274
+ end
275
+
276
+ def released
277
+ self[:released]
278
+ end
279
+ end
280
+
281
+ class HmlInputMouse < FFI::Struct
282
+ layout :pos, HmlVec2.ptr,
283
+ :delta, HmlDoubleVec2,
284
+ :scroll, :float,
285
+ :scroll_delta, :float,
286
+ :selection, HmlRect,
287
+ :selection_type, :hml_input_select_type,
288
+ :left, HmlInputMouseButton.ptr,
289
+ :middle, HmlInputMouseButton.ptr,
290
+ :right, HmlInputMouseButton.ptr
291
+ end
292
+
293
+ class HmlInput < FFI::Struct
294
+ layout :keyboard, HmlInputKeyboard.ptr,
295
+ :mouse, HmlInputMouse.ptr
296
+ end
297
+
298
+ def LibHokusai.const_missing( sym )
299
+ value = enum_value( sym )
300
+ return super unless value
301
+ value
302
+ end
303
+
304
+ # input methods
305
+ attach_function :hoku_input_init, [:pointer], :int
306
+ attach_function :hoku_input_free, [HmlInput.by_ref], :void
307
+ attach_function :hoku_input_set_mouse_position, [HmlInput.by_ref, HmlVec2.by_ref], :void
308
+ attach_function :hoku_input_mouse_set_scroll, [HmlInput.by_ref, :float], :void
309
+ attach_function :hoku_input_mouse_set_button, [HmlInput.by_ref, HmlInputMouseButton.by_ref, :int], :void
310
+
311
+ attach_function :hoku_input_is_clicked, [HmlInput.by_ref, HmlRect.by_ref], :bool
312
+ attach_function :hoku_input_is_hovered, [HmlInput.by_ref, HmlRect.by_ref], :bool
313
+
314
+ attach_function :hoku_input_keyboard_start, [HmlInput.by_ref], :void
315
+ attach_function :hoku_input_keyboard_set_key, [HmlInput.by_ref, :hml_input_key, :bool], :void
316
+ attach_function :hoku_input_keyboard_get_key, [HmlInput.by_ref, :hml_input_key], HmlInputKeyboardKey
317
+ attach_function :hoku_input_keyboard_stop, [HmlInput.by_ref], :void
318
+
319
+
320
+ enum :hoku_select_type, [
321
+ :active, 0x01,
322
+ :frozen, 0x02,
323
+ :none, 0x03
324
+ ]
325
+
326
+ class HokuCursorPosition < FFI::Struct
327
+ layout :x, :float,
328
+ :y, :float,
329
+ :w, :float,
330
+ :h, :float
331
+
332
+ def self.create(position)
333
+ new.tap do |instance|
334
+ instance[:x] = position[0]
335
+ instance[:y] = position[1]
336
+ instance[:w] = position[2]
337
+ instance[:h] = position[3]
338
+ end
339
+ end
340
+ end
341
+
342
+ class HokuSelection < FFI::Struct
343
+ layout :type, :hoku_select_type,
344
+ :start_x, :float,
345
+ :start_y, :float,
346
+ :stop_x, :float,
347
+ :stop_y, :float,
348
+ :offset_y, :float,
349
+ :cursor, HokuCursorPosition.ptr
350
+ end
351
+
352
+ attach_function :hoku_selection_init, [:pointer], :int
353
+ attach_function :hoku_selection_selected, [HokuSelection.by_ref, :float, :float, :float, :float], :bool
354
+ attach_function :hoku_selection_cursor_set, [HokuSelection.by_ref, HokuCursorPosition.by_value], :int
355
+ attach_function :hoku_selection_cursor_free, [HokuSelection.by_ref], :void
356
+ attach_function :hoku_selection_free, [HokuSelection.by_ref], :void
357
+
358
+ attach_function :hoku_rect_includes_y, [HmlRect.by_value, :float], :bool
359
+ attach_function :hoku_rect_includes_x, [HmlRect.by_value, :float], :bool
360
+ attach_function :hoku_rect_x_left, [HmlRect.by_value, :int], :float
361
+ attach_function :hoku_rect_x_right, [HmlRect.by_value, :int], :float
362
+ attach_function :hoku_rect_y_up, [HmlRect.by_value, :int], :float
363
+ attach_function :hoku_rect_y_down, [HmlRect.by_value, :int], :float
364
+
365
+ class HokuChar < FFI::Struct
366
+ layout :offset, :int,
367
+ :width, :int,
368
+ :next_char, HokuChar.ptr
369
+ end
370
+
371
+ GROUP_NORMAL = 1 << 0
372
+ GROUP_BOLD = 1 << 1
373
+ GROUP_ITALICS = 1 << 2
374
+ GROUP_LINK = 1 << 3
375
+ GROUP_IMAGE = 1 << 4
376
+ GROUP_CODE = 1 << 5
377
+ GROUP_LIST_ITEM = 1 << 6
378
+
379
+ class HokuGroupLink < FFI::Struct
380
+ layout :url, :string
381
+ end
382
+
383
+ class HokuGroupImage < FFI::Struct
384
+ layout :src, :string
385
+ end
386
+
387
+ class HokuGroupCode < FFI::Struct
388
+ layout :language, :string
389
+ end
390
+
391
+ class HokuGroupListItem < FFI::Struct
392
+ layout :level, :int
393
+ end
394
+
395
+ class HokuGroup < FFI::Struct
396
+ layout :offset, :int,
397
+ :size, :int,
398
+ :type, :uint8,
399
+ :payload, :pointer,
400
+ :chars, HokuChar.ptr,
401
+ :next_group, HokuGroup.ptr
402
+ end
403
+
404
+ class HokuSegment < FFI::Struct
405
+ layout :offset, :int,
406
+ :size, :int,
407
+ :select_begin, :int,
408
+ :select_end, :int,
409
+ :chars, HokuChar.ptr,
410
+ :groups, HokuGroup.ptr,
411
+ :next_segment, HokuSegment.ptr
412
+ end
413
+
414
+ class HokuClamping < FFI::Struct
415
+ layout :text, :string,
416
+ :width, :float,
417
+ :segments, HokuSegment.ptr
418
+ end
419
+
420
+ callback :hoku_char_width_cb, [:char, :pointer], :int
421
+ attach_function :hoku_text_clamp_debug, [HokuClamping.by_ref], :void
422
+ attach_function :hoku_text_md_clamp, [:pointer, :string, :float, :float, :pointer, :hoku_char_width_cb], :int
423
+ attach_function :hoku_text_clamp, [:pointer, :string, :float, :float, :pointer, :hoku_char_width_cb], :int
424
+ attach_function :hoku_text_clamping_free, [:pointer], :void
425
+ end