glimmer-dsl-libui 0.2.10 → 0.2.14

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.10
1
+ 0.2.14
data/bin/girb CHANGED
File without changes
data/bin/girb_runner.rb CHANGED
@@ -27,7 +27,7 @@ require_relative '../lib/glimmer-dsl-libui'
27
27
 
28
28
  include Glimmer
29
29
 
30
- GIRB_RUNNER_EXIT_FILE = "#{Etc.getpwuid.dir}/.girb_runner_exit"
30
+ GIRB_RUNNER_EXIT_FILE = "#{Dir.home}/.girb_runner_exit"
31
31
  FileUtils.rm_rf GIRB_RUNNER_EXIT_FILE
32
32
 
33
33
  @exit_method = method(:exit)
@@ -55,11 +55,9 @@ window('Area Gallery', 400, 400) {
55
55
  stroke r: 0, g: 0, b: 0, thickness: 2
56
56
  }
57
57
  text(160, 40, 100) { # x, y, width
58
- string {
58
+ string('Area Gallery') {
59
59
  font family: 'Times', size: 14
60
60
  color :black
61
-
62
- 'Area Gallery'
63
61
  }
64
62
  }
65
63
 
@@ -56,11 +56,9 @@ window('Area Gallery', 400, 400) {
56
56
  stroke r: 0, g: 0, b: 0, thickness: 2
57
57
  }
58
58
  text(160, 40, 100) { # x, y, width
59
- string {
59
+ string('Area Gallery') {
60
60
  font family: 'Times', size: 14
61
61
  color :black
62
-
63
- 'Area Gallery'
64
62
  }
65
63
  }
66
64
  end
@@ -16,7 +16,6 @@ class BasicDrawText
16
16
  else
17
17
  color r: 0, g: 128, b: 0, a: 0.7
18
18
  end
19
-
20
19
  block.call + "\n\n"
21
20
  }
22
21
  end
@@ -12,7 +12,7 @@ data = [
12
12
  %w[cow moo delete]
13
13
  ]
14
14
 
15
- window('Animal sounds', 300, 200) {
15
+ window('Animal sounds', 400, 200) {
16
16
  horizontal_box {
17
17
  table {
18
18
  text_column('Animal')
@@ -27,6 +27,7 @@ window('Animal sounds', 300, 200) {
27
27
 
28
28
  on_changed do |row, type, row_data|
29
29
  puts "Row #{row} #{type}: #{row_data}"
30
+ $stdout.flush
30
31
  end
31
32
  }
32
33
  }
@@ -12,7 +12,7 @@ data = [
12
12
  ['cow', 'moo', true]
13
13
  ]
14
14
 
15
- window('Animal sounds', 300, 200) {
15
+ window('Animal sounds', 400, 200) {
16
16
  horizontal_box {
17
17
  table {
18
18
  text_column('Animal')
@@ -14,6 +14,7 @@ IMAGE_ROWS = []
14
14
  50.times do |i|
15
15
  url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
16
16
  puts "Processing Image: #{url}"
17
+ $stdout.flush # for Windows
17
18
  f = URI.open(url)
18
19
  canvas = ChunkyPNG::Canvas.from_io(f)
19
20
  f.close
@@ -14,6 +14,7 @@ IMAGE_ROWS = []
14
14
  5.times do |i|
15
15
  url = format('https://www.ghibli.jp/gallery/thumb-redturtle%03d.png', (i + 1))
16
16
  puts "Processing Image: #{url}"
17
+ $stdout.flush # for Windows
17
18
  f = URI.open(url)
18
19
  canvas = ChunkyPNG::Canvas.from_io(f)
19
20
  f.close
@@ -5,8 +5,8 @@ class ColorTheCircles
5
5
 
6
6
  WINDOW_WIDTH = 800
7
7
  WINDOW_HEIGHT = 600
8
- CIRCLE_MIN_RADIUS = 15
9
- CIRCLE_MAX_RADIUS = 50
8
+ SHAPE_MIN_SIZE = 15
9
+ SHAPE_MAX_SIZE = 75
10
10
  MARGIN_WIDTH = 55
11
11
  MARGIN_HEIGHT = 155
12
12
  TIME_MAX_EASY = 4
@@ -58,12 +58,12 @@ class ColorTheCircles
58
58
  end
59
59
 
60
60
  def add_circle
61
- circle_x_center = rand * (WINDOW_WIDTH - MARGIN_WIDTH - CIRCLE_MAX_RADIUS) + CIRCLE_MAX_RADIUS
62
- circle_y_center = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - CIRCLE_MAX_RADIUS) + CIRCLE_MAX_RADIUS
63
- circle_radius = rand * (CIRCLE_MAX_RADIUS - CIRCLE_MIN_RADIUS) + CIRCLE_MIN_RADIUS
61
+ circle_x = rand * (WINDOW_WIDTH - MARGIN_WIDTH - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
62
+ circle_y = rand * (WINDOW_HEIGHT - MARGIN_HEIGHT - SHAPE_MAX_SIZE) + SHAPE_MAX_SIZE
63
+ circle_size = rand * (SHAPE_MAX_SIZE - SHAPE_MIN_SIZE) + SHAPE_MIN_SIZE
64
64
  stroke_color = Glimmer::LibUI.x11_colors.sample
65
65
  @circles_data << {
66
- args: [circle_x_center, circle_y_center, circle_radius],
66
+ args: [circle_x, circle_y, circle_size],
67
67
  fill: nil,
68
68
  stroke: stroke_color
69
69
  }
@@ -79,7 +79,7 @@ class ColorTheCircles
79
79
 
80
80
  def color_circle(x, y)
81
81
  clicked_circle_data = @circles_data.find do |circle_data|
82
- circle_data[:fill].nil? && circle_data[:circle].include?(x, y)
82
+ circle_data[:fill].nil? && circle_data[:circle]&.include?(x, y)
83
83
  end
84
84
  if clicked_circle_data
85
85
  clicked_circle_data[:fill] = clicked_circle_data[:stroke]
@@ -95,7 +95,7 @@ class ColorTheCircles
95
95
  last_colored_circle_data_index = @circles_data.index(last_colored_circle_data) || -1
96
96
  @circles_data.insert(last_colored_circle_data_index + 1, removed_colored_circle_data)
97
97
  end
98
-
98
+
99
99
  def launch
100
100
  menu('Actions') {
101
101
  menu_item('Restart') {
@@ -190,24 +190,24 @@ class ColorTheCircles
190
190
  vexpand true
191
191
  halign :fill
192
192
  valign :fill
193
-
193
+
194
194
  on_draw do |area_draw_params|
195
195
  path {
196
196
  rectangle(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT)
197
-
197
+
198
198
  fill :white
199
199
  }
200
-
200
+
201
201
  @circles_data.each do |circle_data|
202
202
  path {
203
203
  circle_data[:circle] = circle(*circle_data[:args])
204
-
204
+
205
205
  fill circle_data[:fill]
206
206
  stroke circle_data[:stroke]
207
207
  }
208
208
  end
209
209
  end
210
-
210
+
211
211
  on_mouse_down do |area_mouse_event|
212
212
  color_circle(area_mouse_event[:x], area_mouse_event[:y])
213
213
  end
@@ -9,6 +9,7 @@ menu('File') {
9
9
  on_clicked do
10
10
  file = open_file
11
11
  puts file unless file.nil?
12
+ $stdout.flush # for Windows
12
13
  end
13
14
  }
14
15
 
@@ -16,6 +17,7 @@ menu('File') {
16
17
  on_clicked do
17
18
  file = save_file
18
19
  puts file unless file.nil?
20
+ $stdout.flush # for Windows
19
21
  end
20
22
  }
21
23
 
@@ -98,6 +100,7 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
98
100
 
99
101
  on_changed do |s|
100
102
  puts "New Spinbox value: #{s.value}"
103
+ $stdout.flush # for Windows
101
104
  end
102
105
  }
103
106
 
@@ -107,6 +110,7 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
107
110
  on_changed do |s|
108
111
  v = s.value
109
112
  puts "New Slider value: #{v}"
113
+ $stdout.flush # for Windows
110
114
  @progress_bar.value = v
111
115
  end
112
116
  }
@@ -125,6 +129,7 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
125
129
 
126
130
  on_selected do |c|
127
131
  puts "New combobox selection: #{c.selected}"
132
+ $stdout.flush # for Windows
128
133
  end
129
134
  }
130
135
 
@@ -147,6 +152,7 @@ MAIN_WINDOW = window('Control Gallery', 600, 500) {
147
152
 
148
153
  on_changed do |e|
149
154
  puts "Current textbox data: '#{e.text}'"
155
+ $stdout.flush # for Windows
150
156
  end
151
157
  }
152
158
  }
@@ -23,10 +23,12 @@ window('Editable animal sounds', 300, 200) {
23
23
 
24
24
  on_changed do |row, type, row_data| # fires on all changes (even ones happening through data array)
25
25
  puts "Row #{row} #{type}: #{row_data}"
26
+ $stdout.flush
26
27
  end
27
28
 
28
29
  on_edited do |row, row_data| # only fires on direct table editing
29
30
  puts "Row #{row} edited: #{row_data}"
31
+ $stdout.flush
30
32
  end
31
33
  }
32
34
  }
@@ -1,5 +1,6 @@
1
1
  require 'glimmer-dsl-libui'
2
2
  require 'facets'
3
+ require 'fileutils'
3
4
 
4
5
  class MetaExample
5
6
  include Glimmer
@@ -41,15 +42,20 @@ class MetaExample
41
42
  end
42
43
 
43
44
  def run_example(example)
44
- command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
45
- result = ''
46
- IO.popen(command) do |f|
47
- f.each_line do |line|
48
- result << line
49
- puts line
45
+ Thread.new do
46
+ command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
47
+ result = ''
48
+ IO.popen(command) do |f|
49
+ sleep(0.01) # yield to main thread
50
+ f.each_line do |line|
51
+ result << line
52
+ puts line
53
+ $stdout.flush # for Windows
54
+ sleep(0.01) # yield to main thread
55
+ end
50
56
  end
57
+ Glimmer::LibUI.queue_main { msg_box('Error Running Example', result) } if result.downcase.include?('error')
51
58
  end
52
- msg_box('Error Running Example', result) if result.downcase.include?('error')
53
59
  end
54
60
 
55
61
  def launch
@@ -100,9 +106,13 @@ class MetaExample
100
106
  button('Launch') {
101
107
  on_clicked do
102
108
  begin
103
- meta_example_file = File.join(Dir.home, '.meta_example.rb')
104
- File.write(meta_example_file, @code_entry.text)
105
- run_example(meta_example_file)
109
+ parent_dir = File.join(Dir.home, '.glimmer-dsl-libui', 'examples')
110
+ FileUtils.mkdir_p(parent_dir)
111
+ example_file = File.join(parent_dir, "#{selected_example.underscore}.rb")
112
+ File.write(example_file, @code_entry.text)
113
+ FileUtils.cp_r(File.expand_path('../icons', __dir__), File.dirname(parent_dir))
114
+ FileUtils.cp_r(File.expand_path('../sounds', __dir__), File.dirname(parent_dir))
115
+ run_example(example_file)
106
116
  rescue => e
107
117
  puts e.full_message
108
118
  puts 'Unable to write code changes! Running original example...'
@@ -5,7 +5,7 @@ include Glimmer
5
5
 
6
6
  Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
7
7
 
8
- def field(model, property)
8
+ def form_field(model, property)
9
9
  property = property.to_s
10
10
  entry { |e|
11
11
  label property.underscore.split('_').map(&:capitalize).join(' ')
@@ -19,11 +19,11 @@ end
19
19
 
20
20
  def address_form(address)
21
21
  form {
22
- field(address, :street)
23
- field(address, :p_o_box)
24
- field(address, :city)
25
- field(address, :state)
26
- field(address, :zip_code)
22
+ form_field(address, :street)
23
+ form_field(address, :p_o_box)
24
+ form_field(address, :city)
25
+ form_field(address, :state)
26
+ form_field(address, :zip_code)
27
27
  }
28
28
  end
29
29
 
@@ -58,29 +58,39 @@ window('Method-Based Custom Keyword') {
58
58
  label('Address 1') {
59
59
  stretchy false
60
60
  }
61
+
61
62
  address_form(address1)
63
+
62
64
  horizontal_separator {
63
65
  stretchy false
64
66
  }
67
+
65
68
  label('Address 1 (Saved)') {
66
69
  stretchy false
67
70
  }
71
+
68
72
  address(address1)
69
73
  }
74
+
70
75
  vertical_separator {
71
76
  stretchy false
72
77
  }
78
+
73
79
  vertical_box {
74
80
  label('Address 2') {
75
81
  stretchy false
76
82
  }
83
+
77
84
  address_form(address2)
85
+
78
86
  horizontal_separator {
79
87
  stretchy false
80
88
  }
89
+
81
90
  label('Address 2 (Saved)') {
82
91
  stretchy false
83
92
  }
93
+
84
94
  address(address2)
85
95
  }
86
96
  }
Binary file
@@ -33,6 +33,8 @@ module Glimmer
33
33
  end
34
34
 
35
35
  def interpret(parent, keyword, *args, &block)
36
+ @@inverted_keyword_aliases = Glimmer::LibUI::ControlProxy::KEYWORD_ALIASES.invert unless defined?(@@inverted_keyword_aliases)
37
+ keyword = @@inverted_keyword_aliases[keyword] || keyword
36
38
  Glimmer::LibUI::ControlProxy.create(keyword, parent, args, &block)
37
39
  end
38
40
 
@@ -32,11 +32,18 @@ module Glimmer
32
32
 
33
33
  def can_interpret?(parent, keyword, *args, &block)
34
34
  super and
35
- parent.is_a?(Glimmer::LibUI::ControlProxy::TextProxy)
35
+ (
36
+ parent.is_a?(Glimmer::LibUI::ControlProxy::TextProxy) or
37
+ parent.is_a?(Glimmer::LibUI::AttributedString)
38
+ )
36
39
  end
37
40
 
38
41
  def interpret(parent, keyword, *args, &block)
39
- Glimmer::LibUI::AttributedString.new(keyword, parent, args, &block)
42
+ if parent.is_a?(Glimmer::LibUI::ControlProxy::TextProxy)
43
+ Glimmer::LibUI::AttributedString.new(keyword, parent, args, &block)
44
+ else
45
+ parent.string = args.join
46
+ end
40
47
  end
41
48
 
42
49
  def add_content(parent, keyword, *args, &block)
@@ -27,7 +27,6 @@ require 'glimmer/libui/control_proxy/transformable'
27
27
  module Glimmer
28
28
  module LibUI
29
29
  class AttributedString
30
- attr_accessor :string
31
30
  attr_reader :block, :keyword, :parent_proxy, :args
32
31
 
33
32
  def initialize(keyword, parent_proxy, args, &block)
@@ -39,6 +38,17 @@ module Glimmer
39
38
  post_add_content if @block.nil?
40
39
  end
41
40
 
41
+ def string(value = nil)
42
+ if value.nil?
43
+ @string
44
+ else
45
+ @string = value
46
+ redraw
47
+ end
48
+ end
49
+ alias string= string
50
+ alias set_string string
51
+
42
52
  def font(value = nil)
43
53
  if value.nil?
44
54
  @font
@@ -106,7 +116,7 @@ module Glimmer
106
116
  alias set_open_type_features open_type_features
107
117
 
108
118
  def post_add_content
109
- block_result = block&.call
119
+ block_result = @block&.call
110
120
  @string = block_result if block_result.is_a?(String)
111
121
  @parent_proxy&.post_initialize_child(self)
112
122
  end
@@ -141,16 +151,26 @@ module Glimmer
141
151
  end
142
152
  end
143
153
  unless font.nil?
144
- family_attribute = ::LibUI.new_family_attribute(font[:family])
145
- ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, family_attribute, @start, @start + @string.size)
146
- size_attribute = ::LibUI.new_size_attribute(font[:size])
147
- ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, size_attribute, @start, @start + @string.size)
148
- weight_attribute = ::LibUI.new_weight_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_weight, font[:weight]))
149
- ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, weight_attribute, @start, @start + @string.size)
150
- italic_attribute = ::LibUI.new_italic_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_italic, font[:italic]))
151
- ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, italic_attribute, @start, @start + @string.size)
152
- stretch_attribute = ::LibUI.new_stretch_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_stretch, font[:stretch]))
153
- ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, stretch_attribute, @start, @start + @string.size)
154
+ if font[:family]
155
+ family_attribute = ::LibUI.new_family_attribute(font[:family])
156
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, family_attribute, @start, @start + @string.size)
157
+ end
158
+ if font[:size]
159
+ size_attribute = ::LibUI.new_size_attribute(font[:size])
160
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, size_attribute, @start, @start + @string.size)
161
+ end
162
+ if font[:weight]
163
+ weight_attribute = ::LibUI.new_weight_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_weight, font[:weight]))
164
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, weight_attribute, @start, @start + @string.size)
165
+ end
166
+ if font[:italic]
167
+ italic_attribute = ::LibUI.new_italic_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_italic, font[:italic]))
168
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, italic_attribute, @start, @start + @string.size)
169
+ end
170
+ if font[:stretch]
171
+ stretch_attribute = ::LibUI.new_stretch_attribute(Glimmer::LibUI.enum_symbol_to_value(:text_stretch, font[:stretch]))
172
+ ::LibUI.attributed_string_set_attribute(@parent_proxy.attributed_string, stretch_attribute, @start, @start + @string.size)
173
+ end
154
174
  end
155
175
  unless open_type_features.nil?
156
176
  open_type_features_attribute = ::LibUI.new_features_attribute(open_type_features.libui)
@@ -37,6 +37,7 @@ module Glimmer
37
37
  end
38
38
 
39
39
  LISTENERS = ['on_draw', 'on_mouse_event', 'on_mouse_move', 'on_mouse_down', 'on_mouse_up', 'on_mouse_drag_start', 'on_mouse_drag', 'on_mouse_drop', 'on_mouse_crossed', 'on_mouse_enter', 'on_mouse_exit', 'on_drag_broken', 'on_key_event', 'on_key_down', 'on_key_up']
40
+
40
41
  LISTENER_ALIASES = {
41
42
  on_drawn: 'on_draw',
42
43
  on_mouse_moved: 'on_mouse_move',
@@ -49,6 +50,30 @@ module Glimmer
49
50
  on_drag_break: 'on_drag_broken',
50
51
  }
51
52
 
53
+ SHIFTED_KEY_CODE_CHARS = {
54
+ '`' => '~',
55
+ '1' => '!',
56
+ '2' => '@',
57
+ '3' => '#',
58
+ '4' => '$',
59
+ '5' => '%',
60
+ '6' => '^',
61
+ '7' => '&',
62
+ '8' => '*',
63
+ '9' => '(',
64
+ '10' => ')',
65
+ '-' => '_',
66
+ '=' => '+',
67
+ ',' => '<',
68
+ '.' => '>',
69
+ '/' => '?',
70
+ ';' => ':',
71
+ "'" => '"',
72
+ '[' => '{',
73
+ ']' => '}',
74
+ "\\" => '|',
75
+ }
76
+
52
77
  include Glimmer::FiddleConsumer
53
78
  include Parent
54
79
  prepend Transformable
@@ -164,19 +189,27 @@ module Glimmer
164
189
  end
165
190
 
166
191
  def area_key_event_hash(area_key_event)
192
+ modifiers = modifiers_to_symbols(area_key_event.Modifiers)
167
193
  {
168
- key: key_to_char(area_key_event.Key),
194
+ key: key_to_char(area_key_event.Key, modifiers),
169
195
  key_value: area_key_event.Key,
170
196
  ext_key: ext_key_to_symbol(area_key_event.ExtKey),
171
197
  ext_key_value: area_key_event.ExtKey,
172
198
  modifier: modifiers_to_symbols(area_key_event.Modifier).first,
173
- modifiers: modifiers_to_symbols(area_key_event.Modifiers),
199
+ modifiers: modifiers,
174
200
  up: Glimmer::LibUI.integer_to_boolean(area_key_event.Up),
175
201
  }
176
202
  end
177
203
 
178
- def key_to_char(key)
179
- key.chr if key > 0
204
+ def key_to_char(key, modifiers = [])
205
+ if key > 0
206
+ char = key.chr
207
+ if modifiers == [:shift]
208
+ SHIFTED_KEY_CODE_CHARS[char]
209
+ else
210
+ char
211
+ end
212
+ end
180
213
  end
181
214
 
182
215
  def ext_key_to_symbol(ext_key_value)
@@ -84,7 +84,7 @@ module Glimmer
84
84
  @cell_rows = rows
85
85
  @cell_rows.tap do
86
86
  @last_cell_rows = array_deep_clone(@cell_rows)
87
- Glimmer::DataBinding::Observer.proc do
87
+ Glimmer::DataBinding::Observer.proc do |new_cell_rows|
88
88
  if @cell_rows.size < @last_cell_rows.size && @last_cell_rows.include_all?(*@cell_rows)
89
89
  @last_cell_rows.array_diff_indexes(@cell_rows).reverse.each do |row|
90
90
  ::LibUI.table_model_row_deleted(model, row)
@@ -103,8 +103,9 @@ module Glimmer
103
103
  end
104
104
  end
105
105
  end
106
+ @last_last_cell_rows = array_deep_clone(@last_cell_rows)
106
107
  @last_cell_rows = array_deep_clone(@cell_rows)
107
- end.observe(self, :cell_rows)
108
+ end.observe(self, :cell_rows, recursive: true)
108
109
  end
109
110
  end
110
111
  end
@@ -112,7 +113,11 @@ module Glimmer
112
113
  alias set_cell_rows cell_rows
113
114
 
114
115
  def expanded_cell_rows
115
- cell_rows.map do |row|
116
+ expand(cell_rows)
117
+ end
118
+
119
+ def expand(cell_rows)
120
+ cell_rows.to_a.map do |row|
116
121
  row.flatten(1)
117
122
  end
118
123
  end
@@ -146,23 +151,39 @@ module Glimmer
146
151
  3
147
152
  end
148
153
  end
149
- @model_handler.NumRows = fiddle_closure_block_caller(4) { cell_rows.count }
154
+ @model_handler.NumRows = fiddle_closure_block_caller(4) do
155
+ # Note: there is a double-delete bug in Windows when performing table_model_row_deleted, which requires pre-adding and extra empty row
156
+ cell_rows.count + (OS.windows? ? 1 : 0)
157
+ end
150
158
  @model_handler.CellValue = fiddle_closure_block_caller(1, [1, 1, 4, 4]) do |_, _, row, column|
151
159
  the_cell_rows = expanded_cell_rows
152
160
  case @columns[column]
153
161
  when Column::TextColumnProxy, Column::ButtonColumnProxy, Column::TextColorColumnProxy, :text
154
162
  ::LibUI.new_table_value_string((expanded_cell_rows[row] && expanded_cell_rows[row][column]).to_s)
155
163
  when Column::ImageColumnProxy, Column::ImageTextColumnProxy, Column::ImageTextColorColumnProxy
156
- ::LibUI.new_table_value_image((expanded_cell_rows[row] && (expanded_cell_rows[row][column].respond_to?(:libui) ? expanded_cell_rows[row][column].libui : expanded_cell_rows[row][column])))
164
+ if OS.windows? && row == cell_rows.count
165
+ ::LibUI.new_table_value_image((expanded_cell_rows[row - 1] && (expanded_cell_rows[row - 1][column].respond_to?(:libui) ? expanded_cell_rows[row - 1][column].libui : expanded_cell_rows[row - 1][column])))
166
+ else
167
+ ::LibUI.new_table_value_image((expanded_cell_rows[row] && (expanded_cell_rows[row][column].respond_to?(:libui) ? expanded_cell_rows[row][column].libui : expanded_cell_rows[row][column])))
168
+ end
157
169
  when Column::CheckboxColumnProxy, Column::CheckboxTextColumnProxy, Column::CheckboxTextColorColumnProxy
158
- ::LibUI.new_table_value_int((expanded_cell_rows[row] && (expanded_cell_rows[row][column] == 1 || expanded_cell_rows[row][column].to_s.strip.downcase == 'true' ? 1 : 0)))
170
+ ::LibUI.new_table_value_int(((expanded_cell_rows[row] && (expanded_cell_rows[row][column] == 1 || expanded_cell_rows[row][column].to_s.strip.downcase == 'true' ? 1 : 0))) || 0)
159
171
  when Column::ProgressBarColumnProxy
160
- ::LibUI.new_table_value_int((expanded_cell_rows[row] && (expanded_cell_rows[row][column].to_i)))
172
+ value = (expanded_cell_rows[row] && expanded_cell_rows[row][column]).to_i
173
+ expanded_last_last_cell_rows = expand(@last_last_cell_rows)
174
+ old_value = (expanded_last_last_cell_rows[row] && expanded_last_last_cell_rows[row][column]).to_i
175
+ if OS.windows? && old_value == -1 && value >= 0
176
+ Glimmer::Config.logger.error('Switching a progress bar value from -1 to a positive value is not supported on Windows')
177
+ cell_rows[row][column] = -1
178
+ ::LibUI.new_table_value_int(old_value)
179
+ else
180
+ ::LibUI.new_table_value_int((expanded_cell_rows[row] && expanded_cell_rows[row][column]).to_i)
181
+ end
161
182
  when Column::BackgroundColorColumnProxy
162
- background_color = Glimmer::LibUI.interpret_color(expanded_cell_rows[row] && expanded_cell_rows[row][column])
183
+ background_color = Glimmer::LibUI.interpret_color(expanded_cell_rows[row] && expanded_cell_rows[row][column]) || {r: 255, g: 255, b: 255}
163
184
  ::LibUI.new_table_value_color(background_color[:r] / 255.0, background_color[:g] / 255.0, background_color[:b] / 255.0, background_color[:a] || 1.0)
164
185
  when :color
165
- color = Glimmer::LibUI.interpret_color(expanded_cell_rows[row] && expanded_cell_rows[row][column])
186
+ color = Glimmer::LibUI.interpret_color(expanded_cell_rows[row] && expanded_cell_rows[row][column]) || {r: 0, g: 0, b: 0}
166
187
  ::LibUI.new_table_value_color(color[:r] / 255.0, color[:g] / 255.0, color[:b] / 255.0, color[:a] || 1.0)
167
188
  end
168
189
  end
@@ -182,7 +203,6 @@ module Glimmer
182
203
  @cell_rows[row] ||= []
183
204
  @cell_rows[row][column] = ::LibUI.table_value_int(val).to_i == 1
184
205
  end
185
- on_changed.each {|listener| listener.call(row, :changed, @cell_rows[row])}
186
206
  on_edited.each {|listener| listener.call(row, @cell_rows[row])}
187
207
  end
188
208