glimmer-dsl-libui 0.4.9 → 0.4.13
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 +1330 -487
- 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/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/column/background_color_column_proxy.rb +4 -0
- data/lib/glimmer/libui/control_proxy/image_proxy.rb +16 -0
- 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 +8 -3
- 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/snake2.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'glimmer-dsl-libui'
|
2
|
+
|
3
|
+
require_relative 'snake/presenter/grid'
|
4
|
+
|
5
|
+
class Snake
|
6
|
+
include Glimmer
|
7
|
+
|
8
|
+
CELL_SIZE = 15
|
9
|
+
SNAKE_MOVE_DELAY = 0.1
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@game = Model::Game.new
|
13
|
+
@grid = Presenter::Grid.new(@game)
|
14
|
+
@game.start
|
15
|
+
@keypress_queue = []
|
16
|
+
create_gui
|
17
|
+
register_observers
|
18
|
+
end
|
19
|
+
|
20
|
+
def launch
|
21
|
+
@main_window.show
|
22
|
+
end
|
23
|
+
|
24
|
+
def register_observers
|
25
|
+
@game.height.times do |row|
|
26
|
+
@game.width.times do |column|
|
27
|
+
observe(@grid.cells[row][column], :color) do |new_color|
|
28
|
+
@cell_grid[row][column].fill = new_color
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
observe(@game, :over) do |game_over|
|
34
|
+
Glimmer::LibUI.queue_main do
|
35
|
+
if game_over
|
36
|
+
msg_box('Game Over!', "Score: #{@game.score} | High Score: #{@game.high_score}")
|
37
|
+
@game.start
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Glimmer::LibUI.timer(SNAKE_MOVE_DELAY) do
|
43
|
+
unless @game.over?
|
44
|
+
process_queued_keypress
|
45
|
+
@game.snake.move
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def process_queued_keypress
|
51
|
+
# 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)
|
52
|
+
key = @keypress_queue.shift
|
53
|
+
case [@game.snake.head.orientation, key]
|
54
|
+
in [:north, :right] | [:east, :down] | [:south, :left] | [:west, :up]
|
55
|
+
@game.snake.turn_right
|
56
|
+
in [:north, :left] | [:west, :down] | [:south, :right] | [:east, :up]
|
57
|
+
@game.snake.turn_left
|
58
|
+
else
|
59
|
+
# No Op
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_gui
|
64
|
+
@cell_grid = []
|
65
|
+
@main_window = window {
|
66
|
+
# data-bind window title to game score, converting it to a title string on read from the model
|
67
|
+
title <= [@game, :score, on_read: -> (score) {"Snake (Score: #{@game.score})"}]
|
68
|
+
content_size @game.width * CELL_SIZE, @game.height * CELL_SIZE
|
69
|
+
resizable false
|
70
|
+
|
71
|
+
vertical_box {
|
72
|
+
padded false
|
73
|
+
|
74
|
+
@game.height.times do |row|
|
75
|
+
@cell_grid << []
|
76
|
+
horizontal_box {
|
77
|
+
padded false
|
78
|
+
|
79
|
+
@game.width.times do |column|
|
80
|
+
area {
|
81
|
+
@cell_grid.last << square(0, 0, CELL_SIZE) {
|
82
|
+
fill Presenter::Cell::COLOR_CLEAR
|
83
|
+
}
|
84
|
+
|
85
|
+
on_key_up do |area_key_event|
|
86
|
+
@keypress_queue << area_key_event[:ext_key]
|
87
|
+
end
|
88
|
+
}
|
89
|
+
end
|
90
|
+
}
|
91
|
+
end
|
92
|
+
}
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
Snake.new.launch
|
data/examples/tic_tac_toe.rb
CHANGED
@@ -41,6 +41,7 @@ class TicTacToe
|
|
41
41
|
text(23, 19) {
|
42
42
|
string {
|
43
43
|
font family: 'Arial', size: OS.mac? ? 20 : 16
|
44
|
+
# data-bind string property of area text attributed string to tic tac toe board cell sign
|
44
45
|
string <= [@tic_tac_toe_board[row + 1, column + 1], :sign] # board model is 1-based
|
45
46
|
}
|
46
47
|
}
|