glimmer-dsl-libui 0.2.7 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.7
1
+ 0.2.11
@@ -7,14 +7,15 @@ window('Area Gallery', 400, 400) {
7
7
  path { # declarative stable path
8
8
  square(0, 0, 100)
9
9
  square(100, 100, 400)
10
-
10
+
11
11
  fill r: 102, g: 102, b: 204
12
12
  }
13
13
  path { # declarative stable path
14
14
  rectangle(0, 100, 100, 400)
15
15
  rectangle(100, 0, 400, 100)
16
-
17
- fill r: 204, g: 102, b: 204
16
+
17
+ # linear gradient (has x0, y0, x1, y1, and stops)
18
+ fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
18
19
  }
19
20
  path { # declarative stable path
20
21
  figure(100, 100) {
@@ -40,17 +41,26 @@ window('Area Gallery', 400, 400) {
40
41
  fill r: 202, g: 102, b: 204, a: 0.5
41
42
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
42
43
  }
44
+ path { # declarative stable path
45
+ arc(400, 220, 180, 90, 90, false)
46
+
47
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
48
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
49
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
50
+ }
43
51
  path { # declarative stable path
44
52
  circle(200, 200, 90)
45
53
 
46
54
  fill r: 202, g: 102, b: 204, a: 0.5
47
55
  stroke r: 0, g: 0, b: 0, thickness: 2
48
56
  }
49
- path { # declarative stable path
50
- arc(400, 220, 180, 90, 90, false)
51
-
52
- fill r: 204, g: 102, b: 204, a: 0.5
53
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
57
+ text(160, 40, 100) { # x, y, width
58
+ string {
59
+ font family: 'Times', size: 14
60
+ color :black
61
+
62
+ 'Area Gallery'
63
+ }
54
64
  }
55
65
 
56
66
  on_mouse_event do |area_mouse_event|
@@ -32,7 +32,8 @@ window('Area Gallery', 400, 400) {
32
32
  height 100
33
33
  }
34
34
 
35
- fill r: 204, g: 102, b: 204
35
+ # linear gradient (has x0, y0, x1, y1, and stops)
36
+ fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
36
37
  }
37
38
  path { # declarative stable path
38
39
  figure {
@@ -94,16 +95,6 @@ window('Area Gallery', 400, 400) {
94
95
  fill r: 202, g: 102, b: 204, a: 0.5
95
96
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
96
97
  }
97
- path { # declarative stable path
98
- circle {
99
- x_center 200
100
- y_center 200
101
- radius 90
102
- }
103
-
104
- fill r: 202, g: 102, b: 204, a: 0.5
105
- stroke r: 0, g: 0, b: 0, thickness: 2
106
- }
107
98
  path { # declarative stable path
108
99
  arc {
109
100
  x_center 400
@@ -114,9 +105,32 @@ window('Area Gallery', 400, 400) {
114
105
  is_negative false
115
106
  }
116
107
 
117
- fill r: 204, g: 102, b: 204, a: 0.5
108
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
109
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
118
110
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
119
111
  }
112
+ path { # declarative stable path
113
+ circle {
114
+ x_center 200
115
+ y_center 200
116
+ radius 90
117
+ }
118
+
119
+ fill r: 202, g: 102, b: 204, a: 0.5
120
+ stroke r: 0, g: 0, b: 0, thickness: 2
121
+ }
122
+ text {
123
+ x 160
124
+ y 40
125
+ width 100
126
+
127
+ string {
128
+ font family: 'Times', size: 14
129
+ color :black
130
+
131
+ 'Area Gallery'
132
+ }
133
+ }
120
134
 
121
135
  on_mouse_event do |area_mouse_event|
122
136
  p area_mouse_event
@@ -15,7 +15,8 @@ window('Area Gallery', 400, 400) {
15
15
  rectangle(0, 100, 100, 400)
16
16
  rectangle(100, 0, 400, 100)
17
17
 
18
- fill r: 204, g: 102, b: 204
18
+ # linear gradient (has x0, y0, x1, y1, and stops)
19
+ fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
19
20
  }
20
21
  path { # a dynamic path is added semi-declaratively inside on_draw block
21
22
  figure(100, 100) {
@@ -41,17 +42,26 @@ window('Area Gallery', 400, 400) {
41
42
  fill r: 202, g: 102, b: 204, a: 0.5
42
43
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
43
44
  }
45
+ path { # a dynamic path is added semi-declaratively inside on_draw block
46
+ arc(400, 220, 180, 90, 90, false)
47
+
48
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
49
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
50
+ stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
51
+ }
44
52
  path { # a dynamic path is added semi-declaratively inside on_draw block
45
53
  circle(200, 200, 90)
46
54
 
47
55
  fill r: 202, g: 102, b: 204, a: 0.5
48
56
  stroke r: 0, g: 0, b: 0, thickness: 2
49
57
  }
50
- path { # a dynamic path is added semi-declaratively inside on_draw block
51
- arc(400, 220, 180, 90, 90, false)
52
-
53
- fill r: 204, g: 102, b: 204, a: 0.5
54
- stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
58
+ text(160, 40, 100) { # x, y, width
59
+ string {
60
+ font family: 'Times', size: 14
61
+ color :black
62
+
63
+ 'Area Gallery'
64
+ }
55
65
  }
56
66
  end
57
67
 
@@ -33,7 +33,8 @@ window('Area Gallery', 400, 400) {
33
33
  height 100
34
34
  }
35
35
 
36
- fill r: 204, g: 102, b: 204
36
+ # linear gradient (has x0, y0, x1, y1, and stops)
37
+ fill x0: 10, y0: 10, x1: 350, y1: 350, stops: [{pos: 0.25, r: 204, g: 102, b: 204}, {pos: 0.75, r: 102, g: 102, b: 204}]
37
38
  }
38
39
  path { # a dynamic path is added semi-declaratively inside on_draw block
39
40
  figure {
@@ -95,16 +96,6 @@ window('Area Gallery', 400, 400) {
95
96
  fill r: 202, g: 102, b: 204, a: 0.5
96
97
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
97
98
  }
98
- path { # a dynamic path is added semi-declaratively inside on_draw block
99
- circle {
100
- x_center 200
101
- y_center 200
102
- radius 90
103
- }
104
-
105
- fill r: 202, g: 102, b: 204, a: 0.5
106
- stroke r: 0, g: 0, b: 0, thickness: 2
107
- }
108
99
  path { # a dynamic path is added semi-declaratively inside on_draw block
109
100
  arc {
110
101
  x_center 400
@@ -115,9 +106,32 @@ window('Area Gallery', 400, 400) {
115
106
  is_negative false
116
107
  }
117
108
 
118
- fill r: 204, g: 102, b: 204, a: 0.5
109
+ # radial gradient (has an outer_radius in addition to x0, y0, x1, y1, and stops)
110
+ fill outer_radius: 90, x0: 0, y0: 0, x1: 500, y1: 500, stops: [{pos: 0.25, r: 102, g: 102, b: 204, a: 0.5}, {pos: 0.75, r: 204, g: 102, b: 204}]
119
111
  stroke r: 0, g: 0, b: 0, thickness: 2, dashes: [50, 10, 10, 10], dash_phase: -50.0
120
112
  }
113
+ path { # a dynamic path is added semi-declaratively inside on_draw block
114
+ circle {
115
+ x_center 200
116
+ y_center 200
117
+ radius 90
118
+ }
119
+
120
+ fill r: 202, g: 102, b: 204, a: 0.5
121
+ stroke r: 0, g: 0, b: 0, thickness: 2
122
+ }
123
+ text {
124
+ x 160
125
+ y 40
126
+ width 100
127
+
128
+ string {
129
+ font family: 'Times', size: 14
130
+ color :black
131
+
132
+ 'Area Gallery'
133
+ }
134
+ }
121
135
  end
122
136
 
123
137
  on_mouse_event do |area_mouse_event|
@@ -24,6 +24,11 @@ window('Animal sounds', 300, 200) {
24
24
  }
25
25
 
26
26
  cell_rows data # implicit data-binding
27
+
28
+ on_changed do |row, type, row_data|
29
+ puts "Row #{row} #{type}: #{row_data}"
30
+ $stdout.flush
31
+ end
27
32
  }
28
33
  }
29
34
  }.show
@@ -26,7 +26,7 @@ window('Task Progress', 300, 200) {
26
26
 
27
27
  on_clicked do
28
28
  data.each_with_index do |row_data, row|
29
- data[row] = [row_data[0], 100] # automatically updates table due to implicit data-binding
29
+ data[row][1] = 100 # automatically updates table due to implicit data-binding
30
30
  end
31
31
  end
32
32
  }
@@ -6,6 +6,8 @@ include Glimmer
6
6
 
7
7
  window('color button', 230) {
8
8
  color_button { |cb|
9
+ color :blue
10
+
9
11
  on_changed do
10
12
  rgba = cb.color
11
13
  p rgba
@@ -69,7 +69,7 @@ class CustomDrawText
69
69
  }
70
70
 
71
71
  area {
72
- text { # default arguments for x, y, and width are (0, 0, area_draw_params[:area_width])
72
+ text { # default arguments for x, y, and width are (0, 0, area_draw_params[:area_width] - 2*x)
73
73
  # align :left # default alignment
74
74
 
75
75
  @string = string {
@@ -76,7 +76,7 @@ class CustomDrawText
76
76
 
77
77
  @area = area {
78
78
  on_draw do |area_draw_params|
79
- text { # default arguments for x, y, and width are (0, 0, area_draw_params[:area_width])
79
+ text { # default arguments for x, y, and width are (0, 0, area_draw_params[:area_width] - 2*x)
80
80
  # align :left # default alignment
81
81
 
82
82
  string {
@@ -20,6 +20,16 @@ window('Editable animal sounds', 300, 200) {
20
20
 
21
21
  cell_rows data
22
22
  editable true
23
+
24
+ on_changed do |row, type, row_data| # fires on all changes (even ones happening through data array)
25
+ puts "Row #{row} #{type}: #{row_data}"
26
+ $stdout.flush
27
+ end
28
+
29
+ on_edited do |row, row_data| # only fires on direct table editing
30
+ puts "Row #{row} edited: #{row_data}"
31
+ $stdout.flush
32
+ end
23
33
  }
24
34
  }
25
35
 
data/examples/form.rb CHANGED
@@ -16,11 +16,21 @@ window('Form') {
16
16
  @last_name_entry = entry {
17
17
  label 'Last Name' # label property is available when control is nested under form
18
18
  }
19
+
20
+ @phone_entry = entry {
21
+ label 'Phone' # label property is available when control is nested under form
22
+ }
23
+
24
+ @email_entry = entry {
25
+ label 'Email' # label property is available when control is nested under form
26
+ }
19
27
  }
20
28
 
21
- button('Display Name') {
29
+ button('Display Info') {
30
+ stretchy false
31
+
22
32
  on_clicked do
23
- msg_box('Name', "#{@first_name_entry.text} #{@last_name_entry.text}")
33
+ msg_box('Info', "#{@first_name_entry.text} #{@last_name_entry.text} has phone #{@phone_entry.text} and email #{@email_entry.text}")
24
34
  end
25
35
  }
26
36
  }
@@ -82,6 +82,10 @@ window('Contacts', 600, 600) { |w|
82
82
  text_column('State')
83
83
 
84
84
  cell_rows data # implicit data-binding
85
+
86
+ on_changed do |row, type, row_data|
87
+ puts "Row #{row} #{type}: #{row_data}"
88
+ end
85
89
  }
86
90
  }
87
91
  }.show
@@ -1,7 +1,6 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'glimmer-dsl-libui'
4
2
  require 'facets'
3
+ require 'fileutils'
5
4
 
6
5
  class MetaExample
7
6
  include Glimmer
@@ -42,6 +41,18 @@ class MetaExample
42
41
  examples[@selected_example_index]
43
42
  end
44
43
 
44
+ def run_example(example)
45
+ command = "ruby -r #{glimmer_dsl_libui_file} #{example} 2>&1"
46
+ result = ''
47
+ IO.popen(command) do |f|
48
+ f.each_line do |line|
49
+ result << line
50
+ puts line
51
+ end
52
+ end
53
+ msg_box('Error Running Example', result) if result.downcase.include?('error')
54
+ end
55
+
45
56
  def launch
46
57
  window('Meta-Example', 700, 500) {
47
58
  margined true
@@ -50,16 +61,16 @@ class MetaExample
50
61
  vertical_box {
51
62
  stretchy false
52
63
 
53
- @rbs = radio_buttons {
64
+ @example_radio_buttons = radio_buttons {
54
65
  stretchy false
55
66
  items examples_with_versions
56
67
  selected @selected_example_index
57
68
 
58
69
  on_selected do
59
- @selected_example_index = @rbs.selected
70
+ @selected_example_index = @example_radio_buttons.selected
60
71
  example = selected_example
61
- @nwme.text = File.read(file_path_for(example))
62
- @sb.value = 1
72
+ @code_entry.text = File.read(file_path_for(example))
73
+ @version_spinbox.value = 1
63
74
  end
64
75
  }
65
76
 
@@ -68,17 +79,17 @@ class MetaExample
68
79
  stretchy false
69
80
  }
70
81
 
71
- @sb = spinbox(1, 100) {
82
+ @version_spinbox = spinbox(1, 100) {
72
83
  value 1
73
84
 
74
85
  on_changed do
75
86
  example = selected_example
76
- if @sb.value > version_count_for(example)
77
- @sb.value -= 1
87
+ if @version_spinbox.value > version_count_for(example)
88
+ @version_spinbox.value -= 1
78
89
  else
79
- version_number = @sb.value == 1 ? '' : @sb.value
90
+ version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
80
91
  example = "#{selected_example}#{version_number}"
81
- @nwme.text = File.read(file_path_for(example))
92
+ @code_entry.text = File.read(file_path_for(example))
82
93
  end
83
94
  end
84
95
  }
@@ -90,25 +101,29 @@ class MetaExample
90
101
  button('Launch') {
91
102
  on_clicked do
92
103
  begin
93
- meta_example_file = File.join(Dir.home, '.meta_example.rb')
94
- File.write(meta_example_file, @nwme.text)
95
- result = `ruby -r #{glimmer_dsl_libui_file} #{meta_example_file} 2>&1`
96
- msg_box('Error Running Example', result) if result.include?('error')
104
+ parent_dir = File.join(Dir.home, '.glimmer-dsl-libui', 'examples')
105
+ FileUtils.mkdir_p(parent_dir)
106
+ example_file = File.join(parent_dir, "#{selected_example.underscore}.rb")
107
+ File.write(example_file, @code_entry.text)
108
+ FileUtils.cp_r(File.expand_path('../icons', __dir__), File.dirname(parent_dir))
109
+ FileUtils.cp_r(File.expand_path('../sounds', __dir__), File.dirname(parent_dir))
110
+ run_example(example_file)
97
111
  rescue => e
112
+ puts e.full_message
98
113
  puts 'Unable to write code changes! Running original example...'
99
- system "ruby -r #{glimmer_dsl_libui_file} #{file_path_for(selected_example)}"
114
+ run_example(file_path_for(selected_example))
100
115
  end
101
116
  end
102
117
  }
103
118
  button('Reset') {
104
119
  on_clicked do
105
- @nwme.text = File.read(file_path_for(selected_example))
120
+ @code_entry.text = File.read(file_path_for(selected_example))
106
121
  end
107
122
  }
108
123
  }
109
124
  }
110
125
 
111
- @nwme = non_wrapping_multiline_entry {
126
+ @code_entry = non_wrapping_multiline_entry {
112
127
  text File.read(file_path_for(selected_example))
113
128
  }
114
129
  }
@@ -0,0 +1,97 @@
1
+ require 'glimmer-dsl-libui'
2
+ require 'facets'
3
+
4
+ include Glimmer
5
+
6
+ Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
7
+
8
+ def form_field(model, property)
9
+ property = property.to_s
10
+ entry { |e|
11
+ label property.underscore.split('_').map(&:capitalize).join(' ')
12
+ text model.send(property).to_s
13
+
14
+ on_changed do
15
+ model.send("#{property}=", e.text)
16
+ end
17
+ }
18
+ end
19
+
20
+ def address_form(address)
21
+ form {
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
+ }
28
+ end
29
+
30
+ def label_pair(model, attribute, value)
31
+ name_label = nil
32
+ value_label = nil
33
+ horizontal_box {
34
+ name_label = label(attribute.to_s.underscore.split('_').map(&:capitalize).join(' '))
35
+ value_label = label(value.to_s)
36
+ }
37
+ Glimmer::DataBinding::Observer.proc do
38
+ value_label.text = model.send(attribute)
39
+ end.observe(model, attribute)
40
+ end
41
+
42
+ def address(address)
43
+ vertical_box {
44
+ address.each_pair do |attribute, value|
45
+ label_pair(address, attribute, value)
46
+ end
47
+ }
48
+ end
49
+
50
+ address1 = Address.new('123 Main St', '23923', 'Denver', 'Colorado', '80014')
51
+ address2 = Address.new('2038 Park Ave', '83272', 'Boston', 'Massachusetts', '02101')
52
+
53
+ window('Method-Based Custom Keyword') {
54
+ margined true
55
+
56
+ horizontal_box {
57
+ vertical_box {
58
+ label('Address 1') {
59
+ stretchy false
60
+ }
61
+
62
+ address_form(address1)
63
+
64
+ horizontal_separator {
65
+ stretchy false
66
+ }
67
+
68
+ label('Address 1 (Saved)') {
69
+ stretchy false
70
+ }
71
+
72
+ address(address1)
73
+ }
74
+
75
+ vertical_separator {
76
+ stretchy false
77
+ }
78
+
79
+ vertical_box {
80
+ label('Address 2') {
81
+ stretchy false
82
+ }
83
+
84
+ address_form(address2)
85
+
86
+ horizontal_separator {
87
+ stretchy false
88
+ }
89
+
90
+ label('Address 2 (Saved)') {
91
+ stretchy false
92
+ }
93
+
94
+ address(address2)
95
+ }
96
+ }
97
+ }.show
Binary file
@@ -69,7 +69,6 @@ module Glimmer
69
69
  @fill ||= {}
70
70
  else
71
71
  @fill = Glimmer::LibUI.interpret_color(args)
72
- @fill[:a] = 1.0 if @fill.is_a?(Hash) && @fill[:a].nil?
73
72
  @parent_proxy&.queue_redraw_all
74
73
  end
75
74
  @fill.tap do
@@ -94,7 +93,6 @@ module Glimmer
94
93
  @stroke ||= {}
95
94
  else
96
95
  @stroke = Glimmer::LibUI.interpret_color(args)
97
- @stroke[:a] = 1.0 if @stroke.is_a?(Hash) && @stroke[:a].nil?
98
96
  @parent_proxy&.queue_redraw_all
99
97
  end
100
98
  @stroke.tap do
@@ -149,11 +147,38 @@ module Glimmer
149
147
  end
150
148
 
151
149
  def init_draw_brush(draw_brush, draw_brush_args)
150
+ if draw_brush_args[:r] || draw_brush_args[:g] || draw_brush_args[:b] || draw_brush_args[:a]
151
+ draw_brush_args[:type] ||= :solid
152
+ elsif draw_brush_args[:outer_radius]
153
+ draw_brush_args[:type] ||= :radial_gradient
154
+ else
155
+ draw_brush_args[:type] ||= :linear_gradient
156
+ end
152
157
  draw_brush.Type = Glimmer::LibUI.enum_symbol_to_value(:draw_brush_type, draw_brush_args[:type])
153
- draw_brush.R = (draw_brush_args[:r] || draw_brush_args[:red]).to_f / 255.0
154
- draw_brush.G = (draw_brush_args[:g] || draw_brush_args[:green]).to_f / 255.0
155
- draw_brush.B = (draw_brush_args[:b] || draw_brush_args[:blue]).to_f / 255.0
156
- draw_brush.A = (draw_brush_args[:a] || draw_brush_args[:alpha])
158
+ if draw_brush.Type == 0
159
+ draw_brush.R = (draw_brush_args[:r] || draw_brush_args[:red]).to_f / 255.0
160
+ draw_brush.G = (draw_brush_args[:g] || draw_brush_args[:green]).to_f / 255.0
161
+ draw_brush.B = (draw_brush_args[:b] || draw_brush_args[:blue]).to_f / 255.0
162
+ draw_brush.A = (draw_brush_args[:a] || draw_brush_args[:alpha] || 1.0)
163
+ else
164
+ draw_brush.X0 = draw_brush_args[:x0].to_f
165
+ draw_brush.Y0 = draw_brush_args[:y0].to_f
166
+ draw_brush.X1 = draw_brush_args[:x1].to_f
167
+ draw_brush.Y1 = draw_brush_args[:y1].to_f
168
+ draw_brush.OuterRadius = draw_brush_args[:outer_radius].to_f if draw_brush.Type == 2
169
+ stop_structs = draw_brush_args[:stops].to_a.map do |stop|
170
+ ::LibUI::FFI::DrawBrushGradientStop.malloc.tap do |stop_struct|
171
+ stop_struct.Pos = stop[:pos].to_f
172
+ stop_color = Glimmer::LibUI.interpret_color(stop)
173
+ stop_struct.R = stop_color[:r].to_f / 255.0
174
+ stop_struct.G = stop_color[:g].to_f / 255.0
175
+ stop_struct.B = stop_color[:b].to_f / 255.0
176
+ stop_struct.A = stop_color[:a] || 1.0
177
+ end
178
+ end
179
+ draw_brush.NumStops = stop_structs.count
180
+ draw_brush.Stops = stop_structs.map(&:to_ptr).map(&:to_s).reduce(:+)
181
+ end
157
182
  end
158
183
  end
159
184
  end
@@ -35,6 +35,8 @@ module Glimmer
35
35
  class TableProxy < ControlProxy
36
36
  include Glimmer::FiddleConsumer
37
37
 
38
+ LISTENERS = ['on_changed', 'on_edited']
39
+
38
40
  attr_reader :model_handler, :model, :table_params, :columns
39
41
 
40
42
  def initialize(keyword, parent, args, &block)
@@ -81,22 +83,27 @@ module Glimmer
81
83
  else
82
84
  @cell_rows = rows
83
85
  @cell_rows.tap do
84
- @last_cell_rows = @cell_rows.clone
86
+ @last_cell_rows = array_deep_clone(@cell_rows)
85
87
  Glimmer::DataBinding::Observer.proc do
86
88
  if @cell_rows.size < @last_cell_rows.size && @last_cell_rows.include_all?(*@cell_rows)
87
89
  @last_cell_rows.array_diff_indexes(@cell_rows).reverse.each do |row|
88
90
  ::LibUI.table_model_row_deleted(model, row)
91
+ on_changed.each {|listener| listener.call(row, :deleted, @last_cell_rows[row])}
89
92
  end
90
93
  elsif @cell_rows.size > @last_cell_rows.size && @cell_rows.include_all?(*@last_cell_rows)
91
94
  @cell_rows.array_diff_indexes(@last_cell_rows).each do |row|
92
95
  ::LibUI.table_model_row_inserted(model, row)
96
+ on_changed.each {|listener| listener.call(row, :inserted, @cell_rows[row])}
93
97
  end
94
98
  else
95
99
  @cell_rows.each_with_index do |new_row_data, row|
96
- ::LibUI.table_model_row_changed(model, row) if new_row_data != @last_cell_rows[row]
100
+ if new_row_data != @last_cell_rows[row]
101
+ ::LibUI.table_model_row_changed(model, row)
102
+ on_changed.each {|listener| listener.call(row, :changed, @cell_rows[row])}
103
+ end
97
104
  end
98
105
  end
99
- @last_cell_rows = @cell_rows.clone
106
+ @last_cell_rows = array_deep_clone(@cell_rows)
100
107
  end.observe(self, :cell_rows)
101
108
  end
102
109
  end
@@ -175,6 +182,8 @@ module Glimmer
175
182
  @cell_rows[row] ||= []
176
183
  @cell_rows[row][column] = ::LibUI.table_value_int(val).to_i == 1
177
184
  end
185
+ on_changed.each {|listener| listener.call(row, :changed, @cell_rows[row])}
186
+ on_edited.each {|listener| listener.call(row, @cell_rows[row])}
178
187
  end
179
188
 
180
189
  @model = ::LibUI.new_table_model(@model_handler)
@@ -196,6 +205,16 @@ module Glimmer
196
205
  @next_column_index ||= -1
197
206
  @next_column_index += 1
198
207
  end
208
+
209
+ def array_deep_clone(array_or_object)
210
+ if array_or_object.is_a?(Array)
211
+ array_or_object.map do |element|
212
+ array_deep_clone(element)
213
+ end
214
+ else
215
+ array_or_object.clone
216
+ end
217
+ end
199
218
  end
200
219
  end
201
220
  end
@@ -90,7 +90,7 @@ module Glimmer
90
90
 
91
91
  def width(value = nil)
92
92
  if value.nil?
93
- @width ||= args[2] || (AreaProxy.current_area_draw_params && AreaProxy.current_area_draw_params[:area_width])
93
+ @width ||= args[2] || (AreaProxy.current_area_draw_params && (AreaProxy.current_area_draw_params[:area_width] - 2*x))
94
94
  else
95
95
  @width = value
96
96
  redraw