glimmer-dsl-libui 0.2.23 → 0.3.2

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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.23
1
+ 0.3.2
data/bin/girb CHANGED
File without changes
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+
5
+ include Glimmer
6
+
7
+ window('Basic Image', 96, 96) {
8
+ area {
9
+ # image is not a real LibUI control. It is built in Glimmer as a custom control that renders
10
+ # tiny pixels/lines as rectangle paths. As such, it does not have good performance, but can
11
+ # be used in exceptional circumstances where an image control is really needed.
12
+ #
13
+ # Furthermore, adding image directly under area is even slower due to taking up more memory for every
14
+ # image pixel rendered. Check basic_image2.rb for a faster alternative using on_draw manually.
15
+ #
16
+ # It is recommended to pass width/height args to shrink image and achieve faster performance.
17
+ image(File.expand_path('../icons/glimmer.png', __dir__), 96, 96)
18
+ }
19
+ }.show
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+
5
+ include Glimmer
6
+
7
+ window('Basic Image', 96, 96) {
8
+ area {
9
+ on_draw do |area_draw_params|
10
+ image(File.expand_path('../icons/glimmer.png', __dir__), 96, 96)
11
+ end
12
+ }
13
+ }.show
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+
5
+ include Glimmer
6
+
7
+ window('Basic Image', 96, 96) {
8
+ area {
9
+ # image is not a real LibUI control. It is built in Glimmer as a custom control that renders
10
+ # tiny pixels/lines as rectangle paths. As such, it does not have good performance, but can
11
+ # be used in exceptional circumstances where an image control is really needed.
12
+ #
13
+ # Furthermore, adding image directly under area is even slower due to taking up more memory for every
14
+ # image pixel rendered. Check basic_image4.rb for a faster alternative using on_draw manually.
15
+ #
16
+ # It is recommended to pass width/height args to shrink image and achieve faster performance.
17
+ image {
18
+ file File.expand_path('../icons/glimmer.png', __dir__)
19
+ width 96
20
+ height 96
21
+ }
22
+ }
23
+ }.show
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+
5
+ include Glimmer
6
+
7
+ window('Basic Image', 96, 96) {
8
+ area {
9
+ on_draw do |area_draw_params|
10
+ image {
11
+ file File.expand_path('../icons/glimmer.png', __dir__)
12
+ width 96
13
+ height 96
14
+ }
15
+ end
16
+ }
17
+ }.show
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the manual way of rendering an image unto an area control.
4
+ # It could come in handy in special situations.
5
+ # Otherwise, it is recommended to simply utilize the `image` control that
6
+ # can be nested under area or area on_draw listener to automate all this work.
7
+
8
+ require 'glimmer-dsl-libui'
9
+ require 'chunky_png'
10
+
11
+ include Glimmer
12
+
13
+ puts 'Parsing image...'; $stdout.flush
14
+
15
+ f = File.open(File.expand_path('../icons/glimmer.png', __dir__))
16
+ canvas = ChunkyPNG::Canvas.from_io(f)
17
+ f.close
18
+ canvas.resample_nearest_neighbor!(96, 96)
19
+ data = canvas.to_rgba_stream
20
+ width = canvas.width
21
+ height = canvas.height
22
+ puts "Image width: #{width}"
23
+ puts "Image height: #{height}"
24
+
25
+ puts 'Parsing colors...'; $stdout.flush
26
+
27
+ color_maps = height.times.map do |y|
28
+ width.times.map do |x|
29
+ r = data[(y*width + x)*4].ord
30
+ g = data[(y*width + x)*4 + 1].ord
31
+ b = data[(y*width + x)*4 + 2].ord
32
+ a = data[(y*width + x)*4 + 3].ord
33
+ {x: x, y: y, color: {r: r, g: g, b: b, a: a}}
34
+ end
35
+ end.flatten
36
+ puts "#{color_maps.size} pixels to render..."; $stdout.flush
37
+
38
+ puts 'Parsing shapes...'; $stdout.flush
39
+
40
+ shape_maps = []
41
+ original_color_maps = color_maps.dup
42
+ indexed_original_color_maps = Hash[original_color_maps.each_with_index.to_a]
43
+ color_maps.each do |color_map|
44
+ index = indexed_original_color_maps[color_map]
45
+ @rectangle_start_x ||= color_map[:x]
46
+ @rectangle_width ||= 1
47
+ if color_map[:x] < width - 1 && color_map[:color] == original_color_maps[index + 1][:color]
48
+ @rectangle_width += 1
49
+ else
50
+ if color_map[:x] > 0 && color_map[:color] == original_color_maps[index - 1][:color]
51
+ shape_maps << {x: @rectangle_start_x, y: color_map[:y], width: @rectangle_width, height: 1, color: color_map[:color]}
52
+ else
53
+ shape_maps << {x: color_map[:x], y: color_map[:y], width: 1, height: 1, color: color_map[:color]}
54
+ end
55
+ @rectangle_width = 1
56
+ @rectangle_start_x = color_map[:x] == width - 1 ? 0 : color_map[:x] + 1
57
+ end
58
+ end
59
+ puts "#{shape_maps.size} shapes to render..."; $stdout.flush
60
+
61
+ puts 'Rendering image...'; $stdout.flush
62
+
63
+ window('Basic Image', 96, 96) {
64
+ area {
65
+ on_draw do |area_draw_params|
66
+ shape_maps.each do |shape_map|
67
+ path {
68
+ rectangle(shape_map[:x], shape_map[:y], shape_map[:width], shape_map[:height])
69
+
70
+ fill shape_map[:color]
71
+ }
72
+ end
73
+ end
74
+ }
75
+ }.show
@@ -1,20 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'glimmer-dsl-libui'
4
- require 'chunky_png'
5
4
 
6
5
  include Glimmer
7
6
 
8
- f = File.open(File.expand_path('../icons/glimmer.png', __dir__))
9
- canvas = ChunkyPNG::Canvas.from_io(f)
10
- f.close
11
- canvas.resample_nearest_neighbor!(24, 24)
12
- data = canvas.to_rgba_stream
13
- width = canvas.width
14
- height = canvas.height
15
- img = image {
16
- image_part(data, width, height, width * 4)
17
- }
7
+ img = image(File.expand_path('../icons/glimmer.png', __dir__), 24, 24)
18
8
 
19
9
  data = [
20
10
  [['cat', :red] , ['meow', :blue] , [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], {r: 255, g: 120, b: 0, a: 0.5}],
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+ require 'chunky_png'
5
+
6
+ include Glimmer
7
+
8
+ f = File.open(File.expand_path('../icons/glimmer.png', __dir__))
9
+ canvas = ChunkyPNG::Canvas.from_io(f)
10
+ f.close
11
+ canvas.resample_nearest_neighbor!(24, 24)
12
+ data = canvas.to_rgba_stream
13
+ width = canvas.width
14
+ height = canvas.height
15
+ img = image {
16
+ image_part(data, width, height, width * 4)
17
+ }
18
+
19
+ data = [
20
+ [['cat', :red] , ['meow', :blue] , [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], {r: 255, g: 120, b: 0, a: 0.5}],
21
+ [['dog', :yellow] , ['woof', {r: 240, g: 32, b: 32}] , [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], :skyblue],
22
+ [['chicken', :beige], ['cock-a-doodle-doo', :blue] , [false, 'mammal', :red] , [img, 'Glimmer', :beige], {r: 5, g: 120, b: 110}],
23
+ [['horse', :purple] , ['neigh', {r: 240, g: 32, b: 32}], [true, 'mammal', :green], [img, 'Glimmer', :dark_blue], '13a1fb'],
24
+ [['cow', :gray] , ['moo', :blue] , [true, 'mammal', :green], [img, 'Glimmer', :brown], 0x12ff02]
25
+ ]
26
+
27
+ window('Animals', 500, 200) {
28
+ horizontal_box {
29
+ table {
30
+ text_color_column('Animal')
31
+ text_color_column('Sound')
32
+ checkbox_text_color_column('Description')
33
+ image_text_color_column('GUI')
34
+ background_color_column('Mammal')
35
+
36
+ cell_rows data
37
+ }
38
+ }
39
+ }.show
@@ -4,8 +4,6 @@
4
4
  # This example displays images that can be freely downloaded from the Studio Ghibli website.
5
5
 
6
6
  require 'glimmer-dsl-libui'
7
- require 'chunky_png'
8
- require 'open-uri'
9
7
 
10
8
  include Glimmer
11
9
 
@@ -13,18 +11,8 @@ IMAGE_ROWS = []
13
11
 
14
12
  50.times do |i|
15
13
  url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
16
- puts "Processing Image: #{url}"
17
- $stdout.flush # for Windows
18
- f = URI.open(url)
19
- canvas = ChunkyPNG::Canvas.from_io(f)
20
- f.close
21
- data = canvas.to_rgba_stream
22
- width = canvas.width
23
- height = canvas.height
24
- img = image {
25
- image_part(data, width, height, width * 4)
26
- }
27
- IMAGE_ROWS << [img] # array of one column cell
14
+ puts "Processing Image: #{url}"; $stdout.flush # for Windows
15
+ IMAGE_ROWS << [image(url)] # array of one column cell
28
16
  rescue StandardError => e
29
17
  warn url, e.message
30
18
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # NOTE:
4
+ # This example displays images that can be freely downloaded from the Studio Ghibli website.
5
+
6
+ require 'glimmer-dsl-libui'
7
+ require 'chunky_png'
8
+ require 'open-uri'
9
+
10
+ include Glimmer
11
+
12
+ IMAGE_ROWS = []
13
+
14
+ 50.times do |i|
15
+ url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
16
+ puts "Processing Image: #{url}"
17
+ $stdout.flush # for Windows
18
+ f = URI.open(url)
19
+ canvas = ChunkyPNG::Canvas.from_io(f)
20
+ f.close
21
+ data = canvas.to_rgba_stream
22
+ width = canvas.width
23
+ height = canvas.height
24
+ img = image {
25
+ image_part(data, width, height, width * 4)
26
+ }
27
+ IMAGE_ROWS << [img] # array of one column cell
28
+ rescue StandardError => e
29
+ warn url, e.message
30
+ end
31
+
32
+ window('The Red Turtle', 310, 350, false) {
33
+ horizontal_box {
34
+ table {
35
+ image_column('www.ghibli.jp/works/red-turtle')
36
+
37
+ cell_rows IMAGE_ROWS
38
+ }
39
+ }
40
+
41
+ on_closing do
42
+ puts 'Bye Bye'
43
+ end
44
+ }.show
@@ -4,8 +4,6 @@
4
4
  # This example displays images that can be freely downloaded from the Studio Ghibli website.
5
5
 
6
6
  require 'glimmer-dsl-libui'
7
- require 'chunky_png'
8
- require 'open-uri'
9
7
 
10
8
  include Glimmer
11
9
 
@@ -13,18 +11,9 @@ IMAGE_ROWS = []
13
11
 
14
12
  5.times do |i|
15
13
  url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
16
- puts "Processing Image: #{url}"
17
- $stdout.flush # for Windows
18
- f = URI.open(url)
19
- canvas = ChunkyPNG::Canvas.from_io(f)
20
- f.close
21
- data = canvas.to_rgba_stream
22
- width = canvas.width
23
- height = canvas.height
24
- img = image {
25
- image_part(data, width, height, width * 4)
26
- }
14
+ puts "Processing Image: #{url}"; $stdout.flush # for Windows
27
15
  text = url.sub('https://www.ghibli.jp/gallery/thumb-redturtle', '').sub('.png', '')
16
+ img = image(url)
28
17
  IMAGE_ROWS << [[img, text], [img, text]] # cell values are dual-element arrays
29
18
  rescue StandardError => e
30
19
  warn url, e.message
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # NOTE:
4
+ # This example displays images that can be freely downloaded from the Studio Ghibli website.
5
+
6
+ require 'glimmer-dsl-libui'
7
+ require 'chunky_png'
8
+ require 'open-uri'
9
+
10
+ include Glimmer
11
+
12
+ IMAGE_ROWS = []
13
+
14
+ 5.times do |i|
15
+ url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
16
+ puts "Processing Image: #{url}"
17
+ $stdout.flush # for Windows
18
+ f = URI.open(url)
19
+ canvas = ChunkyPNG::Canvas.from_io(f)
20
+ f.close
21
+ data = canvas.to_rgba_stream
22
+ width = canvas.width
23
+ height = canvas.height
24
+ img = image {
25
+ image_part(data, width, height, width * 4)
26
+ }
27
+ text = url.sub('https://www.ghibli.jp/gallery/thumb-redturtle', '').sub('.png', '')
28
+ IMAGE_ROWS << [[img, text], [img, text]] # cell values are dual-element arrays
29
+ rescue StandardError => e
30
+ warn url, e.message
31
+ end
32
+
33
+ window('The Red Turtle', 670, 350) {
34
+ horizontal_box {
35
+ table {
36
+ image_text_column('image/number')
37
+ image_text_column('image/number (editable)') {
38
+ editable true
39
+ }
40
+
41
+ cell_rows IMAGE_ROWS
42
+ }
43
+ }
44
+ }.show
Binary file
@@ -40,7 +40,7 @@ module Glimmer
40
40
 
41
41
  def add_content(parent, keyword, *args, &block)
42
42
  super
43
- parent.post_add_content
43
+ parent&.post_add_content
44
44
  end
45
45
  end
46
46
  end
@@ -218,6 +218,7 @@ module Glimmer
218
218
  {
219
219
  key: key_to_char(area_key_event.Key, modifiers),
220
220
  key_value: area_key_event.Key,
221
+ key_code: area_key_event.Key,
221
222
  ext_key: ext_key_to_symbol(area_key_event.ExtKey),
222
223
  ext_key_value: area_key_event.ExtKey,
223
224
  modifier: modifiers_to_symbols(area_key_event.Modifier).first,
@@ -43,9 +43,9 @@ module Glimmer
43
43
  @column_index ||= @parent_proxy.send(:next_column_index)
44
44
  end
45
45
 
46
- # actual index within table columns (disregarding nil fillings that account for DualColumn instances)
46
+ # actual index within table columns (disregarding extra fillings that account for DualColumn instances)
47
47
  def index
48
- @parent_proxy.columns.compact.index(self)
48
+ @parent_proxy.columns.select {|c| c.is_a?(Column)}.index(self)
49
49
  end
50
50
  end
51
51
  end
@@ -34,7 +34,6 @@ module Glimmer
34
34
  @args = args
35
35
  @block = block
36
36
  @enabled = true
37
- @children = []
38
37
  post_add_content if @block.nil?
39
38
  end
40
39
 
@@ -20,44 +20,191 @@
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/control_proxy/image_part_proxy'
24
+ require 'glimmer/libui/image_path_renderer'
23
25
  require 'glimmer/data_binding/observer'
26
+ require 'glimmer/libui/control_proxy/transformable'
24
27
 
25
28
  using ArrayIncludeMethods
26
29
 
27
30
  module Glimmer
28
31
  module LibUI
29
32
  class ControlProxy
30
- # Proxy for LibUI image objects
33
+ # Proxy for LibUI image object and Glimmer custom control
31
34
  #
32
35
  # Follows the Proxy Design Pattern
33
36
  class ImageProxy < ControlProxy
37
+ include Parent
38
+ prepend Transformable
39
+
40
+ attr_reader :data, :pixels, :shapes
41
+
34
42
  def initialize(keyword, parent, args, &block)
35
43
  @keyword = keyword
36
44
  @parent_proxy = parent
37
45
  @args = args
38
46
  @block = block
39
47
  @enabled = true
40
- @children = []
41
48
  post_add_content if @block.nil?
42
49
  end
43
-
50
+
44
51
  def post_add_content
45
- build_control
46
- super
52
+ if area_image?
53
+ @shapes = nil
54
+ super
55
+ if @parent_proxy.nil? && AreaProxy.current_area_draw_params
56
+ draw(AreaProxy.current_area_draw_params)
57
+ destroy
58
+ end
59
+ @content_added = true
60
+ else # image object not control
61
+ build_control
62
+ super
63
+ end
64
+ end
65
+
66
+ def file(value = nil)
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
77
+ alias file= file
78
+ alias set_file file
79
+
80
+ def width(value = nil)
81
+ if value.nil?
82
+ @args[1]
83
+ else
84
+ @args[1] = value
85
+ if area_image? && @content_added
86
+ post_add_content
87
+ request_auto_redraw
88
+ end
89
+ end
90
+ end
91
+ alias width= width
92
+ alias set_width width
93
+
94
+ def height(value = nil)
95
+ if value.nil?
96
+ @args[2]
97
+ else
98
+ @args[2] = value
99
+ if area_image? && @content_added
100
+ post_add_content
101
+ request_auto_redraw
102
+ end
103
+ end
104
+ end
105
+ alias height= height
106
+ alias set_height height
107
+
108
+ def redraw
109
+ @parent_proxy&.redraw
110
+ end
111
+
112
+ def request_auto_redraw
113
+ @parent_proxy&.request_auto_redraw if area_image?
114
+ end
115
+
116
+ def draw(area_draw_params)
117
+ if @shapes.nil?
118
+ load_image
119
+ parse_pixels
120
+ calculate_shapes
121
+ end
122
+ ImagePathRenderer.new(@parent_proxy, @shapes).render
47
123
  end
48
-
49
- def post_initialize_child(child)
50
- @children << child
124
+
125
+ def area_image?
126
+ @area_image ||= !!(@parent_proxy&.is_a?(AreaProxy) || AreaProxy.current_area_draw_params)
127
+ end
128
+
129
+ def destroy
130
+ @parent_proxy&.children&.delete(self)
131
+ ControlProxy.control_proxies.delete(self)
51
132
  end
52
133
 
53
134
  private
54
135
 
55
136
  def build_control
56
- @args = [@children.first.args[1], @children.first.args[2]] if @children.size == 1 && (@args[0].nil? || @args[1].nil?)
57
- super
58
- @libui.tap do
59
- @children.each {|child| child&.send(:build_control) }
137
+ unless area_image? # image object
138
+ if file
139
+ load_image
140
+ ImagePartProxy.new('image_part', self, [@data, width, height, width * 4])
141
+ end
142
+ @args[1] = @children.first.args[1] if @children.size == 1 && @args[1].nil?
143
+ @args[2] = @children.first.args[2] if @children.size == 1 && @args[2].nil?
144
+ @libui = ControlProxy.new_control(@keyword, [width, height])
145
+ @libui.tap do
146
+ @children.each {|child| child&.send(:build_control) }
147
+ end
148
+ end
149
+ rescue => e
150
+ Glimmer::Config.logger.error {"Failed to load image file: #{file}"}
151
+ Glimmer::Config.logger.error {e.full_message}
152
+ raise e
153
+ end
154
+
155
+ def load_image
156
+ require 'chunky_png'
157
+ canvas = nil
158
+ if file.start_with?('http')
159
+ require 'net/http'
160
+ require 'open-uri'
161
+ uri = URI(file)
162
+ canvas = ChunkyPNG::Canvas.from_string(Net::HTTP.get(uri))
163
+ else
164
+ f = File.open(file)
165
+ canvas = ChunkyPNG::Canvas.from_io(f)
166
+ f.close
167
+ end
168
+ canvas.resample_nearest_neighbor!(width, height) if width && height
169
+ @data = canvas.to_rgba_stream
170
+ self.width = canvas.width
171
+ self.height = canvas.height
172
+ [@data, width, height]
173
+ end
174
+
175
+ def parse_pixels
176
+ @pixels = height.times.map do |y|
177
+ width.times.map do |x|
178
+ r = @data[(y*width + x)*4].ord
179
+ g = @data[(y*width + x)*4 + 1].ord
180
+ b = @data[(y*width + x)*4 + 2].ord
181
+ a = @data[(y*width + x)*4 + 3].ord
182
+ {x: x, y: y, color: {r: r, g: g, b: b, a: a}}
183
+ end
184
+ end.flatten
185
+ end
186
+
187
+ def calculate_shapes
188
+ @shapes = []
189
+ original_pixels = @pixels.dup
190
+ indexed_original_pixels = Hash[original_pixels.each_with_index.to_a]
191
+ @pixels.each do |pixel|
192
+ index = indexed_original_pixels[pixel]
193
+ @rectangle_start_x ||= pixel[:x]
194
+ @rectangle_width ||= 1
195
+ if pixel[:x] < width - 1 && pixel[:color] == original_pixels[index + 1][:color]
196
+ @rectangle_width += 1
197
+ else
198
+ if pixel[:x] > 0 && pixel[:color] == original_pixels[index - 1][:color]
199
+ @shapes << {x: @rectangle_start_x, y: pixel[:y], width: @rectangle_width, height: 1, color: pixel[:color]}
200
+ else
201
+ @shapes << {x: pixel[:x], y: pixel[:y], width: 1, height: 1, color: pixel[:color]}
202
+ end
203
+ @rectangle_width = 1
204
+ @rectangle_start_x = pixel[:x] == width - 1 ? 0 : pixel[:x] + 1
205
+ end
60
206
  end
207
+ @shapes
61
208
  end
62
209
  end
63
210
  end
@@ -21,6 +21,7 @@
21
21
 
22
22
  require 'glimmer/libui/control_proxy'
23
23
  require 'glimmer/libui/control_proxy/dual_column'
24
+ require 'glimmer/libui/control_proxy/triple_column'
24
25
  require 'glimmer/data_binding/observer'
25
26
  require 'glimmer/fiddle_consumer'
26
27
 
@@ -137,7 +138,7 @@ module Glimmer
137
138
 
138
139
  def build_control
139
140
  @model_handler = ::LibUI::FFI::TableModelHandler.malloc
140
- @model_handler.NumColumns = fiddle_closure_block_caller(4) { @columns.map {|c| c.is_a?(DualColumn) ? 2 : 1}.sum }
141
+ @model_handler.NumColumns = fiddle_closure_block_caller(4) { @columns.map {|c| c.is_a?(DualColumn) ? 2 : (c.is_a?(TripleColumn) ? 3 : 1)}.sum }
141
142
  @model_handler.ColumnType = fiddle_closure_block_caller(4, [1, 1, 4]) do |_, _, column|
142
143
  # TODO consider refactoring to use Glimmer::LibUI.enum_symbols(:table_value_type)
143
144
  case @columns[column]
@@ -193,15 +194,27 @@ module Glimmer
193
194
  column = @columns[column].index
194
195
  @cell_rows[row] ||= []
195
196
  @cell_rows[row][column] = ::LibUI.table_value_string(val).to_s
197
+ when Column::TextColorColumnProxy
198
+ column = @columns[column].index
199
+ @cell_rows[row] ||= []
200
+ @cell_rows[row][column] ||= []
201
+ @cell_rows[row][column][0] = ::LibUI.table_value_string(val).to_s
196
202
  when :text
197
203
  column = @columns[column - 1].index
204
+ @cell_rows[row] ||= []
205
+ @cell_rows[row][column] ||= []
198
206
  @cell_rows[row][column][1] = ::LibUI.table_value_string(val).to_s
199
207
  when Column::ButtonColumnProxy
200
208
  @columns[column].notify_listeners(:on_clicked, row)
201
- when Column::CheckboxColumnProxy, Column::CheckboxTextColumnProxy
209
+ when Column::CheckboxColumnProxy
202
210
  column = @columns[column].index
203
211
  @cell_rows[row] ||= []
204
212
  @cell_rows[row][column] = ::LibUI.table_value_int(val).to_i == 1
213
+ when Column::CheckboxTextColumnProxy
214
+ column = @columns[column].index
215
+ @cell_rows[row] ||= []
216
+ @cell_rows[row][column] ||= []
217
+ @cell_rows[row][column][0] = ::LibUI.table_value_int(val).to_i == 1
205
218
  end
206
219
  on_edited.each {|listener| listener.call(row, @cell_rows[row])}
207
220
  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