glimmer-dsl-libui 0.4.10 → 0.4.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.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