glimmer-dsl-libui 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class Login
4
+ include Glimmer
5
+
6
+ attr_accessor :username, :password
7
+ attr_reader :logged_in
8
+
9
+ def logged_in=(value)
10
+ @logged_in = value
11
+ self.logged_out = !value # calling logged_out= method notifies logged_out observers
12
+ end
13
+
14
+ def logged_out=(value)
15
+ self.logged_in = !value unless logged_in == !value
16
+ end
17
+
18
+ def logged_out
19
+ !logged_in
20
+ end
21
+
22
+ def launch
23
+ window('Login') {
24
+ margined true
25
+
26
+ vertical_box {
27
+ form {
28
+ entry {
29
+ label 'Username:'
30
+ text <=> [self, :username]
31
+ enabled <= [self, :logged_out]
32
+ }
33
+
34
+ password_entry {
35
+ label 'Password:'
36
+ text <=> [self, :password]
37
+ enabled <= [self, :logged_out]
38
+ }
39
+ }
40
+
41
+ horizontal_box {
42
+ button('Login') {
43
+ enabled <= [self, :logged_out]
44
+
45
+ on_clicked do
46
+ self.logged_in = true
47
+ end
48
+ }
49
+
50
+ button('Logout') {
51
+ enabled <= [self, :logged_in]
52
+
53
+ on_clicked do
54
+ self.logged_in = false
55
+ self.username = ''
56
+ self.password = ''
57
+ end
58
+ }
59
+ }
60
+ }
61
+ }.show
62
+ end
63
+ end
64
+
65
+ Login.new.launch
@@ -0,0 +1,61 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ class Login
4
+ include Glimmer
5
+
6
+ attr_accessor :username, :password
7
+ attr_reader :logged_in
8
+
9
+ def logged_in=(value)
10
+ @logged_in = value
11
+ notify_observers(:logged_out) # manually notify observers of logged_out upon logged_in changes; this method comes automatically from enhancement as Glimmer::DataBinding::ObservableModel via data-binding
12
+ end
13
+
14
+ def logged_out
15
+ !logged_in
16
+ end
17
+
18
+ def launch
19
+ window('Login') {
20
+ margined true
21
+
22
+ vertical_box {
23
+ form {
24
+ entry {
25
+ label 'Username:'
26
+ text <=> [self, :username]
27
+ enabled <= [self, :logged_out]
28
+ }
29
+
30
+ password_entry {
31
+ label 'Password:'
32
+ text <=> [self, :password]
33
+ enabled <= [self, :logged_out]
34
+ }
35
+ }
36
+
37
+ horizontal_box {
38
+ button('Login') {
39
+ enabled <= [self, :logged_out]
40
+
41
+ on_clicked do
42
+ self.logged_in = true
43
+ end
44
+ }
45
+
46
+ button('Logout') {
47
+ enabled <= [self, :logged_in]
48
+
49
+ on_clicked do
50
+ self.logged_in = false
51
+ self.username = ''
52
+ self.password = ''
53
+ end
54
+ }
55
+ }
56
+ }
57
+ }.show
58
+ end
59
+ end
60
+
61
+ Login.new.launch
@@ -0,0 +1,43 @@
1
+ require 'glimmer-dsl-libui'
2
+
3
+ include Glimmer
4
+
5
+ window('Login') {
6
+ margined true
7
+
8
+ vertical_box {
9
+ form {
10
+ @username_entry = entry {
11
+ label 'Username:'
12
+ }
13
+
14
+ @password_entry = password_entry {
15
+ label 'Password:'
16
+ }
17
+ }
18
+
19
+ horizontal_box {
20
+ @login_button = button('Login') {
21
+ on_clicked do
22
+ @username_entry.enabled = false
23
+ @password_entry.enabled = false
24
+ @login_button.enabled = false
25
+ @logout_button.enabled = true
26
+ end
27
+ }
28
+
29
+ @logout_button = button('Logout') {
30
+ enabled false
31
+
32
+ on_clicked do
33
+ @username_entry.text = ''
34
+ @password_entry.text = ''
35
+ @username_entry.enabled = true
36
+ @password_entry.enabled = true
37
+ @login_button.enabled = true
38
+ @logout_button.enabled = false
39
+ end
40
+ }
41
+ }
42
+ }
43
+ }.show
@@ -7,8 +7,11 @@ class MetaExample
7
7
 
8
8
  ADDITIONAL_BASIC_EXAMPLES = ['Color Button', 'Font Button', 'Form', 'Date Time Picker', 'Simple Notepad']
9
9
 
10
+ attr_accessor :code_text
11
+
10
12
  def initialize
11
13
  @selected_example_index = examples_with_versions.index(basic_examples_with_versions.first)
14
+ @code_text = File.read(file_path_for(selected_example))
12
15
  end
13
16
 
14
17
  def examples
@@ -89,7 +92,7 @@ class MetaExample
89
92
  on_selected do
90
93
  @selected_example_index = examples_with_versions.index(basic_examples_with_versions[@basic_example_radio_buttons.selected])
91
94
  example = selected_example
92
- @code_entry.text = File.read(file_path_for(example))
95
+ self.code_text = File.read(file_path_for(example))
93
96
  @version_spinbox.value = 1
94
97
  end
95
98
  }
@@ -108,7 +111,7 @@ class MetaExample
108
111
  on_selected do
109
112
  @selected_example_index = examples_with_versions.index(advanced_examples_with_versions[@advanced_example_radio_buttons.selected])
110
113
  example = selected_example
111
- @code_entry.text = File.read(file_path_for(example))
114
+ self.code_text = File.read(file_path_for(example))
112
115
  @version_spinbox.value = 1
113
116
  end
114
117
  }
@@ -134,7 +137,7 @@ class MetaExample
134
137
  else
135
138
  version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
136
139
  example = "#{selected_example}#{version_number}"
137
- @code_entry.text = File.read(file_path_for(example))
140
+ self.code_text = File.read(file_path_for(example))
138
141
  end
139
142
  end
140
143
  }
@@ -149,7 +152,7 @@ class MetaExample
149
152
  parent_dir = File.join(Dir.home, '.glimmer-dsl-libui', 'examples')
150
153
  FileUtils.mkdir_p(parent_dir)
151
154
  example_file = File.join(parent_dir, "#{selected_example.underscore}.rb")
152
- File.write(example_file, @code_entry.text)
155
+ File.write(example_file, code_text)
153
156
  example_supporting_directory = File.expand_path(selected_example.underscore, __dir__)
154
157
  FileUtils.cp_r(example_supporting_directory, parent_dir) if Dir.exist?(example_supporting_directory)
155
158
  FileUtils.cp_r(File.expand_path('../icons', __dir__), File.dirname(parent_dir))
@@ -164,14 +167,14 @@ class MetaExample
164
167
  }
165
168
  button('Reset') {
166
169
  on_clicked do
167
- @code_entry.text = File.read(file_path_for(selected_example))
170
+ self.code_text = File.read(file_path_for(selected_example))
168
171
  end
169
172
  }
170
173
  }
171
174
  }
172
175
 
173
176
  @code_entry = non_wrapping_multiline_entry {
174
- text File.read(file_path_for(selected_example))
177
+ text <=> [self, :code_text]
175
178
  }
176
179
  }
177
180
  }.show
@@ -5,15 +5,11 @@ include Glimmer
5
5
 
6
6
  Address = Struct.new(:street, :p_o_box, :city, :state, :zip_code)
7
7
 
8
- def form_field(model, property)
9
- property = property.to_s
8
+ def form_field(model, attribute)
9
+ attribute = attribute.to_s
10
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
11
+ label attribute.underscore.split('_').map(&:capitalize).join(' ')
12
+ text <=> [model, attribute]
17
13
  }
18
14
  end
19
15
 
@@ -28,15 +24,12 @@ def address_form(address)
28
24
  end
29
25
 
30
26
  def label_pair(model, attribute, value)
31
- name_label = nil
32
- value_label = nil
33
27
  horizontal_box {
34
- name_label = label(attribute.to_s.underscore.split('_').map(&:capitalize).join(' '))
35
- value_label = label(value.to_s)
28
+ label(attribute.to_s.underscore.split('_').map(&:capitalize).join(' '))
29
+ label(value.to_s) {
30
+ text <= [model, attribute]
31
+ }
36
32
  }
37
- observe(model, attribute) do
38
- value_label.text = model.send(attribute)
39
- end
40
33
  end
41
34
 
42
35
  def address(address)
@@ -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
+ observe(model, attribute) do
38
+ value_label.text = model.send(attribute)
39
+ end
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
@@ -30,16 +30,14 @@ module Glimmer
30
30
  class DataBindingExpression < Expression
31
31
  def can_interpret?(parent, keyword, *args, &block)
32
32
  args.size == 1 and
33
- args[0].is_a?(DataBinding::ModelBinding)
33
+ args[0].is_a?(DataBinding::ModelBinding) and
34
+ parent.respond_to?(:data_bind)
34
35
  end
35
36
 
36
37
  def interpret(parent, keyword, *args, &block)
38
+ property = keyword
37
39
  model_binding = args[0]
38
- model_attribute_observer = Glimmer::DataBinding::Observer.proc do
39
- parent.send("#{keyword}=", model_binding.evaluate_property)
40
- end
41
- model_attribute_observer.observe(model_binding)
42
- model_attribute_observer.call # initial update
40
+ parent.data_bind(property, model_binding)
43
41
  end
44
42
  end
45
43
  end
@@ -28,6 +28,11 @@ module Glimmer
28
28
  #
29
29
  # Follows the Proxy Design Pattern
30
30
  class EntryProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
34
+ end
35
+
31
36
  def libui_api_keyword
32
37
  'entry'
33
38
  end
@@ -28,6 +28,11 @@ module Glimmer
28
28
  #
29
29
  # Follows the Proxy Design Pattern
30
30
  class MultilineEntryProxy < ControlProxy
31
+ def data_bind(property, model_binding)
32
+ super
33
+ handle_listener('on_changed') { model_binding.call(text) } if property == 'text'
34
+ end
35
+
31
36
  def libui_api_keyword
32
37
  'multiline_entry'
33
38
  end
@@ -332,6 +332,18 @@ module Glimmer
332
332
  alias set_visible visible
333
333
  alias visible= visible
334
334
 
335
+ # Data-binds model to update view.
336
+ # Subclasses can override to do inverse data-binding by observing view control for property changes and updating model binding accordingly
337
+ def data_bind(property, model_binding)
338
+ model_attribute_observer = Glimmer::DataBinding::Observer.proc do
339
+ new_value = model_binding.evaluate_property
340
+ send("#{property}=", new_value) unless send(property) == new_value
341
+ end
342
+ model_attribute_observer.observe(model_binding)
343
+ model_attribute_observer.call # initial update
344
+ model_attribute_observer
345
+ end
346
+
335
347
  def content(&block)
336
348
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::ControlExpression.new, @keyword, &block)
337
349
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-libui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-26 00:00:00.000000000 Z
11
+ date: 2021-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -223,6 +223,7 @@ files:
223
223
  - examples/basic_draw_text.rb
224
224
  - examples/basic_draw_text2.rb
225
225
  - examples/basic_entry.rb
226
+ - examples/basic_entry2.rb
226
227
  - examples/basic_image.rb
227
228
  - examples/basic_image2.rb
228
229
  - examples/basic_image3.rb
@@ -257,12 +258,19 @@ files:
257
258
  - examples/editable_table.rb
258
259
  - examples/font_button.rb
259
260
  - examples/form.rb
261
+ - examples/form2.rb
260
262
  - examples/form_table.rb
263
+ - examples/form_table2.rb
261
264
  - examples/grid.rb
262
265
  - examples/histogram.rb
263
266
  - examples/login.rb
267
+ - examples/login2.rb
268
+ - examples/login3.rb
269
+ - examples/login4.rb
270
+ - examples/login5.rb
264
271
  - examples/meta_example.rb
265
272
  - examples/method_based_custom_keyword.rb
273
+ - examples/method_based_custom_keyword2.rb
266
274
  - examples/midi_player.rb
267
275
  - examples/simple_notepad.rb
268
276
  - examples/snake.rb