glimmer-dsl-libui 0.4.10 → 0.4.11

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.4.10
1
+ 0.4.11
@@ -1,34 +1,58 @@
1
- # frozen_string_literal: true
2
-
3
1
  require 'glimmer-dsl-libui'
4
2
 
5
- include Glimmer
6
-
7
- data = [
8
- %w[cat meow delete],
9
- %w[dog woof delete],
10
- %w[chicken cock-a-doodle-doo delete],
11
- %w[horse neigh delete],
12
- %w[cow moo delete]
13
- ]
14
-
15
- window('Animal sounds', 400, 200) {
16
- horizontal_box {
17
- table {
18
- text_column('Animal')
19
- text_column('Description')
20
- button_column('Action') {
21
- on_clicked do |row|
22
- data.delete_at(row) # automatically deletes actual table row due to implicit data-binding
23
- end
3
+ class BasicTableButton
4
+ BasicAnimal = Struct.new(:name, :sound)
5
+
6
+ class Animal < BasicAnimal
7
+ def action
8
+ 'delete'
9
+ end
10
+ end
11
+
12
+ include Glimmer
13
+
14
+ attr_accessor :animals
15
+
16
+ def initialize
17
+ @animals = [
18
+ Animal.new('cat', 'meow'),
19
+ Animal.new('dog', 'woof'),
20
+ Animal.new('chicken', 'cock-a-doodle-doo'),
21
+ Animal.new('horse', 'neigh'),
22
+ Animal.new('cow', 'moo'),
23
+ ]
24
+ end
25
+
26
+ def launch
27
+ window('Animal sounds', 400, 200) {
28
+ horizontal_box {
29
+ table {
30
+ text_column('Animal')
31
+ text_column('Description')
32
+ button_column('Action') {
33
+ on_clicked do |row|
34
+ # Option 1: direct data deletion is the simpler solution
35
+ # @animals.delete_at(row) # automatically deletes actual table row due to explicit data-binding
36
+
37
+ # Option 2: cloning only to demonstrate table row deletion upon explicit setting of animals attribute (cloning is not recommended beyond demonstrating this point)
38
+ new_animals = @animals.clone
39
+ new_animals.delete_at(row)
40
+ self.animals = new_animals # automatically loses deleted table row due to explicit data-binding
41
+ end
42
+ }
43
+
44
+
45
+ cell_rows <= [self, :animals, column_attributes: {'Animal' => :name, 'Description' => :sound}]
46
+
47
+ # explicit unidirectional data-binding of table cell_rows to self.animals
48
+ on_changed do |row, type, row_data|
49
+ puts "Row #{row} #{type}: #{row_data}"
50
+ $stdout.flush
51
+ end
52
+ }
24
53
  }
54
+ }.show
55
+ end
56
+ end
25
57
 
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
32
- }
33
- }
34
- }.show
58
+ BasicTableButton.new.launch
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+
5
+ include Glimmer
6
+
7
+ data = [
8
+ %w[cat meow delete],
9
+ %w[dog woof delete],
10
+ %w[chicken cock-a-doodle-doo delete],
11
+ %w[horse neigh delete],
12
+ %w[cow moo delete]
13
+ ]
14
+
15
+ window('Animal sounds', 400, 200) {
16
+ horizontal_box {
17
+ table {
18
+ text_column('Animal')
19
+ text_column('Description')
20
+ button_column('Action') {
21
+ on_clicked do |row|
22
+ data.delete_at(row) # automatically deletes actual table row due to implicit data-binding
23
+ end
24
+ }
25
+
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
32
+ }
33
+ }
34
+ }.show
@@ -21,7 +21,7 @@ window('Animals', 500, 200) {
21
21
  text_color_column('Sound')
22
22
  checkbox_text_color_column('Description')
23
23
  image_text_color_column('GUI')
24
- background_color_column('Mammal')
24
+ background_color_column # must be the last column
25
25
 
26
26
  cell_rows data
27
27
  }
@@ -18,8 +18,8 @@ window('Editable animal sounds', 300, 200) {
18
18
  text_column('Animal')
19
19
  text_column('Description')
20
20
 
21
- cell_rows data
22
21
  editable true
22
+ cell_rows data
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}"
@@ -1,17 +1,19 @@
1
1
  require 'glimmer-dsl-libui'
2
2
 
3
3
  class FormTable
4
+ Contact = Struct.new(:name, :email, :phone, :city, :state)
5
+
4
6
  include Glimmer
5
7
 
6
- attr_accessor :name, :email, :phone, :city, :state, :filter_value
8
+ attr_accessor :contacts, :name, :email, :phone, :city, :state, :filter_value
7
9
 
8
10
  def initialize
9
- @data = [
10
- ['Lisa Sky', 'lisa@sky.com', '720-523-4329', 'Denver', 'CO', '80014'],
11
- ['Jordan Biggins', 'jordan@biggins.com', '617-528-5399', 'Boston', 'MA', '02101'],
12
- ['Mary Glass', 'mary@glass.com', '847-589-8788', 'Elk Grove Village', 'IL', '60007'],
13
- ['Darren McGrath', 'darren@mcgrath.com', '206-539-9283', 'Seattle', 'WA', '98101'],
14
- ['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA', '90001'],
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'),
15
17
  ]
16
18
  end
17
19
 
@@ -25,7 +27,7 @@ class FormTable
25
27
 
26
28
  entry {
27
29
  label 'Name'
28
- text <=> [self, :name]
30
+ text <=> [self, :name] # bidirectional data-binding between entry text and self.name
29
31
  }
30
32
 
31
33
  entry {
@@ -57,8 +59,8 @@ class FormTable
57
59
  if new_row.include?('')
58
60
  msg_box_error(w, 'Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
59
61
  else
60
- @data << new_row # automatically inserts a row into the table due to implicit data-binding
61
- @unfiltered_data = @data.dup
62
+ @contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
63
+ @unfiltered_contacts = @contacts.dup
62
64
  self.name = '' # automatically clears name entry through explicit data-binding
63
65
  self.email = ''
64
66
  self.phone = ''
@@ -70,16 +72,17 @@ class FormTable
70
72
 
71
73
  search_entry {
72
74
  stretchy false
73
- text <=> [self, :filter_value, # bidirectional data-binding of text to self.filter_value with after_write option
75
+ # bidirectional data-binding of text to self.filter_value with after_write option
76
+ text <=> [self, :filter_value,
74
77
  after_write: ->(filter_value) { # execute after write to self.filter_value
75
- @unfiltered_data ||= @data.dup
78
+ @unfiltered_contacts ||= @contacts.dup
76
79
  # Unfilter first to remove any previous filters
77
- @data.replace(@unfiltered_data) # affects table indirectly through implicit data-binding
80
+ self.contacts = @unfiltered_contacts.dup # affects table indirectly through explicit data-binding
78
81
  # Now, apply filter if entered
79
82
  unless filter_value.empty?
80
- @data.filter! do |row_data| # affects table indirectly through implicit data-binding
81
- row_data.any? do |cell|
82
- cell.to_s.downcase.include?(filter_value.downcase)
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)
83
86
  end
84
87
  end
85
88
  end
@@ -94,7 +97,8 @@ class FormTable
94
97
  text_column('City')
95
98
  text_column('State')
96
99
 
97
- cell_rows @data # implicit data-binding
100
+ editable true
101
+ cell_rows <=> [self, :contacts] # explicit data-binding to Model Array
98
102
 
99
103
  on_changed do |row, type, row_data|
100
104
  puts "Row #{row} #{type}: #{row_data}"
@@ -1,93 +1,112 @@
1
1
  require 'glimmer-dsl-libui'
2
2
 
3
- include Glimmer
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
- 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
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
- 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)
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
- end
76
- end
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
- table {
80
- text_column('Name')
81
- text_column('Email')
82
- text_column('Phone')
83
- text_column('City')
84
- text_column('State')
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
- cell_rows data # implicit data-binding
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