hokusai-zero 0.2.6.pre.pinephone → 0.2.6.pre.pinephone3

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.
@@ -16,8 +16,7 @@ module Hokusai::Backends
16
16
  yield(config)
17
17
  end
18
18
 
19
- block = app.mount
20
- backend.run(block)
19
+ backend.run(app)
21
20
  end
22
21
 
23
22
  def self.cursors
@@ -30,6 +29,17 @@ module Hokusai::Backends
30
29
  }
31
30
  end
32
31
 
32
+ def hml_vec2(x, y)
33
+ if @hml_vec2.nil?
34
+ @hml_vec2 = LibHokusai::HmlVec2.create(x, y)
35
+ else
36
+ @hml_vec2[:x] = x
37
+ @hml_vec2[:y] = y
38
+ end
39
+
40
+ @hml_vec2
41
+ end
42
+
33
43
  def self.stopped
34
44
  @stopped ||= false
35
45
  end
@@ -56,7 +66,19 @@ module Hokusai::Backends
56
66
  yield @config
57
67
  end
58
68
 
59
- def run(block)
69
+ def get_size(window)
70
+ w = FFI::MemoryPointer.new :int
71
+ h = FFI::MemoryPointer.new :int
72
+
73
+ SDL.GL_GetDrawableSize(window, w, h)
74
+
75
+ res = { width: w.read_int, height: h.read_int }
76
+ w.free
77
+ h.free
78
+ res
79
+ end
80
+
81
+ def run(app)
60
82
  resize = true
61
83
  self.render_width = config.width
62
84
  self.render_height = config.height
@@ -80,6 +102,7 @@ module Hokusai::Backends
80
102
  image_libpath: "#{SDL_PATH}/libSDL2_image.so"
81
103
  )
82
104
  end
105
+
83
106
  SDL.Init(config.init_flags)
84
107
  SDL.TTF_Init
85
108
 
@@ -87,43 +110,73 @@ module Hokusai::Backends
87
110
  SDL.SetWindowPosition(window, SDL::WINDOWPOS_CENTERED_MASK, SDL::WINDOWPOS_CENTERED_MASK)
88
111
  renderer = SDL.CreateRenderer(window, -1, SDL::RENDERER_TARGETTEXTURE | SDL::RENDERER_ACCELERATED)
89
112
 
113
+ size = get_size(window)
114
+ SDL.RenderSetScale(renderer, size[:width] / render_width, size[:height] / render_height);
115
+
90
116
  Hokusai.fonts.register "default", SDLBackend::Font.from("#{__dir__}/sdl2/Monaco.ttf", 121)
91
117
  Hokusai.fonts.activate "default"
92
118
  config.after_load_cb&.call
93
119
 
94
120
  register_command_handlers(renderer, window)
121
+ block = app.mount
95
122
  # MemoryProfiler.start if ENV["PROFILE"]
96
123
 
97
124
  ptr = FFI::MemoryPointer.new :pointer
98
125
  LibHokusai.hoku_input_init(ptr)
99
126
  raw = LibHokusai::HmlInput.new(ptr.get_pointer(0))
100
127
  input = Hokusai::Input.new(raw)
128
+
129
+ if config.touch
130
+ input.support_touch!
131
+ end
132
+
101
133
  canvas = Hokusai::Canvas.new(render_width.to_f, render_height.to_f)
102
134
  event = SDL::Event.new
103
135
 
104
136
  loop do
105
- SDL.WaitEvent(event)
106
- break if event[:common][:type] == SDL::QUIT || self.class.stopped
107
- if process_input(input, event)
108
- # since we are using wait event, we need to process the render twice
109
- # once to capture all events, and once after updating block state.
110
- SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_NONE)
111
- SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
112
- SDL.RenderClear(renderer)
113
- canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
114
- painter = Hokusai::Painter.new(block, input)
115
- painter.render(canvas, resize)
116
- block.update
117
- SDL.RenderPresent(renderer)
118
-
119
- SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_NONE)
120
- SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
121
- SDL.RenderClear(renderer)
122
- canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
123
- painter = Hokusai::Painter.new(block, input)
124
- painter.render(canvas, resize, capture: false)
125
- SDL.RenderPresent(renderer)
137
+ if SDL.PollEvent(event)
138
+ self.class.stopped = true if event[:common][:type] == SDL::QUIT || self.class.stopped
139
+
140
+ process_input(input, event)
141
+ if config.touch
142
+ if input.touch.touching?
143
+ token = input.touch.token
144
+
145
+ LibHokusai.hoku_input_set_mouse_position(input.raw, hml_vec2(token[:x], token[:y]))
146
+ end
147
+
148
+ # translate taps to clicks
149
+ if input.touch.tapped?
150
+ button = mouse_button(clicked: true, down: true, released: false, up: false)
151
+ LibHokusai.hoku_input_mouse_set_button(input.raw, button, 0)
152
+ else
153
+ button = mouse_button(clicked: false, down: false, released: true, up: true)
154
+ LibHokusai.hoku_input_mouse_set_button(input.raw, button, 0)
155
+ end
156
+ end
126
157
  end
158
+
159
+ break if self.class.stopped
160
+ # since we are using wait event, we need to process the render twice
161
+ # once to capture all events, and once after updating block state.
162
+ SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_BLEND)
163
+ SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
164
+ SDL.RenderClear(renderer)
165
+ canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
166
+ painter = Hokusai::Painter.new(block, input)
167
+ painter.render(canvas, resize)
168
+
169
+ SDL.RenderPresent(renderer)
170
+ block.update
171
+
172
+ # SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_NONE)
173
+ # SDL.SetRenderDrawColor(renderer, config.background[:r], config.background[:g], config.background[:b], config.background[:a])
174
+ # SDL.RenderClear(renderer)
175
+ # canvas.reset(nil, nil, render_width.to_f, render_height.to_f)
176
+ # painter = Hokusai::Painter.new(block, input)
177
+ # painter.render(canvas, resize, capture: false)
178
+ # SDL.RenderPresent(renderer)
179
+ SDL.Delay(10)
127
180
  end
128
181
 
129
182
  LibHokusai.hoku_input_free(input.raw)
@@ -157,52 +210,78 @@ module Hokusai::Backends
157
210
  end
158
211
 
159
212
  def reset_keys(input)
160
- LibHokusai.hoku_input_keyboard_start(input.raw)
161
- Modifiers.each do |(sdlk, hkey)|
162
- LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
163
- end
213
+ if !input.keyboard_override
214
+ LibHokusai.hoku_input_keyboard_start(input.raw)
215
+ Modifiers.each do |(sdlk, hkey)|
216
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
217
+ end
164
218
 
165
- Keys.values.each do |hkey|
166
- LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
167
- end
219
+ Keys.values.each do |hkey|
220
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
221
+ end
168
222
 
169
- LibHokusai.hoku_input_keyboard_stop(input.raw)
223
+ LibHokusai.hoku_input_keyboard_stop(input.raw)
224
+ end
170
225
  end
171
226
 
172
227
  def process_input(input, event)
173
228
  reset_keys(input)
174
229
 
230
+ t = event[:common][:type]
231
+ if config.touch && t != SDL::FINGERDOWN && t != SDL::WINDOWEVENT && t != SDL::FINGERUP && t != SDL::FINGERMOTION && t != SDL::MOUSEMOTION && t != SDL::POLLSENTINEL
232
+ input.touch.clear
233
+ end
234
+
175
235
  case event[:common][:type]
176
- when SDL::KEYDOWN
177
- modifier = event[:key][:keysym][:mod]
178
- code = event[:key][:keysym][:sym]
179
- hkey = Keys[code]
236
+ when SDL::FINGERDOWN
237
+ x = event[:tfinger][:x] * render_width
238
+ y = event[:tfinger][:y] * render_height
180
239
 
181
- LibHokusai.hoku_input_keyboard_start(input.raw)
182
- Modifiers.each do |(sdlk, hkey)|
183
- if modifier & sdlk == sdlk
184
- LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, true)
240
+ input.touch.record(0, x, y)
241
+ return true
242
+ when SDL::FINGERUP
243
+ input.touch.clear
244
+ return true
245
+ when SDL::FINGERMOTION
246
+ x = event[:tfinger][:x] * render_width
247
+ y = event[:tfinger][:y] * render_height
248
+
249
+ input.touch.record(0, x, y)
250
+ return true
251
+ when SDL::KEYDOWN
252
+ if !input.keyboard_override
253
+ modifier = event[:key][:keysym][:mod]
254
+ code = event[:key][:keysym][:sym]
255
+ hkey = Keys[code]
256
+
257
+ LibHokusai.hoku_input_keyboard_start(input.raw)
258
+ Modifiers.each do |(sdlk, hkey)|
259
+ if modifier & sdlk == sdlk
260
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, true)
261
+ end
185
262
  end
186
- end
187
263
 
188
- LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, true) unless hkey.nil?
189
- LibHokusai.hoku_input_keyboard_stop(input.raw)
264
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, true) unless hkey.nil?
265
+ LibHokusai.hoku_input_keyboard_stop(input.raw)
266
+ end
190
267
 
191
268
  return true
192
269
  when SDL::KEYUP
193
- modifier = event[:key][:keysym][:mod]
194
- code = event[:key][:keysym][:sym]
195
- hkey = Keys[code]
196
-
197
- LibHokusai.hoku_input_keyboard_start(input.raw)
198
- Modifiers.each do |(sdlk, hkey)|
199
- if modifier & sdlk == sdlk
200
- LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
270
+ if !input.keyboard_override
271
+ modifier = event[:key][:keysym][:mod]
272
+ code = event[:key][:keysym][:sym]
273
+ hkey = Keys[code]
274
+
275
+ LibHokusai.hoku_input_keyboard_start(input.raw)
276
+ Modifiers.each do |(sdlk, hkey)|
277
+ if modifier & sdlk == sdlk
278
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
279
+ end
201
280
  end
202
- end
203
281
 
204
- LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false) unless hkey.nil?
205
- LibHokusai.hoku_input_keyboard_stop(input.raw)
282
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false) unless hkey.nil?
283
+ LibHokusai.hoku_input_keyboard_stop(input.raw)
284
+ end
206
285
  return true
207
286
  when SDL::WINDOWEVENT
208
287
  if event[:window][:event] == SDL::WINDOWEVENT_RESIZED
@@ -257,20 +336,34 @@ module Hokusai::Backends
257
336
  clicked = event[:button][:clicks] > 0
258
337
  button = mouse_button(down: true, clicked: clicked)
259
338
 
260
- # LibHokusai.hoku_input_mouse_set_scroll(input.raw, 0.0)
261
- # input.raw[:mouse][:delta][:y] = 0.0
339
+ LibHokusai.hoku_input_mouse_set_scroll(input.raw, 0.0)
340
+ input.raw[:mouse][:delta][:y] = 0.0
262
341
 
263
342
  LibHokusai.hoku_input_mouse_set_button(input.raw, button, event[:button][:which])
264
343
  return true
265
344
  when SDL::MOUSEBUTTONUP
266
345
  button = mouse_button(up: true)
267
346
  #
268
- # LibHokusai.hoku_input_mouse_set_scroll(input.raw, 0.0)
269
- # input.raw[:mouse][:delta][:y] = 0.0
347
+ LibHokusai.hoku_input_mouse_set_scroll(input.raw, 0.0)
348
+ input.raw[:mouse][:delta][:y] = 0.0
270
349
 
271
350
  LibHokusai.hoku_input_mouse_set_button(input.raw, button, event[:button][:which])
272
351
  return true
273
352
  when SDL::TEXTINPUT
353
+ char = event[:text][:text].to_s
354
+ LibHokusai.hoku_input_keyboard_start(input.raw)
355
+
356
+ Modifiers.each do |(sdlk, hkey)|
357
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, hkey, false)
358
+ end
359
+ LibHokusai.hoku_input_keyboard_set_key(input.raw, char.to_sym, true)
360
+ LibHokusai.hoku_input_keyboard_stop(input.raw)
361
+
362
+ return true
363
+ when SDL::TEXTEDITING
364
+ # start = event[:edit][:start]
365
+ # len = event[:edit][:length]
366
+ # text = event[:edit][:text]
274
367
  return false
275
368
  else
276
369
  false
@@ -410,16 +503,21 @@ module Hokusai::Backends
410
503
  self.class.images[command.source]
411
504
  else
412
505
  file = File.read(command.source)
413
-
414
- rw = SDL.RWFromConstMem(file, file.size)
415
- surface_ptr = SDL.IMG_Load_RW(rw, 1)
416
- if surface_ptr.null?
506
+ SDL.SetHint(SDL::HINT_RENDER_SCALE_QUALITY, "0");
507
+ texture = SDL.IMG_LoadTexture(renderer, command.source)
508
+ if texture.null?
417
509
  raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
418
510
  end
419
511
 
420
- texture = SDL.CreateTextureFromSurface(renderer, surface_ptr)
512
+ # rw = SDL.RWFromConstMem(file, file.size)
513
+ # surface_ptr = SDL.IMG_LoadSVG_RW(rw)
514
+ # if surface_ptr.null?
515
+ # raise Hokusai::Error.new("Can't load Image: #{SDL.GetError.read_string}")
516
+ # end
517
+
518
+ # texture = SDL.CreateTextureFromSurface(renderer, surface_ptr)
421
519
  self.class.images[command.source] = texture
422
- SDL.FreeSurface(surface_ptr)
520
+ # SDL.FreeSurface(surface_ptr)
423
521
  texture
424
522
  end
425
523
  end
@@ -431,6 +529,7 @@ module Hokusai::Backends
431
529
 
432
530
  Hokusai::Commands::Rect.on_draw do |command|
433
531
  next unless inside_scissor(command.x, command.y, command.height)
532
+ next if command.color.a == 0
434
533
  # draw background first
435
534
  x, y, w, h = [command.x, command.y, command.width, command.height]
436
535
 
@@ -506,7 +605,6 @@ module Hokusai::Backends
506
605
  rounding = command.rounding
507
606
 
508
607
  if command.rounding > 0
509
- pp command.color
510
608
  SDL.roundedBoxRGBA(renderer, x, y, x + w, y + h, (command.rounding).ceil.to_i, command.color.r, command.color.g, command.color.b, command.color.a)
511
609
  else
512
610
  rect = SDL::Rect.new
@@ -515,6 +613,7 @@ module Hokusai::Backends
515
613
  rect[:w] = w
516
614
  rect[:h] = h
517
615
 
616
+ SDL.SetRenderDrawBlendMode(renderer, SDL::BLENDMODE_BLEND)
518
617
  SDL.SetRenderDrawColor(renderer, command.color.r, command.color.g, command.color.b, command.color.a)
519
618
  SDL.RenderFillRect(renderer, rect)
520
619
  end
@@ -87,7 +87,7 @@ class Hokusai::Blocks::Input < Hokusai::Block
87
87
  end
88
88
 
89
89
  def dynamic_keypress_handle(event)
90
- return unless node.meta.focused
90
+ return unless node.meta.focused || event.input.keyboard_override
91
91
  case event
92
92
  when proc(&:ctrl), proc(&:super)
93
93
  if event.char == "z"
@@ -0,0 +1,234 @@
1
+ module Hokusai::Blocks
2
+ class Key < Hokusai::Block
3
+ template <<~EOF
4
+ [template]
5
+ empty {
6
+ @mousedown="set_down"
7
+ @mouseup="set_up"
8
+ cursor="pointer"
9
+ }
10
+ EOF
11
+
12
+ uses(empty: Hokusai::Blocks::Empty)
13
+
14
+ computed! :value
15
+ computed! :icons
16
+ computed :size, default: 24, convert: proc(&:to_i)
17
+ computed :background, default: Hokusai::Color.new(70, 70, 70), convert: Hokusai::Color
18
+ computed :color, default: Hokusai::Color.new(244, 244, 244), convert: Hokusai::Color
19
+ computed :background_down, default: Hokusai::Color.new(33,33,33), convert: Hokusai::Color
20
+ computed :margin, default: Hokusai::Padding.new(3.0, 2.5, 3.0, 2.5), convert: Hokusai::Padding
21
+
22
+ attr_accessor :down
23
+
24
+ def initialize(**args)
25
+ @down = false
26
+
27
+ super
28
+ end
29
+
30
+ def set_down(event)
31
+ if !down
32
+ emit("clicked", value[0], event)
33
+
34
+ self.down = true
35
+ else
36
+ emit("released", value[0], event)
37
+ end
38
+ end
39
+
40
+ def set_up(event)
41
+ self.down = false
42
+ emit("released", value[0], event)
43
+ end
44
+
45
+ def render(canvas)
46
+ hpad = (canvas.width - size) / 2
47
+ vpad = (canvas.height - margin.height - size) / 2
48
+
49
+ draw do
50
+ if icon = icons[value[0]]
51
+ rect(canvas.x + margin.left, canvas.y + margin.top, canvas.width - margin.width, canvas.height - margin.height) do |command|
52
+ command.color = icon[:background]# down ? background_down : background
53
+ command.round = 6.0
54
+ end
55
+
56
+ svg(icon[:file], canvas.x + icon[:size] / 3, canvas.y + icon[:size] / 3, icon[:size], icon[:size]) do |command|
57
+ command.color = icon[:color]
58
+ end
59
+ else
60
+ rect(canvas.x + margin.left, canvas.y + margin.top, canvas.width - margin.width, canvas.height - margin.height) do |command|
61
+ command.color = down ? background_down : background
62
+ command.round = 6.0
63
+ end
64
+
65
+ text(value[1].to_s, canvas.x + hpad + margin.width, canvas.y + margin.height) do |command|
66
+ command.color = color
67
+ command.size = size
68
+ end
69
+ end
70
+ end
71
+
72
+ yield canvas
73
+ end
74
+ end
75
+
76
+ class KeyboardRow < Hokusai::Block
77
+ style <<~EOF
78
+ [style]
79
+ keyboardStyle {
80
+ background: rgb(28, 28, 28);
81
+ }
82
+ keyStyle {
83
+ background: rgb(46, 46, 46);
84
+ color: rgb(208, 205, 218);
85
+ background_down: rgb(37, 37, 37);
86
+ }
87
+ EOF
88
+
89
+ template <<~EOF
90
+ [template]
91
+ hblock { ...keyboardStyle }
92
+ [for="number in keys"]
93
+ key {
94
+ ...keyStyle
95
+ :width="width(number)"
96
+ :icons="icons"
97
+ :key="loop_key(number)"
98
+ :value="number"
99
+ @clicked="emit_key"
100
+ @released="emit_released"
101
+ }
102
+ EOF
103
+
104
+ uses(
105
+ hblock: Hblock,
106
+ vblock: Vblock,
107
+ key: Key
108
+ )
109
+
110
+ computed! :keys
111
+ computed! :icons
112
+
113
+ # def on_mounted
114
+ # node.meta.set_prop(:height, 48.0)
115
+ # end
116
+
117
+ def width(key)
118
+ if icon = icons[key[0]]
119
+ icon[:width]
120
+ end
121
+ end
122
+
123
+ def loop_key(value)
124
+ "key-#{value}"
125
+ end
126
+
127
+ def emit_key(key, event)
128
+ emit("key", key, event)
129
+ end
130
+
131
+ def emit_released(key, event)
132
+ emit("released", key, event)
133
+ end
134
+ end
135
+
136
+ class Keyboard < Hokusai::Block
137
+ style <<~EOF
138
+ [style]
139
+ kstyle {
140
+ padding: padding(10.0, 5.0, 10.0, 5.0);
141
+ background: rgb(28, 28, 28);
142
+ }
143
+ EOF
144
+
145
+ template <<~EOF
146
+ [template]
147
+ vblock { ...kstyle }
148
+ [for="row in key_rows"]
149
+ row {
150
+ :icons="icons"
151
+ @released="handle_released"
152
+ @key="handle_keypress"
153
+ :key="index"
154
+ :keys="row"
155
+ }
156
+ EOF
157
+
158
+ uses(
159
+ vblock: Hokusai::Blocks::Vblock,
160
+ row: KeyboardRow
161
+ )
162
+
163
+
164
+ def self.icons
165
+ {
166
+ :shift => {
167
+ file: Hokusai.asset("icons/outline/arrow-big-up.svg"),
168
+ width: 54.0,
169
+ size: 30,
170
+ background: Hokusai::Color.new(50, 109, 70),
171
+ color: Hokusai::Color.new(172, 224, 189)
172
+ },
173
+ :backspace => {
174
+ file: Hokusai.asset("icons/outline/backspace.svg"),
175
+ width: 54.0,
176
+ size: 30,
177
+ background: Hokusai::Color.new(50, 109, 70),
178
+ color: Hokusai::Color.new(172, 224, 189)
179
+ }
180
+ }
181
+ end
182
+
183
+ computed :icons, default: icons
184
+ computed :row_height, default: 48.0, convert: proc(&:to_f)
185
+
186
+ def on_mounted
187
+ node.meta.set_prop(:height, row_height * 5.0 + 20)
188
+ end
189
+
190
+ def space_row
191
+ [[:comma, ","], [:space, ''], [:period, "."]]
192
+ end
193
+
194
+ def key_rows
195
+ [number_keys, querty_keys, asdf_keys, zxcv_keys, space_row]
196
+ end
197
+
198
+ def handle_released(key, event)
199
+ event.input.keyboard_override = false
200
+ end
201
+
202
+ def handle_keypress(key, event)
203
+ event.input.keyboard_override = true
204
+ LibHokusai.hoku_input_keyboard_start(event.input.raw)
205
+ LibHokusai.hoku_input_keyboard_set_key(event.input.raw, key.to_sym, true)
206
+ LibHokusai.hoku_input_keyboard_stop(event.input.raw)
207
+ end
208
+
209
+ def zxcv_keys
210
+ @zxcv_keys ||= begin
211
+ keys = %w[z x c v b n m]
212
+ middle = keys.zip(keys)
213
+ middle << [:backspace, :backspace]
214
+ middle.unshift([:shift, :shift])
215
+ middle
216
+ end
217
+ end
218
+
219
+ def asdf_keys
220
+ keys = %w[a s d f g h j k l]
221
+ @asdf_keys ||= keys.zip(keys)
222
+ end
223
+
224
+ def querty_keys
225
+ keys = %w[q w e r t y u i o p]
226
+ @querty_keys ||= keys.zip(keys)
227
+ end
228
+
229
+ def number_keys
230
+ keys = [[:one,1],[:two, 2], [:three,3], [:four,4],[:five, 5], [:six,6], [:seven,7], [:eight,8],[:nine,9], [:zero, 0]]
231
+ @number_keys ||= keys
232
+ end
233
+ end
234
+ end