glimmer-dsl-libui 0.4.8 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +1361 -461
- data/VERSION +1 -1
- data/examples/basic_table_button.rb +54 -30
- data/examples/basic_table_button2.rb +34 -0
- data/examples/basic_table_color.rb +104 -26
- data/examples/basic_table_color2.rb +2 -14
- data/examples/basic_table_color3.rb +37 -0
- data/examples/basic_table_image.rb +1 -1
- data/examples/basic_table_image2.rb +2 -14
- data/examples/basic_table_image3.rb +44 -0
- data/examples/basic_table_image_text.rb +1 -2
- data/examples/basic_table_image_text2.rb +2 -13
- data/examples/basic_table_image_text3.rb +44 -0
- data/examples/cpu_percentage.rb +36 -0
- data/examples/editable_table.rb +1 -1
- data/examples/form_table.rb +21 -17
- data/examples/form_table2.rb +104 -85
- data/examples/form_table3.rb +113 -0
- data/examples/form_table4.rb +110 -0
- data/examples/form_table5.rb +94 -0
- data/examples/meta_example.rb +6 -4
- data/examples/snake.rb +19 -10
- data/examples/snake2.rb +97 -0
- data/examples/tic_tac_toe.rb +1 -0
- data/examples/tic_tac_toe2.rb +84 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/control_expression.rb +2 -1
- data/lib/glimmer/dsl/libui/shape_expression.rb +2 -2
- data/lib/glimmer/dsl/libui/string_expression.rb +2 -1
- data/lib/glimmer/libui/attributed_string.rb +3 -2
- data/lib/glimmer/libui/control_proxy/checkbox_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/color_button_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/column/background_color_column_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/combobox_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/date_time_picker_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/editable_combobox_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/entry_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/font_button_proxy.rb +5 -1
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/check_menu_item_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/radio_menu_item_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/multiline_entry_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/radio_buttons_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/slider_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/spinbox_proxy.rb +1 -2
- data/lib/glimmer/libui/control_proxy/table_proxy.rb +95 -29
- data/lib/glimmer/libui/control_proxy.rb +4 -2
- data/lib/glimmer/libui/data_bindable.rb +34 -4
- data/lib/glimmer/libui/shape.rb +3 -2
- data/lib/glimmer/libui.rb +2 -2
- data/lib/glimmer-dsl-libui.rb +1 -0
- metadata +12 -2
data/examples/form_table2.rb
CHANGED
@@ -1,93 +1,112 @@
|
|
1
1
|
require 'glimmer-dsl-libui'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
data = [
|
6
|
-
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
|
7
|
-
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
|
8
|
-
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
|
9
|
-
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
|
10
|
-
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
|
11
|
-
]
|
12
|
-
|
13
|
-
window('Contacts', 600, 600) { |w|
|
14
|
-
margined true
|
3
|
+
class FormTable
|
4
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state)
|
15
5
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
label 'City'
|
34
|
-
}
|
35
|
-
|
36
|
-
@state_entry = entry {
|
37
|
-
label 'State'
|
38
|
-
}
|
39
|
-
}
|
40
|
-
|
41
|
-
button('Save Contact') {
|
42
|
-
stretchy false
|
43
|
-
|
44
|
-
on_clicked do
|
45
|
-
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
46
|
-
if new_row.include?('')
|
47
|
-
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
48
|
-
else
|
49
|
-
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
50
|
-
@unfiltered_data = data.dup
|
51
|
-
@name_entry.text = ''
|
52
|
-
@email_entry.text = ''
|
53
|
-
@phone_entry.text = ''
|
54
|
-
@city_entry.text = ''
|
55
|
-
@state_entry.text = ''
|
56
|
-
end
|
57
|
-
end
|
58
|
-
}
|
59
|
-
|
60
|
-
search_entry { |se|
|
61
|
-
stretchy false
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@contacts = [
|
12
|
+
Contact.new('Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'),
|
13
|
+
Contact.new('Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'),
|
14
|
+
Contact.new('Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'),
|
15
|
+
Contact.new('Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'),
|
16
|
+
Contact.new('Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'),
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def launch
|
21
|
+
window('Contacts', 600, 600) { |w|
|
22
|
+
margined true
|
62
23
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
24
|
+
vertical_box {
|
25
|
+
form {
|
26
|
+
stretchy false
|
27
|
+
|
28
|
+
entry {
|
29
|
+
label 'Name'
|
30
|
+
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
31
|
+
}
|
32
|
+
|
33
|
+
entry {
|
34
|
+
label 'Email'
|
35
|
+
text <=> [self, :email]
|
36
|
+
}
|
37
|
+
|
38
|
+
entry {
|
39
|
+
label 'Phone'
|
40
|
+
text <=> [self, :phone]
|
41
|
+
}
|
42
|
+
|
43
|
+
entry {
|
44
|
+
label 'City'
|
45
|
+
text <=> [self, :city]
|
46
|
+
}
|
47
|
+
|
48
|
+
entry {
|
49
|
+
label 'State'
|
50
|
+
text <=> [self, :state]
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
button('Save Contact') {
|
55
|
+
stretchy false
|
56
|
+
|
57
|
+
on_clicked do
|
58
|
+
new_row = [name, email, phone, city, state]
|
59
|
+
if new_row.include?('')
|
60
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
61
|
+
else
|
62
|
+
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
63
|
+
@unfiltered_contacts = @contacts.dup
|
64
|
+
self.name = '' # automatically clears name entry through explicit data-binding
|
65
|
+
self.email = ''
|
66
|
+
self.phone = ''
|
67
|
+
self.city = ''
|
68
|
+
self.state = ''
|
73
69
|
end
|
74
70
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
}
|
72
|
+
|
73
|
+
search_entry {
|
74
|
+
stretchy false
|
75
|
+
# bidirectional data-binding of text to self.filter_value with after_write option
|
76
|
+
text <=> [self, :filter_value,
|
77
|
+
after_write: ->(filter_value) { # execute after write to self.filter_value
|
78
|
+
@unfiltered_contacts ||= @contacts.dup
|
79
|
+
# Unfilter first to remove any previous filters
|
80
|
+
self.contacts = @unfiltered_contacts.dup # affects table indirectly through explicit data-binding
|
81
|
+
# Now, apply filter if entered
|
82
|
+
unless filter_value.empty?
|
83
|
+
self.contacts = @contacts.filter do |contact| # affects table indirectly through explicit data-binding
|
84
|
+
contact.members.any? do |attribute|
|
85
|
+
contact[attribute].to_s.downcase.include?(filter_value.downcase)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
}
|
90
|
+
]
|
91
|
+
}
|
92
|
+
|
93
|
+
table {
|
94
|
+
text_column('Name')
|
95
|
+
text_column('Email')
|
96
|
+
text_column('Phone')
|
97
|
+
text_column('City')
|
98
|
+
text_column('State/Province')
|
78
99
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
100
|
+
editable true
|
101
|
+
cell_rows <=> [self, :contacts, column_attributes: {'State/Province' => :state}] # explicit data-binding to Model Array with column_attributes mapping for a specific column
|
102
|
+
|
103
|
+
on_changed do |row, type, row_data|
|
104
|
+
puts "Row #{row} #{type}: #{row_data}"
|
105
|
+
end
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}.show
|
109
|
+
end
|
110
|
+
end
|
85
111
|
|
86
|
-
|
87
|
-
|
88
|
-
on_changed do |row, type, row_data|
|
89
|
-
puts "Row #{row} #{type}: #{row_data}"
|
90
|
-
end
|
91
|
-
}
|
92
|
-
}
|
93
|
-
}.show
|
112
|
+
FormTable.new.launch
|
@@ -0,0 +1,113 @@
|
|
1
|
+
|
2
|
+
require 'glimmer-dsl-libui'
|
3
|
+
|
4
|
+
class FormTable
|
5
|
+
Contact = Struct.new(:full_name, :email_address, :phone_number, :city_or_town, :state_or_province)
|
6
|
+
|
7
|
+
include Glimmer
|
8
|
+
|
9
|
+
attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@contacts = [
|
13
|
+
Contact.new('Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'),
|
14
|
+
Contact.new('Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'),
|
15
|
+
Contact.new('Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'),
|
16
|
+
Contact.new('Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'),
|
17
|
+
Contact.new('Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'),
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
def launch
|
22
|
+
window('Contacts', 600, 600) { |w|
|
23
|
+
margined true
|
24
|
+
|
25
|
+
vertical_box {
|
26
|
+
form {
|
27
|
+
stretchy false
|
28
|
+
|
29
|
+
entry {
|
30
|
+
label 'Name'
|
31
|
+
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
32
|
+
}
|
33
|
+
|
34
|
+
entry {
|
35
|
+
label 'Email'
|
36
|
+
text <=> [self, :email]
|
37
|
+
}
|
38
|
+
|
39
|
+
entry {
|
40
|
+
label 'Phone'
|
41
|
+
text <=> [self, :phone]
|
42
|
+
}
|
43
|
+
|
44
|
+
entry {
|
45
|
+
label 'City'
|
46
|
+
text <=> [self, :city]
|
47
|
+
}
|
48
|
+
|
49
|
+
entry {
|
50
|
+
label 'State'
|
51
|
+
text <=> [self, :state]
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
button('Save Contact') {
|
56
|
+
stretchy false
|
57
|
+
|
58
|
+
on_clicked do
|
59
|
+
new_row = [name, email, phone, city, state]
|
60
|
+
if new_row.include?('')
|
61
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
62
|
+
else
|
63
|
+
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
64
|
+
@unfiltered_contacts = @contacts.dup
|
65
|
+
self.name = '' # automatically clears name entry through explicit data-binding
|
66
|
+
self.email = ''
|
67
|
+
self.phone = ''
|
68
|
+
self.city = ''
|
69
|
+
self.state = ''
|
70
|
+
end
|
71
|
+
end
|
72
|
+
}
|
73
|
+
|
74
|
+
search_entry {
|
75
|
+
stretchy false
|
76
|
+
# bidirectional data-binding of text to self.filter_value with after_write option
|
77
|
+
text <=> [self, :filter_value,
|
78
|
+
after_write: ->(filter_value) { # execute after write to self.filter_value
|
79
|
+
@unfiltered_contacts ||= @contacts.dup
|
80
|
+
# Unfilter first to remove any previous filters
|
81
|
+
self.contacts = @unfiltered_contacts.dup # affects table indirectly through explicit data-binding
|
82
|
+
# Now, apply filter if entered
|
83
|
+
unless filter_value.empty?
|
84
|
+
self.contacts = @contacts.filter do |contact| # affects table indirectly through explicit data-binding
|
85
|
+
contact.members.any? do |attribute|
|
86
|
+
contact[attribute].to_s.downcase.include?(filter_value.downcase)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
}
|
91
|
+
]
|
92
|
+
}
|
93
|
+
|
94
|
+
table {
|
95
|
+
text_column('Name')
|
96
|
+
text_column('Email')
|
97
|
+
text_column('Phone')
|
98
|
+
text_column('City')
|
99
|
+
text_column('State')
|
100
|
+
|
101
|
+
editable true
|
102
|
+
cell_rows <=> [self, :contacts, column_attributes: [:full_name, :email_address, :phone_number, :city_or_town, :state_or_province]] # explicit data-binding to Model Array with column_attributes mapping for all columns
|
103
|
+
|
104
|
+
on_changed do |row, type, row_data|
|
105
|
+
puts "Row #{row} #{type}: #{row_data}"
|
106
|
+
end
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}.show
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
FormTable.new.launch
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
class FormTable
|
4
|
+
include Glimmer
|
5
|
+
|
6
|
+
attr_accessor :data, :name, :email, :phone, :city, :state, :filter_value
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@data = [
|
10
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'],
|
11
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'],
|
12
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'],
|
13
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'],
|
14
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
def launch
|
19
|
+
window('Contacts', 600, 600) { |w|
|
20
|
+
margined true
|
21
|
+
|
22
|
+
vertical_box {
|
23
|
+
form {
|
24
|
+
stretchy false
|
25
|
+
|
26
|
+
entry {
|
27
|
+
label 'Name'
|
28
|
+
text <=> [self, :name] # bidirectional data-binding between entry text and self.name
|
29
|
+
}
|
30
|
+
|
31
|
+
entry {
|
32
|
+
label 'Email'
|
33
|
+
text <=> [self, :email]
|
34
|
+
}
|
35
|
+
|
36
|
+
entry {
|
37
|
+
label 'Phone'
|
38
|
+
text <=> [self, :phone]
|
39
|
+
}
|
40
|
+
|
41
|
+
entry {
|
42
|
+
label 'City'
|
43
|
+
text <=> [self, :city]
|
44
|
+
}
|
45
|
+
|
46
|
+
entry {
|
47
|
+
label 'State'
|
48
|
+
text <=> [self, :state]
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
button('Save Contact') {
|
53
|
+
stretchy false
|
54
|
+
|
55
|
+
on_clicked do
|
56
|
+
new_row = [name, email, phone, city, state]
|
57
|
+
if new_row.include?('')
|
58
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
59
|
+
else
|
60
|
+
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
61
|
+
@unfiltered_data = data.dup
|
62
|
+
self.name = '' # automatically clears name entry through explicit data-binding
|
63
|
+
self.email = ''
|
64
|
+
self.phone = ''
|
65
|
+
self.city = ''
|
66
|
+
self.state = ''
|
67
|
+
end
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
search_entry {
|
72
|
+
stretchy false
|
73
|
+
# bidirectional data-binding of text to self.filter_value with after_write option
|
74
|
+
text <=> [self, :filter_value,
|
75
|
+
after_write: ->(filter_value) { # execute after write to self.filter_value
|
76
|
+
@unfiltered_data ||= data.dup
|
77
|
+
# Unfilter first to remove any previous filters
|
78
|
+
data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
79
|
+
# Now, apply filter if entered
|
80
|
+
unless filter_value.empty?
|
81
|
+
data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
82
|
+
row_data.any? do |cell|
|
83
|
+
cell.to_s.downcase.include?(filter_value.downcase)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
}
|
88
|
+
]
|
89
|
+
}
|
90
|
+
|
91
|
+
table {
|
92
|
+
text_column('Name')
|
93
|
+
text_column('Email')
|
94
|
+
text_column('Phone')
|
95
|
+
text_column('City')
|
96
|
+
text_column('State')
|
97
|
+
|
98
|
+
editable true
|
99
|
+
cell_rows <=> [self, :data] # explicit data-binding to raw data Array of Arrays
|
100
|
+
|
101
|
+
on_changed do |row, type, row_data|
|
102
|
+
puts "Row #{row} #{type}: #{row_data}"
|
103
|
+
end
|
104
|
+
}
|
105
|
+
}
|
106
|
+
}.show
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
FormTable.new.launch
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
include Glimmer
|
4
|
+
|
5
|
+
data = [
|
6
|
+
['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO'],
|
7
|
+
['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA'],
|
8
|
+
['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL'],
|
9
|
+
['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA'],
|
10
|
+
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
11
|
+
]
|
12
|
+
|
13
|
+
window('Contacts', 600, 600) { |w|
|
14
|
+
margined true
|
15
|
+
|
16
|
+
vertical_box {
|
17
|
+
form {
|
18
|
+
stretchy false
|
19
|
+
|
20
|
+
@name_entry = entry {
|
21
|
+
label 'Name'
|
22
|
+
}
|
23
|
+
|
24
|
+
@email_entry = entry {
|
25
|
+
label 'Email'
|
26
|
+
}
|
27
|
+
|
28
|
+
@phone_entry = entry {
|
29
|
+
label 'Phone'
|
30
|
+
}
|
31
|
+
|
32
|
+
@city_entry = entry {
|
33
|
+
label 'City'
|
34
|
+
}
|
35
|
+
|
36
|
+
@state_entry = entry {
|
37
|
+
label 'State'
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
button('Save Contact') {
|
42
|
+
stretchy false
|
43
|
+
|
44
|
+
on_clicked do
|
45
|
+
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
46
|
+
if new_row.include?('')
|
47
|
+
msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
48
|
+
else
|
49
|
+
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
50
|
+
@unfiltered_data = data.dup
|
51
|
+
@name_entry.text = ''
|
52
|
+
@email_entry.text = ''
|
53
|
+
@phone_entry.text = ''
|
54
|
+
@city_entry.text = ''
|
55
|
+
@state_entry.text = ''
|
56
|
+
end
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
search_entry { |se|
|
61
|
+
stretchy false
|
62
|
+
|
63
|
+
on_changed do
|
64
|
+
filter_value = se.text
|
65
|
+
@unfiltered_data ||= data.dup
|
66
|
+
# Unfilter first to remove any previous filters
|
67
|
+
data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
|
68
|
+
# Now, apply filter if entered
|
69
|
+
unless filter_value.empty?
|
70
|
+
data.filter! do |row_data| # affects table indirectly through implicit data-binding
|
71
|
+
row_data.any? do |cell|
|
72
|
+
cell.to_s.downcase.include?(filter_value.downcase)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
table {
|
80
|
+
text_column('Name')
|
81
|
+
text_column('Email')
|
82
|
+
text_column('Phone')
|
83
|
+
text_column('City')
|
84
|
+
text_column('State')
|
85
|
+
|
86
|
+
editable true
|
87
|
+
cell_rows data # implicit data-binding to raw data Array of Arrays
|
88
|
+
|
89
|
+
on_changed do |row, type, row_data|
|
90
|
+
puts "Row #{row} #{type}: #{row_data}"
|
91
|
+
end
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}.show
|
data/examples/meta_example.rb
CHANGED
@@ -25,11 +25,11 @@ class MetaExample
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def basic_examples
|
28
|
-
examples.select {|example| example.start_with?('Basic') || ADDITIONAL_BASIC_EXAMPLES.include?(example) }
|
28
|
+
examples.select {|example| example.start_with?('Basic') || ADDITIONAL_BASIC_EXAMPLES.include?(example) }.sort
|
29
29
|
end
|
30
30
|
|
31
31
|
def advanced_examples
|
32
|
-
examples - basic_examples
|
32
|
+
(examples - basic_examples).sort
|
33
33
|
end
|
34
34
|
|
35
35
|
def examples_with_versions
|
@@ -69,12 +69,12 @@ class MetaExample
|
|
69
69
|
command = "#{RbConfig.ruby} -r #{glimmer_dsl_libui_file} #{example} 2>&1"
|
70
70
|
result = ''
|
71
71
|
IO.popen(command) do |f|
|
72
|
-
sleep(0.
|
72
|
+
sleep(0.00001) # yield to main thread
|
73
73
|
f.each_line do |line|
|
74
74
|
result << line
|
75
75
|
puts line
|
76
76
|
$stdout.flush # for Windows
|
77
|
-
sleep(0.
|
77
|
+
sleep(0.00001) # yield to main thread
|
78
78
|
end
|
79
79
|
end
|
80
80
|
Glimmer::LibUI.queue_main { msg_box('Error Running Example', result) } if result.downcase.include?('error')
|
@@ -104,6 +104,7 @@ class MetaExample
|
|
104
104
|
example = selected_example
|
105
105
|
self.code_text = File.read(file_path_for(example))
|
106
106
|
@version_spinbox.value = 1
|
107
|
+
@advanced_example_radio_buttons.selected = -1
|
107
108
|
end
|
108
109
|
}
|
109
110
|
|
@@ -124,6 +125,7 @@ class MetaExample
|
|
124
125
|
example = selected_example
|
125
126
|
self.code_text = File.read(file_path_for(example))
|
126
127
|
@version_spinbox.value = 1
|
128
|
+
@basic_example_radio_buttons.selected = -1
|
127
129
|
end
|
128
130
|
}
|
129
131
|
|
data/examples/snake.rb
CHANGED
@@ -12,6 +12,7 @@ class Snake
|
|
12
12
|
@game = Model::Game.new
|
13
13
|
@grid = Presenter::Grid.new(@game)
|
14
14
|
@game.start
|
15
|
+
@keypress_queue = []
|
15
16
|
create_gui
|
16
17
|
register_observers
|
17
18
|
end
|
@@ -31,7 +32,23 @@ class Snake
|
|
31
32
|
end
|
32
33
|
|
33
34
|
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
|
34
|
-
|
35
|
+
unless @game.over?
|
36
|
+
process_queued_keypress
|
37
|
+
@game.snake.move
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_queued_keypress
|
43
|
+
# key press queue ensures one turn per snake move to avoid a double-turn resulting in instant death (due to snake illogically going back against itself)
|
44
|
+
key = @keypress_queue.shift
|
45
|
+
case [@game.snake.head.orientation, key]
|
46
|
+
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
47
|
+
@game.snake.turn_right
|
48
|
+
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
49
|
+
@game.snake.turn_left
|
50
|
+
else
|
51
|
+
# No Op
|
35
52
|
end
|
36
53
|
end
|
37
54
|
|
@@ -56,15 +73,7 @@ class Snake
|
|
56
73
|
}
|
57
74
|
|
58
75
|
on_key_up do |area_key_event|
|
59
|
-
|
60
|
-
case orientation_and_key
|
61
|
-
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
62
|
-
@game.snake.turn_right
|
63
|
-
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
64
|
-
@game.snake.turn_left
|
65
|
-
else
|
66
|
-
# No Op
|
67
|
-
end
|
76
|
+
@keypress_queue << area_key_event[:ext_key]
|
68
77
|
end
|
69
78
|
}
|
70
79
|
end
|