glimmer-dsl-tk 0.0.57 → 0.0.60

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e0e1ed1843f904d42892c7fe2546383717da65d7cfd0690b1b66101a5b68576
4
- data.tar.gz: af96af00f8b06606ac584ab14d5d8d360977a58ec354053a0826edc470c0d57f
3
+ metadata.gz: 9c0553115fdb0b7a912c59f6feda8b475e76c546fc2db32984037e7bbc8db204
4
+ data.tar.gz: 450c7795ef8adafe88db9fbfdf78691933f79b06f1f4b1e899f5ddacac3da567
5
5
  SHA512:
6
- metadata.gz: '01787afce29bc0b1d4656b8ab646f0eb4501a8b8feb23979ad99970f6e5d6bb75d5945bb0b9a9a91cdb34f36d6bdf9226ec3e3aa60368206cd98b40daa2cd0a1'
7
- data.tar.gz: 677f8d13ab20b7857c613167d1d21eed0dec3f1b19a8b29ba4b4cec49545186446c2c9bacbaf9e0741c16ceb2d20e60136c482dc6e78783d8b1d435ed4239be8
6
+ metadata.gz: 256d0e2d25fd50791b979cf92ba9dad8dedf77941e6e6394f1474f41f20a035bb601f6cc2af3b2bab8ed0b3acf11825d041a3d65d5d8941da85e6fc563c7c23b
7
+ data.tar.gz: b122dd08e9a6b2ec400ecf49c15d0be69fcc3c4e4fbe4de9c427dc0b1a085cae6ab8c95deca79272f28ecb21479477a6792ae434544c64013ebfe8cc4b8b49de
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.60
4
+
5
+ - Update Hello, Built-in Dialog! with more options for customizing dialogs
6
+ - Support setting colors as rgb colors via `r, g, b` (e.g. `foreground 210, 48, 110`)
7
+ - Accept hex color strings not starting with `#` (e.g. `background 'f828d7'`)
8
+
9
+ ## 0.0.59
10
+
11
+ - Auto-Default to `validate 'key'` on an `entry` when defining `validatecommand {}`, `on('validate') {}`, `invalidcommand {}`, `on('invalid') {}`
12
+
13
+ ## 0.0.58
14
+
15
+ - Support `@tk.textvariable.trace('write')` kind of variable tracing via `on_var(trace_operation) {}` listeners (e.g. `on_textvariable('write') {}`)
16
+ - Use `on_textvariable` in `samples/hello/hello_entry.rb`
17
+ - Improve validation text in `samples/hello/hello_entry.rb` to say "... not a valid phone!"
18
+
3
19
  ## 0.0.57
4
20
 
5
21
  - Hello, Theme! sample
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.57
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.60
2
2
  ## Ruby Tk Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-tk.svg)](http://badge.fury.io/rb/glimmer-dsl-tk)
4
4
  [![Ruby](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml/badge.svg)](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml)
@@ -195,7 +195,7 @@ gem install glimmer-dsl-tk
195
195
 
196
196
  Add the following to `Gemfile`:
197
197
  ```
198
- gem 'glimmer-dsl-tk', '0.0.57'
198
+ gem 'glimmer-dsl-tk', '0.0.60'
199
199
  ```
200
200
 
201
201
  And, then run:
@@ -309,14 +309,14 @@ keyword(args) | attributes | event bindings & callbacks
309
309
  ------------- | ---------- | ---------
310
310
  `button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command {}`
311
311
  `checkbutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `onvalue` (default: `1`), `offvalue` (default: `0`) | `command {}`
312
- `choose_color(options = nil)` | None | None
313
- `choose_directory(options = nil)` | None | None
314
- `choose_font(options = nil) {|font| ... }` | None | None
312
+ `choose_color(parent: nil, initialcolor: 'white', title: 'Colors')` | None | None
313
+ `choose_directory(parent: nil)` | None | None
314
+ `choose_font(family: nil, size: nil, weight: nil) {|font| ... }` | None | None
315
315
  `combobox` | `state`, `text` | `'ComboboxSelected'`
316
316
  `entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'` (alias: `'changed'`), `validatecommand {}`, `invalidcommand {}`
317
- `get_multiple_open_file(options = nil)` | None | None
318
- `get_open_file(options = nil)` | None | None
319
- `get_save_file(options = nil)` | None | None
317
+ `get_multiple_open_file(parent: nil, title: '')` | None | None
318
+ `get_open_file(parent: nil, title: '')` | None | None
319
+ `get_save_file(parent: nil, title: '')` | None | None
320
320
  `spinbox` | `text`, `from`, `to`, `increment`, `format`, [more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `command {}`, `'increment'`, `'decrement'`
321
321
  `frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
322
322
  `label` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `font` (`'default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip'`), `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`), `justify` (`'left', 'center', 'right'`), `foreground`, `background` | None
@@ -343,6 +343,8 @@ Options for `get_open_file` and `get_multiple_open_file` include:
343
343
  #### Common Attributes
344
344
 
345
345
  - `grid`: `Hash` of `:row`, `:column`, `:padx`, `:pady`, `:sticky` (`'e', 'w', 'n', 's'` or any combination of direction letters)
346
+ - `foreground`: [Built-in Color](https://tcl.tk/man/tcl8.6/TkCmd/colors.htm) (e.g. `'AliceBlue'`) or Hex color (e.g. `'#ffd807'`)
347
+ - `background`: [Built-in Color](https://tcl.tk/man/tcl8.6/TkCmd/colors.htm) (e.g. `'AliceBlue'`) or Hex color (e.g. `'#ffd807'`)
346
348
 
347
349
  #### Common Event Bindings
348
350
 
@@ -2181,12 +2183,13 @@ class HelloEntry
2181
2183
  def launch
2182
2184
  root {
2183
2185
  title 'Hello, Entry!'
2184
-
2186
+ minsize 230, 0
2187
+
2185
2188
  label {
2186
2189
  grid sticky: 'ew'
2187
2190
  text 'default entry'
2188
2191
  }
2189
- entry {
2192
+ entry { |the_entry|
2190
2193
  grid sticky: 'ew'
2191
2194
  text <=> [self, :default]
2192
2195
  }
@@ -2205,11 +2208,14 @@ class HelloEntry
2205
2208
  grid sticky: 'ew'
2206
2209
  text 'entry with event handlers'
2207
2210
  }
2208
- entry {
2211
+ entry { |the_entry|
2209
2212
  grid sticky: 'ew'
2210
2213
  text <=> [self, :telephone]
2211
- validate 'key'
2212
2214
 
2215
+ # validate 'key' # default when on('validate') or on('invalid') is specified
2216
+ ## Validation happens on key change by default when validation listeners are specified
2217
+ ## (other accepted values: 'none', 'focus', 'focusin', 'focusout', 'key', or 'all')
2218
+
2213
2219
  ## this event kicks in just after the user typed and before modifying the text variable
2214
2220
  on('validate') do |new_text_variable|
2215
2221
  telephone?(new_text_variable.value)
@@ -2217,7 +2223,7 @@ class HelloEntry
2217
2223
 
2218
2224
  ## this event kicks in just after the text variable is validated and before it is modified
2219
2225
  on('invalid') do |validate_args|
2220
- @validated_entry_label.text = "#{validate_args.string} is not valid!"
2226
+ @validated_entry_label.text = "#{validate_args.value} is not a valid phone!"
2221
2227
  @validated_entry_label.foreground = 'red'
2222
2228
  end
2223
2229
 
@@ -2227,6 +2233,13 @@ class HelloEntry
2227
2233
  @validated_entry_label.text = 'entry with event handlers'
2228
2234
  @validated_entry_label.foreground = nil
2229
2235
  end
2236
+
2237
+ ## this is similar to on('change') (which is Glimmer-specific), but more low level at the Tk level
2238
+ ## it is the equivalent of calling: the_entry.tk.textvariable.trace('write') { puts "..." }
2239
+ ## More at: https://tkdocs.com/tutorial/widgets.html#entry and https://tcl.tk/man/tcl8.6/TclCmd/trace.htm#M14
2240
+ on_textvariable('write') do
2241
+ puts "\"#{the_entry.text}\" has been written to entry!"
2242
+ end
2230
2243
  }
2231
2244
 
2232
2245
  label {
@@ -4274,9 +4287,9 @@ https://github.com/ancorgs/y3network-ruby-ui
4274
4287
 
4275
4288
  This is a Graphical User Interface for the famous [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
4276
4289
 
4277
- https://github.com/cryptopunksnotdead/cryptopunks-gui
4290
+ https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks-gui
4278
4291
 
4279
- ![CryptoPunks GUI Screenshot](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks-gui/master/screenshots/cryptopunks-gui-screenshot.png)
4292
+ ![CryptoPunks GUI Screenshot](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/cryptopunks-gui/screenshots/cryptopunks-gui-screenshot.png)
4280
4293
 
4281
4294
  ### Circule
4282
4295
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.57
1
+ 0.0.60
Binary file
@@ -37,6 +37,7 @@ module Glimmer
37
37
  Tk,
38
38
  %w[
39
39
  list_selection_data_binding
40
+ variable_listener
40
41
  data_binding
41
42
  attribute
42
43
  shine_data_binding
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2020-2022 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/dsl/expression'
23
+ require 'glimmer/tk/widget_proxy'
24
+
25
+ module Glimmer
26
+ module DSL
27
+ module Tk
28
+ class VariableListenerExpression < Expression
29
+ def can_interpret?(parent, keyword, *args, &block)
30
+ parent.is_a?(Glimmer::Tk::WidgetProxy) && keyword.match(/^on_.*/) && textual?(args.first)
31
+ end
32
+
33
+ def interpret(parent, keyword, *args, &block)
34
+ variable_name = keyword.sub(/^on_/, '')
35
+ operation = args.first.to_s
36
+ parent.tk.send(variable_name).trace(operation, &block)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -31,13 +31,24 @@ module Glimmer
31
31
  include TextVariableOwner
32
32
 
33
33
  def validatecommand_block=(proc)
34
+ self.validate = 'key' unless validate
34
35
  tk.validatecommand(proc)
35
36
  end
36
37
 
37
38
  def invalidcommand_block=(proc)
39
+ self.validate = 'key' unless validate
38
40
  tk.invalidcommand(proc)
39
41
  end
40
42
 
43
+ def validate
44
+ @validate
45
+ end
46
+
47
+ def validate=(value)
48
+ @validate = value
49
+ @tk.validate(value)
50
+ end
51
+
41
52
  def handle_listener(listener_name, &listener)
42
53
  case listener_name.to_s.downcase
43
54
  when 'change', 'changed', 'modified'
@@ -192,6 +192,7 @@ module Glimmer
192
192
 
193
193
  def set_attribute(attribute, *args)
194
194
  begin
195
+ args = normalize_attribute_arguments(attribute, args)
195
196
  widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
196
197
  if respond_to?(attribute_setter(attribute), super_only: true)
197
198
  send(attribute_setter(attribute), *args)
@@ -308,6 +309,30 @@ module Glimmer
308
309
  @tk.style = style
309
310
  end
310
311
 
312
+ def normalize_attribute_arguments(attribute, args)
313
+ attribute_argument_normalizers[attribute]&.call(args) || args
314
+ end
315
+
316
+ def attribute_argument_normalizers
317
+ color_normalizer = lambda do |args|
318
+ if args.size > 1 || args.first.is_a?(Numeric)
319
+ rgb = args
320
+ rgb = rgb.map(&:to_s).map(&:to_i)
321
+ rgb = 3.times.map { |n| rgb[n] || 0}
322
+ hex = rgb.map { |color| color.to_s(16).ljust(2, '0') }.join
323
+ ["##{hex}"]
324
+ elsif args.size == 1 && args.first.is_a?(String) && !args.first.start_with?('#')
325
+ ["##{args.first}"]
326
+ else
327
+ args
328
+ end
329
+ end
330
+ @attribute_argument_normalizers ||= {
331
+ 'background' => color_normalizer,
332
+ 'foreground' => color_normalizer,
333
+ }
334
+ end
335
+
311
336
  def widget_custom_attribute_mapping
312
337
  # TODO consider extracting to modules/subclasses
313
338
  @widget_custom_attribute_mapping ||= {
@@ -534,10 +559,12 @@ module Glimmer
534
559
 
535
560
  def method_missing(method, *args, &block)
536
561
  method = method.to_s
562
+ attribute_name = method.sub(/=$/, '')
563
+ args = normalize_attribute_arguments(attribute_name, args)
537
564
  if args.empty? && block.nil? && ((widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method]) || has_state?(method) || has_attributes_attribute?(method))
538
565
  get_attribute(method)
539
566
  elsif method.end_with?('=') && block.nil? && ((widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method.sub(/=$/, '')]) || has_state?(method) || has_attributes_attribute?(method))
540
- set_attribute(method.sub(/=$/, ''), *args)
567
+ set_attribute(attribute_name, *args)
541
568
  else
542
569
  tk.send(method, *args, &block)
543
570
  end
@@ -31,21 +31,47 @@ root { |w|
31
31
  y 150
32
32
 
33
33
  frame {
34
- %w[get_open_file get_multiple_open_file get_save_file choose_directory choose_color].each do |dialog|
34
+ %w[get_open_file get_multiple_open_file get_save_file choose_directory].each do |dialog|
35
+ dialog_name = dialog.split('_').map(&:capitalize).join(' ')
35
36
  button {
36
- text dialog.split('_').map(&:capitalize).join(' ')
37
+ text dialog_name
37
38
 
38
39
  on('command') do
39
- result = send(dialog, parent: w)
40
+ # parent is optional.
41
+ # It is recommended to set parent to display dialog on top of.
42
+ #
43
+ # title is optional (defaults to blank).
44
+ # It is not supported by choose_directory (its title is always blank).
45
+ result = send(dialog, parent: w, title: dialog_name)
46
+ # Uniformly handle both a singular result (e.g. from get_open_file)
47
+ # and an array of results (e.g. from get_multiple_open_file)
40
48
  @result_label.text = [result].flatten.join("\n")
41
49
  end
42
50
  }
43
51
  end
44
52
 
53
+ button {
54
+ text 'Choose Color'
55
+
56
+ on('command') do
57
+ # parent is optional.
58
+ # It is recommended to set parent to display dialog on top of.
59
+ #
60
+ # title is optional (defaults to 'Colors').
61
+ #
62
+ # initialcolor is optional (defaults to 'white').
63
+ # It can be a built-in color (e.g. 'AliceBlue') or hex (e.g. '#FFFF00')
64
+ # Full list of built-in colors is at: https://tcl.tk/man/tcl8.6/TkCmd/colors.htm
65
+ chosen_color = choose_color(parent: w, title: 'Choose Color', initialcolor: '#FFFF00')
66
+ @result_label.text = chosen_color
67
+ end
68
+ }
69
+
45
70
  button {
46
71
  text 'Choose Font'
47
72
 
48
73
  on('command') do
74
+ # Initial family, size, and weight are optional.
49
75
  choose_font(family: 'Courier New', size: '30', weight: 'bold') do |chosen_font|
50
76
  @result_label.text = chosen_font
51
77
  end
@@ -36,12 +36,13 @@ class HelloEntry
36
36
  def launch
37
37
  root {
38
38
  title 'Hello, Entry!'
39
-
39
+ minsize 230, 0
40
+
40
41
  label {
41
42
  grid sticky: 'ew'
42
43
  text 'default entry'
43
44
  }
44
- entry {
45
+ entry { |the_entry|
45
46
  grid sticky: 'ew'
46
47
  text <=> [self, :default]
47
48
  }
@@ -60,11 +61,14 @@ class HelloEntry
60
61
  grid sticky: 'ew'
61
62
  text 'entry with event handlers'
62
63
  }
63
- entry {
64
+ entry { |the_entry|
64
65
  grid sticky: 'ew'
65
66
  text <=> [self, :telephone]
66
- validate 'key'
67
67
 
68
+ # validate 'key' # default when on('validate') or on('invalid') is specified
69
+ ## Validation happens on key change by default when validation listeners are specified
70
+ ## (other accepted values: 'none', 'focus', 'focusin', 'focusout', 'key', or 'all')
71
+
68
72
  ## this event kicks in just after the user typed and before modifying the text variable
69
73
  on('validate') do |new_text_variable|
70
74
  telephone?(new_text_variable.value)
@@ -72,7 +76,7 @@ class HelloEntry
72
76
 
73
77
  ## this event kicks in just after the text variable is validated and before it is modified
74
78
  on('invalid') do |validate_args|
75
- @validated_entry_label.text = "#{validate_args.value} is not valid!"
79
+ @validated_entry_label.text = "#{validate_args.value} is not a valid phone!"
76
80
  @validated_entry_label.foreground = 'red'
77
81
  end
78
82
 
@@ -82,6 +86,13 @@ class HelloEntry
82
86
  @validated_entry_label.text = 'entry with event handlers'
83
87
  @validated_entry_label.foreground = nil
84
88
  end
89
+
90
+ ## this is similar to on('change') (which is Glimmer-specific), but more low level at the Tk level
91
+ ## it is the equivalent of calling: the_entry.tk.textvariable.trace('write') { puts "..." }
92
+ ## More at: https://tkdocs.com/tutorial/widgets.html#entry and https://tcl.tk/man/tcl8.6/TclCmd/trace.htm#M14
93
+ on_textvariable('write') do
94
+ puts "\"#{the_entry.text}\" has been written to entry!"
95
+ end
85
96
  }
86
97
 
87
98
  label {
@@ -80,8 +80,13 @@ class HelloLabel
80
80
  anchor 'center'
81
81
  justify 'center' # other options are: 'left' and 'right'
82
82
  font 'caption' # other options are: 'default', 'text', 'fixed', 'menu', 'heading', 'small_caption', 'icon', 'tooltip'
83
- foreground 'blue'
84
83
  relief 'sunken' # other options are: 'flat' (default), 'raised', 'solid', 'ridge', 'groove'
84
+ foreground 38, 20, 138 # RGB (Red Green Blue) color
85
+
86
+ # Other supported color arguments:
87
+ # foreground 'blue' # built-in color alternative from https://tcl.tk/man/tcl8.6/TkCmd/colors.htm
88
+ # foreground '#ff0000' # hex color
89
+ # foreground 'ff0000' # hex color missing the # prefix
85
90
  }
86
91
  }
87
92
 
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.57
4
+ version: 0.0.60
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-28 00:00:00.000000000 Z
11
+ date: 2022-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -170,8 +170,8 @@ dependencies:
170
170
  - - "~>"
171
171
  - !ruby/object:Gem::Version
172
172
  version: 0.7.0
173
- description: Glimmer DSL for Tk (MRI Ruby Desktop Development GUI Library) - Ruby
174
- DSL for Tcl/Tk with bidirectional/unidirectional data-binding support.
173
+ description: Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library) - Ruby DSL
174
+ for Tcl/Tk with bidirectional/unidirectional data-binding support.
175
175
  email: andy.am@gmail.com
176
176
  executables:
177
177
  - girb
@@ -205,6 +205,7 @@ files:
205
205
  - lib/glimmer/dsl/tk/on_expression.rb
206
206
  - lib/glimmer/dsl/tk/root_expression.rb
207
207
  - lib/glimmer/dsl/tk/shine_data_binding_expression.rb
208
+ - lib/glimmer/dsl/tk/variable_listener_expression.rb
208
209
  - lib/glimmer/dsl/tk/widget_expression.rb
209
210
  - lib/glimmer/tk/checkbutton_proxy.rb
210
211
  - lib/glimmer/tk/combobox_proxy.rb