glimmer-dsl-tk 0.0.4 → 0.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 631bc5fe4586f68987c644c71f33768414c8088601dfbe1cc641d0fc13656729
4
- data.tar.gz: abe0f504f6b7fd897af3964e24041331bba475a966c9e75fc22554b86b31cbef
3
+ metadata.gz: 8b2c3772ea3eeec35d08dfaebbe1db0a25d85b9569e7c88461a0886447c73928
4
+ data.tar.gz: 6b27a8f3a122a570732d64ca541703cb33fe21009d4e04f1d51cbf3ebdc96df8
5
5
  SHA512:
6
- metadata.gz: c9d211b7f70cbf38c2ad231343a1d5b73c14767d89468a1e99bf418209c03db079edf5ea116ef78c211f4e35795607ea7a9911acf48bffc3913ed53a0adcbc7a
7
- data.tar.gz: b7a66a93ad9d478a215c0c3d6348c9e934ce6dc34b04716d8f2d61a908dd62dd2fa4a4bc42fd4804bd53e0a6c5e4413dc2ea6495b3d2c87417e46d435cb82da9
6
+ metadata.gz: c470bb4fdc925295f92b6f743126edc5c2fef5480dc7913c66124a4489c6d093f163a70ba4410894043a51f715af2fb09aea5eff85f06031ba012467197b7dc0
7
+ data.tar.gz: 50ff417aab865e7dbdf0d5208d211cb19a5bd6fc4c1c193a695394e42b6f9715f2e1bbe7ada5985ad123ad3bbc75d879330b535afc7454d00522a27b33137322
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.5
4
+
5
+ - Label text data-binding
6
+ - Entry text data-binding
7
+ - The `grid` geometry manager
8
+ - Hello, Computed! sample
9
+
3
10
  ## 0.0.4
4
11
 
5
12
  - `list` custom widget (since listbox is not tile themed yet in Tk)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.4 (Desktop GUI)
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.5 (Desktop GUI)
2
2
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-tk.svg)](http://badge.fury.io/rb/glimmer-dsl-tk)
3
3
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-tk.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-tk)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer-dsl-tk/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer-dsl-tk?branch=master)
@@ -77,7 +77,7 @@ gem install glimmer-dsl-tk
77
77
 
78
78
  Add the following to `Gemfile`:
79
79
  ```
80
- gem 'glimmer-dsl-tk', '~> 0.0.4'
80
+ gem 'glimmer-dsl-tk', '~> 0.0.5'
81
81
  ```
82
82
 
83
83
  And, then run:
@@ -163,6 +163,26 @@ root {
163
163
  }.open
164
164
  ```
165
165
 
166
+ ## The Grid Geometry Manager
167
+
168
+ The Grid Geometry Manager is supported via the `grid` keyword just as per the [Tk documentation](https://tkdocs.com/tutorial/grid.html), except by nesting under the widget it concerns.
169
+
170
+ Example:
171
+
172
+ ```ruby
173
+ label {
174
+ grid column: 0, row: 2, sticky: 'w'
175
+ text 'Year of Birth: '
176
+ }
177
+ entry {
178
+ grid column: 1, row: 2
179
+ width 15
180
+ text bind(@contact, :year_of_birth)
181
+ }
182
+ ```
183
+
184
+ More details can be found in the [Hello, Computed!](#hello-computed) sample below.
185
+
166
186
  ## Bidirectional Data-Binding
167
187
 
168
188
  Glimmer supports bidirectional data-binding via the `bind` keyword, which takes a model and an attribute.
@@ -180,8 +200,8 @@ This assumes a `Person` model with a `country` attribute representing their curr
180
200
  }
181
201
  ```
182
202
 
183
- It binds the `values` of the `combobox` to the `country_options` property on the `person` model (data-binding attribute + "_options" by convention).
184
- That binds the `text` selection of the `combobox` to the `country` property on the `person` model.
203
+ That code sets the `values` of the `combobox` to the `country_options` property on the `person` model (data-binding attribute + "_options" by convention).
204
+ It also binds the `text` selection of the `combobox` to the `country` property on the `person` model.
185
205
 
186
206
  It automatically handles all the Tk plumbing behind the scenes, such as using `TkVariable` and setting `combobox` `values` from `person.country_options` by convention (attribute_name + "_options").
187
207
 
@@ -202,7 +222,7 @@ This assumes a `Person` model with a `country` attribute representing their curr
202
222
  }
203
223
  ```
204
224
 
205
- It binds the `items` text of the `list` to the `country_options` property on the `person` model (data-binding attribute + "_options" by convention).
225
+ That code binds the `items` text of the `list` to the `country_options` property on the `person` model (data-binding attribute + "_options" by convention).
206
226
  It also binds the `selection` text of the `list` to the `country` property on the `person` model.
207
227
 
208
228
  It automatically handles all the Tk plumbing behind the scenes.
@@ -223,13 +243,49 @@ This assumes a `Person` model with a `provinces` attribute representing their cu
223
243
  }
224
244
  ```
225
245
 
226
- It binds the `items` text of the `list` to the `provinces_options` property on the `person` model (data-binding attribute + "_options" by convention)
246
+ That code binds the `items` text of the `list` to the `provinces_options` property on the `person` model (data-binding attribute + "_options" by convention)
227
247
  That binds the `selection` text of the `list` to the `provinces` property on the `person` model.
228
248
 
229
249
  It automatically handles all the Tk plumbing behind the scenes.
230
250
 
231
251
  More details can be found in the [Hello, List Multi Selection!](#hello-list-multi-selection) sample below.
232
252
 
253
+ ### Label Data-Binding
254
+
255
+ Example:
256
+
257
+ This assumes a `Person` model with a `country` attribute.
258
+
259
+ ```ruby
260
+ label {
261
+ text bind(person, :country)
262
+ }
263
+ ```
264
+
265
+ That code binds the `textvariable` value of the `label` to the `country` property on the `person` model.
266
+
267
+ It automatically handles all the Tk plumbing behind the scenes.
268
+
269
+ More details can be found in the [Hello, Computed!](#hello-computed) sample below.
270
+
271
+ ### Entry Data-Binding
272
+
273
+ Example:
274
+
275
+ This assumes a `Person` model with a `country` attribute.
276
+
277
+ ```ruby
278
+ entry {
279
+ text bind(person, :country)
280
+ }
281
+ ```
282
+
283
+ That code binds the `textvariable` value of the `entry` to the `country` property on the `person` model.
284
+
285
+ It automatically handles all the Tk plumbing behind the scenes.
286
+
287
+ More details can be found in the [Hello, Computed!](#hello-computed) sample below.
288
+
233
289
  ## Command Observer
234
290
 
235
291
  Buttons can set a `command` option to trigger when the user clicks the button. This may be done with the `command` keyword, passing in a block directly (no need for `proc` as per Tk)
@@ -408,9 +464,79 @@ Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem ins
408
464
  ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_list_multi_selection.rb'"
409
465
  ```
410
466
 
467
+ ### Hello, Computed!
468
+
469
+ Glimmer code (from [samples/hello/hello_computed.rb](samples/hello/hello_computed.rb)):
470
+
471
+ ```ruby
472
+ # ... more code precedes
473
+ root {
474
+ title 'Hello, Computed!'
475
+
476
+ frame {
477
+ grid column: 0, row: 0, padx: 5, pady: 5
478
+
479
+ label {
480
+ grid column: 0, row: 0, sticky: 'w'
481
+ text 'First Name: '
482
+ }
483
+ entry {
484
+ grid column: 1, row: 0
485
+ width 15
486
+ text bind(@contact, :first_name)
487
+ }
488
+
489
+ label {
490
+ grid column: 0, row: 1, sticky: 'w'
491
+ text 'Last Name: '
492
+ }
493
+ entry {
494
+ grid column: 1, row: 1
495
+ width 15
496
+ text bind(@contact, :last_name)
497
+ }
498
+
499
+ label {
500
+ grid column: 0, row: 2, sticky: 'w'
501
+ text 'Year of Birth: '
502
+ }
503
+ entry {
504
+ grid column: 1, row: 2
505
+ width 15
506
+ text bind(@contact, :year_of_birth)
507
+ }
508
+
509
+ label {
510
+ grid column: 0, row: 3, sticky: 'w'
511
+ text 'Name: '
512
+ }
513
+ label {
514
+ grid column: 1, row: 3, sticky: 'w'
515
+ text bind(@contact, :name, computed_by: [:first_name, :last_name])
516
+ }
517
+
518
+ label {
519
+ grid column: 0, row: 4, sticky: 'w'
520
+ text 'Age: '
521
+ }
522
+ label {
523
+ grid column: 1, row: 4, sticky: 'w'
524
+ text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
525
+ }
526
+ }
527
+ }.open
528
+ # ... more code follows
529
+ ```
530
+
531
+ Run (with the [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed):
532
+
533
+ ```
534
+ ruby -r glimmer-dsl-tk -e "require '../samples/hello/hello_computed.rb'"
535
+ ```
536
+
411
537
  Glimmer app:
412
538
 
413
- ![glimmer dsl tk screenshot sample hello list multi selection](images/glimmer-dsl-tk-screenshot-sample-hello-list-multi-selection.png)
539
+ ![glimmer dsl tk screenshot sample hello computed](images/glimmer-dsl-tk-screenshot-sample-hello-computed.png)
414
540
 
415
541
  ## Help
416
542
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -55,4 +55,6 @@ require 'glimmer/tk/widget_proxy'
55
55
  require 'glimmer/tk/notebook_proxy'
56
56
  require 'glimmer/tk/frame_proxy'
57
57
  require 'glimmer/tk/button_proxy'
58
+ require 'glimmer/tk/label_proxy'
58
59
  require 'glimmer/tk/list_proxy'
60
+ require 'glimmer/tk/entry_proxy'
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/tk/widget_proxy'
23
+
24
+ module Glimmer
25
+ module Tk
26
+ # Proxy for Tk::Tile::TEntry
27
+ #
28
+ # Follows the Proxy Design Pattern
29
+ class EntryProxy < WidgetProxy
30
+ def validatecommand_block=(proc)
31
+ tk.validatecommand(proc)
32
+ end
33
+ def invalidcommand_block=(proc)
34
+ tk.invalidcommand(proc)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,40 @@
1
+ # Copyright (c) 2020 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/tk/widget_proxy'
23
+
24
+ module Glimmer
25
+ module Tk
26
+ # Proxy for Tk::Tile::TLabel
27
+ #
28
+ # Follows the Proxy Design Pattern
29
+ class LabelProxy < WidgetProxy
30
+ # TODO specify attribute setters
31
+ # def tk_widget_has_attribute_setter?(attribute)
32
+ # if ['anchor', 'justify'].include?(attribute.to_s)
33
+ # true
34
+ # else
35
+ # super
36
+ # end
37
+ # end
38
+ end
39
+ end
40
+ end
@@ -31,6 +31,12 @@ module Glimmer
31
31
  'combobox' => lambda do |tk|
32
32
  tk.textvariable = ::TkVariable.new
33
33
  end,
34
+ 'label' => lambda do |tk|
35
+ tk.textvariable = ::TkVariable.new
36
+ end,
37
+ 'entry' => lambda do |tk|
38
+ tk.textvariable = ::TkVariable.new
39
+ end,
34
40
  }
35
41
 
36
42
  class << self
@@ -75,7 +81,7 @@ module Glimmer
75
81
  def initialize(underscored_widget_name, parent_proxy, args)
76
82
  @parent_proxy = parent_proxy
77
83
  @args = args
78
- tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name)
84
+ tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name)
79
85
  @tk = tk_widget_class.new(@parent_proxy.tk, *args)
80
86
  # a common widget initializer
81
87
  @tk.grid
@@ -97,7 +103,7 @@ module Glimmer
97
103
  !!tk_widget_class_for(underscored_widget_name)
98
104
  end
99
105
 
100
- def tk_widget_has_attribute?(attribute)
106
+ def tk_widget_has_attribute_setter?(attribute)
101
107
  result = nil
102
108
  begin
103
109
  # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
@@ -109,9 +115,22 @@ module Glimmer
109
115
  result
110
116
  end
111
117
 
118
+ def tk_widget_has_attribute_getter_setter?(attribute)
119
+ result = nil
120
+ begin
121
+ # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
122
+ @tk.send(attribute, @tk.send(attribute))
123
+ result = true
124
+ rescue => e
125
+ result = false
126
+ end
127
+ result
128
+ end
129
+
112
130
  def has_attribute?(attribute, *args)
113
131
  (widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]) ||
114
- tk_widget_has_attribute?(attribute) ||
132
+ tk_widget_has_attribute_setter?(attribute) ||
133
+ tk_widget_has_attribute_getter_setter?(attribute) ||
115
134
  respond_to?(attribute_setter(attribute), args)
116
135
  end
117
136
 
@@ -119,8 +138,10 @@ module Glimmer
119
138
  widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
120
139
  if widget_custom_attribute
121
140
  widget_custom_attribute[:setter][:invoker].call(@tk, args)
122
- elsif tk_widget_has_attribute?(attribute)
141
+ elsif tk_widget_has_attribute_setter?(attribute)
123
142
  @tk.send(attribute_setter(attribute), *args) unless @tk.send(attribute) == args.first
143
+ elsif tk_widget_has_attribute_getter_setter?(attribute)
144
+ @tk.send(attribute, *args) unless @tk.send(attribute) == args.first
124
145
  else
125
146
  send(attribute_setter(attribute), args)
126
147
  end
@@ -130,7 +151,7 @@ module Glimmer
130
151
  widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
131
152
  if widget_custom_attribute
132
153
  widget_custom_attribute[:getter][:invoker].call(@tk, args)
133
- elsif tk_widget_has_attribute?(attribute)
154
+ elsif tk_widget_has_attribute_getter_setter?(attribute)
134
155
  @tk.send(attribute)
135
156
  else
136
157
  send(attribute)
@@ -149,6 +170,18 @@ module Glimmer
149
170
  setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
150
171
  },
151
172
  },
173
+ ::Tk::Tile::TLabel => {
174
+ 'text' => {
175
+ getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
176
+ setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
177
+ },
178
+ },
179
+ ::Tk::Tile::TEntry => {
180
+ 'text' => {
181
+ getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
182
+ setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first unless @text_variable_edit }},
183
+ },
184
+ },
152
185
  }
153
186
  end
154
187
 
@@ -166,6 +199,21 @@ module Glimmer
166
199
  }
167
200
  end,
168
201
  },
202
+ ::Tk::Tile::TEntry => {
203
+ 'text' => lambda do |observer|
204
+ tk.validate = 'key'
205
+ tk.validatecommand { |new_tk_variable|
206
+ @text_variable_edit = new_tk_variable.value != @tk.textvariable.value
207
+ if @text_variable_edit
208
+ observer.call(new_tk_variable.value)
209
+ @text_variable_edit = nil
210
+ true
211
+ else
212
+ false
213
+ end
214
+ }
215
+ end,
216
+ },
169
217
  }
170
218
  end
171
219
 
@@ -0,0 +1,75 @@
1
+ require 'glimmer-dsl-tk'
2
+
3
+ require_relative 'hello_computed/contact'
4
+
5
+ class HelloComputed
6
+ include Glimmer
7
+
8
+ def initialize
9
+ @contact = Contact.new(
10
+ first_name: 'Barry',
11
+ last_name: 'McKibbin',
12
+ year_of_birth: 1985
13
+ )
14
+ end
15
+
16
+ def launch
17
+ root {
18
+ title 'Hello, Computed!'
19
+
20
+ frame {
21
+ grid column: 0, row: 0, padx: 5, pady: 5
22
+
23
+ label {
24
+ grid column: 0, row: 0, sticky: 'w'
25
+ text 'First Name: '
26
+ }
27
+ entry {
28
+ grid column: 1, row: 0
29
+ width 15
30
+ text bind(@contact, :first_name)
31
+ }
32
+
33
+ label {
34
+ grid column: 0, row: 1, sticky: 'w'
35
+ text 'Last Name: '
36
+ }
37
+ entry {
38
+ grid column: 1, row: 1
39
+ width 15
40
+ text bind(@contact, :last_name)
41
+ }
42
+
43
+ label {
44
+ grid column: 0, row: 2, sticky: 'w'
45
+ text 'Year of Birth: '
46
+ }
47
+ entry {
48
+ grid column: 1, row: 2
49
+ width 15
50
+ text bind(@contact, :year_of_birth)
51
+ }
52
+
53
+ label {
54
+ grid column: 0, row: 3, sticky: 'w'
55
+ text 'Name: '
56
+ }
57
+ label {
58
+ grid column: 1, row: 3, sticky: 'w'
59
+ text bind(@contact, :name, computed_by: [:first_name, :last_name])
60
+ }
61
+
62
+ label {
63
+ grid column: 0, row: 4, sticky: 'w'
64
+ text 'Age: '
65
+ }
66
+ label {
67
+ grid column: 1, row: 4, sticky: 'w'
68
+ text bind(@contact, :age, on_write: :to_i, computed_by: [:year_of_birth])
69
+ }
70
+ }
71
+ }.open
72
+ end
73
+ end
74
+
75
+ HelloComputed.new.launch
@@ -0,0 +1,21 @@
1
+ class HelloComputed
2
+ class Contact
3
+ attr_accessor :first_name, :last_name, :year_of_birth
4
+
5
+ def initialize(attribute_map)
6
+ @first_name = attribute_map[:first_name]
7
+ @last_name = attribute_map[:last_name]
8
+ @year_of_birth = attribute_map[:year_of_birth]
9
+ end
10
+
11
+ def name
12
+ "#{last_name}, #{first_name}"
13
+ end
14
+
15
+ def age
16
+ Time.now.year - year_of_birth.to_i
17
+ rescue
18
+ 0
19
+ end
20
+ end
21
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-tk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-13 00:00:00.000000000 Z
11
+ date: 2020-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -198,12 +198,16 @@ files:
198
198
  - lib/glimmer/dsl/tk/root_expression.rb
199
199
  - lib/glimmer/dsl/tk/widget_expression.rb
200
200
  - lib/glimmer/tk/button_proxy.rb
201
+ - lib/glimmer/tk/entry_proxy.rb
201
202
  - lib/glimmer/tk/frame_proxy.rb
203
+ - lib/glimmer/tk/label_proxy.rb
202
204
  - lib/glimmer/tk/list_proxy.rb
203
205
  - lib/glimmer/tk/notebook_proxy.rb
204
206
  - lib/glimmer/tk/root_proxy.rb
205
207
  - lib/glimmer/tk/widget_proxy.rb
206
208
  - samples/hello/hello_combo.rb
209
+ - samples/hello/hello_computed.rb
210
+ - samples/hello/hello_computed/contact.rb
207
211
  - samples/hello/hello_list_multi_selection.rb
208
212
  - samples/hello/hello_list_single_selection.rb
209
213
  - samples/hello/hello_tab.rb