glimmer-dsl-libui 0.2.8 → 0.2.12

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.8
1
+ 0.2.12
@@ -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,24 @@ 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('Area Gallery') {
59
+ font family: 'Times', size: 14
60
+ color :black
61
+ }
54
62
  }
55
63
 
56
64
  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,24 @@ 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('Area Gallery') {
60
+ font family: 'Times', size: 14
61
+ color :black
62
+ }
55
63
  }
56
64
  end
57
65
 
@@ -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|
@@ -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
@@ -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
  }
@@ -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
@@ -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
  }
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
  }
@@ -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
@@ -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
@@ -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
@@ -83,7 +83,7 @@ module Glimmer
83
83
  else
84
84
  @cell_rows = rows
85
85
  @cell_rows.tap do
86
- @last_cell_rows = @cell_rows.clone
86
+ @last_cell_rows = array_deep_clone(@cell_rows)
87
87
  Glimmer::DataBinding::Observer.proc do
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|
@@ -103,8 +103,8 @@ module Glimmer
103
103
  end
104
104
  end
105
105
  end
106
- @last_cell_rows = @cell_rows.clone
107
- end.observe(self, :cell_rows)
106
+ @last_cell_rows = array_deep_clone(@cell_rows)
107
+ end.observe(self, :cell_rows, recursive: true)
108
108
  end
109
109
  end
110
110
  end
@@ -205,6 +205,16 @@ module Glimmer
205
205
  @next_column_index ||= -1
206
206
  @next_column_index += 1
207
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
208
218
  end
209
219
  end
210
220
  end
data/lib/glimmer/libui.rb CHANGED
@@ -44,8 +44,8 @@ module Glimmer
44
44
  value = value[0...-1]
45
45
  end
46
46
  value = value.first if value.is_a?(Array) && value.size == 1
47
- value = value.to_s if value.is_a?(Symbol)
48
47
  value = value[:color] if value.is_a?(Hash) && value[:color]
48
+ value = value.to_s if value.is_a?(Symbol)
49
49
  result = if value.is_a?(Array)
50
50
  old_value = value
51
51
  value = {