glimmer-dsl-libui 0.2.21 → 0.3.0
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/CHANGELOG.md +24 -0
- data/README.md +571 -42
- data/VERSION +1 -1
- data/examples/area_gallery.rb +1 -1
- data/examples/area_gallery2.rb +1 -1
- data/examples/area_gallery3.rb +1 -1
- data/examples/area_gallery4.rb +1 -1
- data/examples/basic_image.rb +19 -0
- data/examples/basic_image2.rb +13 -0
- data/examples/basic_image3.rb +23 -0
- data/examples/basic_image4.rb +17 -0
- data/examples/basic_image5.rb +75 -0
- data/examples/meta_example.rb +1 -1
- data/examples/snake/model/apple.rb +33 -0
- data/examples/snake/model/game.rb +51 -0
- data/examples/snake/model/snake.rb +95 -0
- data/examples/snake/model/vertebra.rb +22 -0
- data/examples/snake/presenter/cell.rb +27 -0
- data/examples/snake/presenter/grid.rb +47 -0
- data/examples/snake.rb +90 -0
- data/examples/tetris/model/game.rb +1 -1
- data/examples/tetris.rb +23 -3
- data/examples/tic_tac_toe.rb +1 -1
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +1 -1
- data/lib/glimmer/libui/control_proxy/image_part_proxy.rb +0 -1
- data/lib/glimmer/libui/control_proxy/image_proxy.rb +152 -12
- data/lib/glimmer/libui/control_proxy/window_proxy.rb +1 -1
- data/lib/glimmer/libui/control_proxy.rb +7 -7
- data/lib/glimmer/libui/image_path_renderer.rb +30 -0
- data/lib/glimmer/libui.rb +6 -5
- metadata +31 -4
@@ -20,44 +20,184 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'glimmer/libui/control_proxy'
|
23
|
+
require 'glimmer/libui/image_path_renderer'
|
23
24
|
require 'glimmer/data_binding/observer'
|
25
|
+
require 'glimmer/libui/control_proxy/transformable'
|
24
26
|
|
25
27
|
using ArrayIncludeMethods
|
26
28
|
|
27
29
|
module Glimmer
|
28
30
|
module LibUI
|
29
31
|
class ControlProxy
|
30
|
-
# Proxy for LibUI image
|
32
|
+
# Proxy for LibUI image object and Glimmer custom control
|
31
33
|
#
|
32
34
|
# Follows the Proxy Design Pattern
|
33
35
|
class ImageProxy < ControlProxy
|
36
|
+
include Parent
|
37
|
+
prepend Transformable
|
38
|
+
|
39
|
+
attr_reader :data, :pixels, :shapes
|
40
|
+
|
34
41
|
def initialize(keyword, parent, args, &block)
|
35
42
|
@keyword = keyword
|
36
43
|
@parent_proxy = parent
|
37
44
|
@args = args
|
38
45
|
@block = block
|
39
46
|
@enabled = true
|
40
|
-
@children = []
|
41
47
|
post_add_content if @block.nil?
|
42
48
|
end
|
43
|
-
|
49
|
+
|
44
50
|
def post_add_content
|
45
|
-
|
46
|
-
|
51
|
+
if area_image?
|
52
|
+
@shapes = nil
|
53
|
+
super
|
54
|
+
if @parent_proxy.nil? && AreaProxy.current_area_draw_params
|
55
|
+
draw(AreaProxy.current_area_draw_params)
|
56
|
+
destroy
|
57
|
+
end
|
58
|
+
@content_added = true
|
59
|
+
else # image object not control
|
60
|
+
build_control
|
61
|
+
super
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def file(value = nil)
|
66
|
+
if area_image?
|
67
|
+
if value.nil?
|
68
|
+
@args[0]
|
69
|
+
else
|
70
|
+
@args[0] = value
|
71
|
+
if @content_added
|
72
|
+
post_add_content
|
73
|
+
request_auto_redraw
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
47
77
|
end
|
48
|
-
|
49
|
-
|
50
|
-
|
78
|
+
alias file= file
|
79
|
+
alias set_file file
|
80
|
+
|
81
|
+
def width(value = nil)
|
82
|
+
if value.nil?
|
83
|
+
area_image? ? @args[1] : @args[0]
|
84
|
+
else
|
85
|
+
if area_image?
|
86
|
+
@args[1] = value
|
87
|
+
if @content_added
|
88
|
+
post_add_content
|
89
|
+
request_auto_redraw
|
90
|
+
end
|
91
|
+
else
|
92
|
+
@args[0] = value
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
alias width= width
|
97
|
+
alias set_width width
|
98
|
+
|
99
|
+
def height(value = nil)
|
100
|
+
if value.nil?
|
101
|
+
area_image? ? @args[2] : @args[1]
|
102
|
+
else
|
103
|
+
if area_image?
|
104
|
+
@args[2] = value
|
105
|
+
if @content_added
|
106
|
+
post_add_content
|
107
|
+
request_auto_redraw
|
108
|
+
end
|
109
|
+
else
|
110
|
+
@args[1] = value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
alias height= height
|
115
|
+
alias set_height height
|
116
|
+
|
117
|
+
def redraw
|
118
|
+
@parent_proxy&.redraw
|
119
|
+
end
|
120
|
+
|
121
|
+
def request_auto_redraw
|
122
|
+
@parent_proxy&.request_auto_redraw if area_image?
|
123
|
+
end
|
124
|
+
|
125
|
+
def draw(area_draw_params)
|
126
|
+
if @shapes.nil?
|
127
|
+
load_image
|
128
|
+
parse_pixels
|
129
|
+
calculate_shapes
|
130
|
+
end
|
131
|
+
ImagePathRenderer.new(@parent_proxy, @shapes).render
|
132
|
+
end
|
133
|
+
|
134
|
+
def area_image?
|
135
|
+
@parent_proxy&.is_a?(AreaProxy) or
|
136
|
+
AreaProxy.current_area_draw_params or
|
137
|
+
@args[0].is_a?(String) # first arg is file
|
138
|
+
end
|
139
|
+
|
140
|
+
def destroy
|
141
|
+
@parent_proxy&.children&.delete(self)
|
142
|
+
ControlProxy.control_proxies.delete(self)
|
51
143
|
end
|
52
144
|
|
53
145
|
private
|
54
146
|
|
55
147
|
def build_control
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@
|
148
|
+
unless area_image? # image object
|
149
|
+
@args = [@children.first.args[1], @children.first.args[2]] if @children.size == 1 && (@args[0].nil? || @args[1].nil?)
|
150
|
+
super
|
151
|
+
@libui.tap do
|
152
|
+
@children.each {|child| child&.send(:build_control) }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def load_image
|
158
|
+
require 'chunky_png'
|
159
|
+
f = File.open(file)
|
160
|
+
canvas = ChunkyPNG::Canvas.from_io(f)
|
161
|
+
f.close
|
162
|
+
canvas.resample_nearest_neighbor!(width, height) if width && height
|
163
|
+
@data = canvas.to_rgba_stream
|
164
|
+
self.width = canvas.width
|
165
|
+
self.height = canvas.height
|
166
|
+
end
|
167
|
+
|
168
|
+
def parse_pixels
|
169
|
+
@pixels = height.times.map do |y|
|
170
|
+
width.times.map do |x|
|
171
|
+
r = @data[(y*width + x)*4].ord
|
172
|
+
g = @data[(y*width + x)*4 + 1].ord
|
173
|
+
b = @data[(y*width + x)*4 + 2].ord
|
174
|
+
a = @data[(y*width + x)*4 + 3].ord
|
175
|
+
{x: x, y: y, color: {r: r, g: g, b: b, a: a}}
|
176
|
+
end
|
177
|
+
end.flatten
|
178
|
+
end
|
179
|
+
|
180
|
+
def calculate_shapes
|
181
|
+
@shapes = []
|
182
|
+
original_pixels = @pixels.dup
|
183
|
+
indexed_original_pixels = Hash[original_pixels.each_with_index.to_a]
|
184
|
+
@pixels.each do |pixel|
|
185
|
+
index = indexed_original_pixels[pixel]
|
186
|
+
@rectangle_start_x ||= pixel[:x]
|
187
|
+
@rectangle_width ||= 1
|
188
|
+
if pixel[:x] < width - 1 && pixel[:color] == original_pixels[index + 1][:color]
|
189
|
+
@rectangle_width += 1
|
190
|
+
else
|
191
|
+
if pixel[:x] > 0 && pixel[:color] == original_pixels[index - 1][:color]
|
192
|
+
@shapes << {x: @rectangle_start_x, y: pixel[:y], width: @rectangle_width, height: 1, color: pixel[:color]}
|
193
|
+
else
|
194
|
+
@shapes << {x: pixel[:x], y: pixel[:y], width: 1, height: 1, color: pixel[:color]}
|
195
|
+
end
|
196
|
+
@rectangle_width = 1
|
197
|
+
@rectangle_start_x = pixel[:x] == width - 1 ? 0 : pixel[:x] + 1
|
198
|
+
end
|
60
199
|
end
|
200
|
+
@shapes
|
61
201
|
end
|
62
202
|
end
|
63
203
|
end
|
@@ -45,7 +45,7 @@ module Glimmer
|
|
45
45
|
|
46
46
|
def destroy
|
47
47
|
super
|
48
|
-
ControlProxy.image_proxies.each { |image_proxy| ::LibUI.free_image(image_proxy.libui) }
|
48
|
+
ControlProxy.image_proxies.each { |image_proxy| ::LibUI.free_image(image_proxy.libui) unless image_proxy.area_image? }
|
49
49
|
@on_destroy_procs&.each { |on_destroy_proc| on_destroy_proc.call(self)}
|
50
50
|
end
|
51
51
|
|
@@ -27,8 +27,8 @@ module Glimmer
|
|
27
27
|
class ControlProxy
|
28
28
|
class << self
|
29
29
|
def exists?(keyword)
|
30
|
-
::LibUI.respond_to?("new_#{keyword}")
|
31
|
-
::LibUI.respond_to?(keyword)
|
30
|
+
::LibUI.respond_to?("new_#{keyword}") or
|
31
|
+
::LibUI.respond_to?(keyword) or
|
32
32
|
descendant_keyword_constant_map.keys.include?(keyword)
|
33
33
|
end
|
34
34
|
|
@@ -207,11 +207,11 @@ module Glimmer
|
|
207
207
|
end
|
208
208
|
|
209
209
|
def respond_to_libui?(method_name, *args, &block)
|
210
|
-
::LibUI.respond_to?("control_#{method_name}")
|
211
|
-
(::LibUI.respond_to?("control_#{method_name.to_s.sub(/\?$/, '')}") && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, '')) )
|
212
|
-
::LibUI.respond_to?("control_set_#{method_name.to_s.sub(/=$/, '')}")
|
213
|
-
::LibUI.respond_to?("#{libui_api_keyword}_#{method_name}")
|
214
|
-
(::LibUI.respond_to?("#{libui_api_keyword}_#{method_name.to_s.sub(/\?$/, '')}") && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, '')) )
|
210
|
+
::LibUI.respond_to?("control_#{method_name}") or
|
211
|
+
(::LibUI.respond_to?("control_#{method_name.to_s.sub(/\?$/, '')}") && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, '')) ) or
|
212
|
+
::LibUI.respond_to?("control_set_#{method_name.to_s.sub(/=$/, '')}") or
|
213
|
+
::LibUI.respond_to?("#{libui_api_keyword}_#{method_name}") or
|
214
|
+
(::LibUI.respond_to?("#{libui_api_keyword}_#{method_name.to_s.sub(/\?$/, '')}") && BOOLEAN_PROPERTIES.include?(method_name.to_s.sub(/\?$/, '')) ) or
|
215
215
|
::LibUI.respond_to?("#{libui_api_keyword}_set_#{method_name.to_s.sub(/=$/, '')}")
|
216
216
|
end
|
217
217
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module LibUI
|
3
|
+
class ImagePathRenderer
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
def initialize(area_proxy, shapes)
|
7
|
+
@area_proxy = area_proxy
|
8
|
+
@shapes = shapes
|
9
|
+
end
|
10
|
+
|
11
|
+
def render
|
12
|
+
work = Proc.new do
|
13
|
+
@shapes.each do |shape|
|
14
|
+
path {
|
15
|
+
rectangle(shape[:x], shape[:y], shape[:width], shape[:height])
|
16
|
+
|
17
|
+
fill shape[:color]
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
if @area_proxy.nil?
|
22
|
+
# Ensure it renders without a parent
|
23
|
+
Glimmer::DSL::Engine.add_content(nil, Glimmer::DSL::Libui::ControlExpression.new, 'image', &work)
|
24
|
+
else
|
25
|
+
work.call
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/glimmer/libui.rb
CHANGED
@@ -26,12 +26,12 @@ module Glimmer
|
|
26
26
|
class << self
|
27
27
|
include Glimmer::FiddleConsumer
|
28
28
|
|
29
|
-
def integer_to_boolean(int, allow_nil: true)
|
30
|
-
int.nil? ? (allow_nil ? nil : false) : ((int.is_a?(TrueClass) || int.is_a?(FalseClass)) ? int : (int.is_a?(Integer) ? int == 1 : (allow_nil ? nil : false)))
|
29
|
+
def integer_to_boolean(int, allow_nil: true, allow_boolean: true)
|
30
|
+
int.nil? ? (allow_nil ? nil : false) : (allow_boolean && (int.is_a?(TrueClass) || int.is_a?(FalseClass)) ? int : (int.is_a?(Integer) ? int == 1 : (allow_nil ? nil : false)))
|
31
31
|
end
|
32
32
|
|
33
|
-
def boolean_to_integer(bool, allow_nil: true)
|
34
|
-
bool.nil? ? (allow_nil ? nil : 0) : (bool.is_a?(Integer) ? bool : (bool.is_a?(TrueClass) || bool.is_a?(FalseClass) ? (bool == true ? 1 : 0) : (allow_nil ? nil : 0)))
|
33
|
+
def boolean_to_integer(bool, allow_nil: true, allow_integer: true)
|
34
|
+
bool.nil? ? (allow_nil ? nil : 0) : (allow_integer && bool.is_a?(Integer) ? bool : (bool.is_a?(TrueClass) || bool.is_a?(FalseClass) ? (bool == true ? 1 : 0) : (allow_nil ? nil : 0)))
|
35
35
|
end
|
36
36
|
|
37
37
|
def degrees_to_radians(degrees)
|
@@ -83,6 +83,7 @@ module Glimmer
|
|
83
83
|
value = value.chars.map {|char| [char, char]}.flatten.join if value.length == 3
|
84
84
|
value = "0x#{value}"
|
85
85
|
end
|
86
|
+
value = "0x#{value[1..-1]}" if value.start_with?('#')
|
86
87
|
value = value.to_i(16)
|
87
88
|
end
|
88
89
|
if value.is_a?(Integer)
|
@@ -173,7 +174,7 @@ module Glimmer
|
|
173
174
|
# If block returns true at any point, the timer continues for another repetition regardless of `repeat:` keyword arg value
|
174
175
|
def timer(time_in_seconds = 0.1, repeat: true, &block)
|
175
176
|
closure = fiddle_closure_block_caller(4, [0]) do
|
176
|
-
result = boolean_to_integer(block.call)
|
177
|
+
result = boolean_to_integer(block.call, allow_integer: false)
|
177
178
|
repeat -= 1 if repeat.is_a?(Integer)
|
178
179
|
if result.nil?
|
179
180
|
if (repeat == true || (repeat.is_a?(Integer) && repeat > 0))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.4.
|
19
|
+
version: 2.4.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.4.
|
26
|
+
version: 2.4.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: os
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,6 +72,20 @@ dependencies:
|
|
72
72
|
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: 0.0.12
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: chunky_png
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.4.0
|
82
|
+
type: :runtime
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.4.0
|
75
89
|
- !ruby/object:Gem::Dependency
|
76
90
|
name: juwelier
|
77
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,6 +235,11 @@ files:
|
|
221
235
|
- examples/basic_draw_text.rb
|
222
236
|
- examples/basic_draw_text2.rb
|
223
237
|
- examples/basic_entry.rb
|
238
|
+
- examples/basic_image.rb
|
239
|
+
- examples/basic_image2.rb
|
240
|
+
- examples/basic_image3.rb
|
241
|
+
- examples/basic_image4.rb
|
242
|
+
- examples/basic_image5.rb
|
224
243
|
- examples/basic_table.rb
|
225
244
|
- examples/basic_table_button.rb
|
226
245
|
- examples/basic_table_checkbox.rb
|
@@ -252,6 +271,13 @@ files:
|
|
252
271
|
- examples/method_based_custom_keyword.rb
|
253
272
|
- examples/midi_player.rb
|
254
273
|
- examples/simple_notepad.rb
|
274
|
+
- examples/snake.rb
|
275
|
+
- examples/snake/model/apple.rb
|
276
|
+
- examples/snake/model/game.rb
|
277
|
+
- examples/snake/model/snake.rb
|
278
|
+
- examples/snake/model/vertebra.rb
|
279
|
+
- examples/snake/presenter/cell.rb
|
280
|
+
- examples/snake/presenter/grid.rb
|
255
281
|
- examples/tetris.rb
|
256
282
|
- examples/tetris/model/block.rb
|
257
283
|
- examples/tetris/model/game.rb
|
@@ -340,6 +366,7 @@ files:
|
|
340
366
|
- lib/glimmer/libui/control_proxy/transformable.rb
|
341
367
|
- lib/glimmer/libui/control_proxy/triple_column.rb
|
342
368
|
- lib/glimmer/libui/control_proxy/window_proxy.rb
|
369
|
+
- lib/glimmer/libui/image_path_renderer.rb
|
343
370
|
- lib/glimmer/libui/parent.rb
|
344
371
|
- lib/glimmer/libui/shape.rb
|
345
372
|
- lib/glimmer/libui/shape/arc.rb
|