glimmer-dsl-tk 0.0.24 → 0.0.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +141 -3
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/format_expression.rb +39 -0
- data/lib/glimmer/dsl/tk/root_expression.rb +1 -1
- data/lib/glimmer/tk/frame_proxy.rb +8 -0
- data/lib/glimmer/tk/radiobutton_proxy.rb +1 -1
- data/lib/glimmer/tk/root_proxy.rb +7 -1
- data/lib/glimmer/tk/spinbox_proxy.rb +52 -0
- data/lib/glimmer/tk/text_proxy.rb +71 -0
- data/lib/glimmer/tk/widget_proxy.rb +26 -3
- data/samples/elaborate/meta_sample.rb +138 -0
- data/samples/hello/hello_checkbutton.rb +0 -1
- data/samples/hello/hello_radiobutton.rb +21 -1
- data/samples/hello/hello_spinbox.rb +75 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c940ac2487be1d7d3088f773bd34aa32f089fa58867ccdcb241886a36cc4327
|
4
|
+
data.tar.gz: 814497bd3fda9e8b11b7388b4c7d35f0fc6ee966ed0d6e0e7ac010151eac3ca6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78c56736b536e3e284b417840f96ed0bcf8598dec29e0e09ba9a5174dce2797e1973ae1039b4715658361bf4db9b37f1862040c3e84ae9d3d4df7252f4e77ae8
|
7
|
+
data.tar.gz: ca7968598a8281c48304899c4fd6bfc48e8f4647592cb41d3e6b657027f675ce974e7222dd34d7b6b0fa9caad94fc1d3f216161042d182a20c8f61f7a91f9482
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.25
|
4
|
+
|
5
|
+
- Elaborate, Meta-Sample
|
6
|
+
- Hello, Spinbox!
|
7
|
+
- Support `spinbox` `command {}` and `on('increment') {}` / `on('decrement') {}`
|
8
|
+
- Support `spinbox` `format` attribute (e.g. `format '%0.2f'`
|
9
|
+
- Make `grid sticky: 'nsew', column_weight: 1` the default for all widgets (column weight is only applied to the first widget in a series of siblings)
|
10
|
+
- Support `text` widget with `text` attribute/data-binding just like `entry`
|
11
|
+
- Set `background '#ececec' if OS.mac?` on `root` by default
|
12
|
+
- Support `'modified'`/`'selected'` event bindings for `text` widget
|
13
|
+
|
3
14
|
## 0.0.24
|
4
15
|
|
5
16
|
- Hello, Entry!
|
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.
|
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.25
|
2
2
|
## MRI Ruby 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)
|
@@ -82,12 +82,14 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
82
82
|
- [Notebook Frame](#notebook-frame)
|
83
83
|
- [Icon Photo](#icon-photo)
|
84
84
|
- [The Grid Geometry Manager](#the-grid-geometry-manager)
|
85
|
-
- [
|
85
|
+
- [Data-Binding](#data-binding)
|
86
86
|
- [Label Data-Binding](#label-data-binding)
|
87
87
|
- [Combobox Data-Binding](#combobox-data-binding)
|
88
88
|
- [List Single Selection Data-Binding](#list-single-selection-data-binding)
|
89
89
|
- [List Multi Selection Data-Binding](#list-multi-selection-data-binding)
|
90
90
|
- [Entry Data-Binding](#entry-data-binding)
|
91
|
+
- [Spinbox Data-Binding](#spinbox-data-binding)
|
92
|
+
- [Text Data-Binding](#text-data-binding)
|
91
93
|
- [Checkbutton Data-Binding](#checkbutton-data-binding)
|
92
94
|
- [Radiobutton Data-Binding](#radiobutton-data-binding)
|
93
95
|
- [Command Callback](#command-callback)
|
@@ -106,6 +108,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
106
108
|
- [Hello, List Single Selection!](#hello-list-single-selection)
|
107
109
|
- [Hello, List Multi Selection!](#hello-list-multi-selection)
|
108
110
|
- [Hello, Entry!](#hello-entry)
|
111
|
+
- [Hello, Spinbox!](#hello-spinbox)
|
109
112
|
- [Hello, Computed!](#hello-computed)
|
110
113
|
- [Help](#help)
|
111
114
|
- [Issues](#issues)
|
@@ -143,7 +146,7 @@ gem install glimmer-dsl-tk
|
|
143
146
|
|
144
147
|
Add the following to `Gemfile`:
|
145
148
|
```
|
146
|
-
gem 'glimmer-dsl-tk', '~> 0.0.
|
149
|
+
gem 'glimmer-dsl-tk', '~> 0.0.25'
|
147
150
|
```
|
148
151
|
|
149
152
|
And, then run:
|
@@ -256,6 +259,7 @@ keyword(args) | attributes | event bindings & callbacks
|
|
256
259
|
`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 {}`
|
257
260
|
`combobox` | `state`, `text` | `'ComboboxSelected'`
|
258
261
|
`entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'`, `validatecommand {}`, `invalidcommand {}`
|
262
|
+
`spinbox` | `text`, `from`, `to`, `increment`, `format`, [more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `command {}`, `'increment'`, `'decrement'`
|
259
263
|
`frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
|
260
264
|
`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
|
261
265
|
`list` | `selectmode`, `selection` | None
|
@@ -263,6 +267,7 @@ keyword(args) | attributes | event bindings & callbacks
|
|
263
267
|
`notebook` | None | None
|
264
268
|
`radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
|
265
269
|
`root` | `title`, `iconphoto`, `background`, `alpha`, `fullscreen?`, `topmost?`, `transparent?`, `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`, `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`) | `'DELETE_WINDOW'`, `'OPEN_WINDOW'`
|
270
|
+
`text` | `text`, [many more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `'modified'`, `'selection'`
|
266
271
|
|
267
272
|
#### Common Attributes
|
268
273
|
|
@@ -477,6 +482,46 @@ It automatically handles all the Tk plumbing behind the scenes.
|
|
477
482
|
|
478
483
|
More details can be found in [Hello, Entry!](#hello-entry) and [Hello, Computed!](#hello-computed) samples below.
|
479
484
|
|
485
|
+
### Spinbox Data-Binding
|
486
|
+
|
487
|
+
Example:
|
488
|
+
|
489
|
+
This assumes a `Person` model with a `donation` attribute.
|
490
|
+
|
491
|
+
```ruby
|
492
|
+
spinbox {
|
493
|
+
from 1.0 # minimum value
|
494
|
+
to 150.0 # maximum value
|
495
|
+
increment 5.0 # increment on up and down
|
496
|
+
format '%0.2f'
|
497
|
+
text <=> [person, :country]
|
498
|
+
}
|
499
|
+
```
|
500
|
+
|
501
|
+
That code binds the `textvariable` value of the `spinbox` to the `donation` attribute on the `person` model.
|
502
|
+
|
503
|
+
It automatically handles all the Tk plumbing behind the scenes.
|
504
|
+
|
505
|
+
More details can be found in [Hello, Spinbox!](#hello-spinbox) sample below.
|
506
|
+
|
507
|
+
### Text Data-Binding
|
508
|
+
|
509
|
+
Example:
|
510
|
+
|
511
|
+
This assumes a `Person` model with a `address` attribute.
|
512
|
+
|
513
|
+
```ruby
|
514
|
+
text {
|
515
|
+
text <=> [person, :address]
|
516
|
+
}
|
517
|
+
```
|
518
|
+
|
519
|
+
That code binds the text content of `text` to the `address` attribute on the `person` model.
|
520
|
+
|
521
|
+
It automatically handles all the Tk plumbing behind the scenes (including fine-grained inserts and deletes, abstracting them all away).
|
522
|
+
|
523
|
+
More details can be found in [Glimmer Meta-Sample](#samples) below.
|
524
|
+
|
480
525
|
### Checkbutton Data-Binding
|
481
526
|
|
482
527
|
Example:
|
@@ -547,6 +592,22 @@ More details can be found in the [Hello, Button!](#hello-button) sample below.
|
|
547
592
|
|
548
593
|
## Samples
|
549
594
|
|
595
|
+
The easiest way to run samples is by launching the Glimmer Meta-Sample (the Sample of Samples).
|
596
|
+
|
597
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
598
|
+
|
599
|
+
```
|
600
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/elaborate/meta_sample'"
|
601
|
+
```
|
602
|
+
|
603
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
604
|
+
|
605
|
+
```
|
606
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/elaborate/meta_sample.rb
|
607
|
+
```
|
608
|
+
|
609
|
+
![glimmer dsl tk screenshot sample meta sample](images/glimmer-dsl-tk-screenshot-sample-elaborate-meta-sample.png)
|
610
|
+
|
550
611
|
### Hello, World!
|
551
612
|
|
552
613
|
Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
|
@@ -1625,6 +1686,83 @@ Glimmer app:
|
|
1625
1686
|
![glimmer dsl tk screenshot sample hello entry](images/glimmer-dsl-tk-screenshot-sample-hello-entry.png)
|
1626
1687
|
![glimmer dsl tk screenshot sample hello entry validated](images/glimmer-dsl-tk-screenshot-sample-hello-entry-validated.png)
|
1627
1688
|
|
1689
|
+
### Hello, Spinbox!
|
1690
|
+
|
1691
|
+
Glimmer code (from [samples/hello/hello_spinbox.rb](samples/hello/hello_spinbox.rb)):
|
1692
|
+
|
1693
|
+
```ruby
|
1694
|
+
require 'glimmer-dsl-tk'
|
1695
|
+
|
1696
|
+
class HelloSpinbox
|
1697
|
+
class Person
|
1698
|
+
attr_accessor :donation
|
1699
|
+
end
|
1700
|
+
|
1701
|
+
include Glimmer
|
1702
|
+
|
1703
|
+
def initialize
|
1704
|
+
@person = Person.new
|
1705
|
+
@person.donation = 5.0 # in dollars
|
1706
|
+
end
|
1707
|
+
|
1708
|
+
def launch
|
1709
|
+
root {
|
1710
|
+
title 'Hello, Spinbox!'
|
1711
|
+
|
1712
|
+
label {
|
1713
|
+
text 'Please select the amount you would like to donate to the poor:'
|
1714
|
+
}
|
1715
|
+
|
1716
|
+
frame {
|
1717
|
+
label {
|
1718
|
+
grid row: 0, column: 0
|
1719
|
+
text 'Amount:'
|
1720
|
+
font 'caption'
|
1721
|
+
}
|
1722
|
+
|
1723
|
+
label {
|
1724
|
+
grid row: 0, column: 1
|
1725
|
+
text '$'
|
1726
|
+
}
|
1727
|
+
|
1728
|
+
spinbox { |sb|
|
1729
|
+
grid row: 0, column: 2
|
1730
|
+
from 1.0 # minimum value
|
1731
|
+
to 150.0 # maximum value
|
1732
|
+
increment 5.0 # increment on up and down
|
1733
|
+
format '%0.2f'
|
1734
|
+
text <=> [@person, :donation]
|
1735
|
+
}
|
1736
|
+
|
1737
|
+
label {
|
1738
|
+
grid row: 1, column: 0, columnspan: 3
|
1739
|
+
text <=> [@person, :donation, on_read: ->(value) { "Thank you for your donation of $#{"%.2f" % value.to_f}"}]
|
1740
|
+
}
|
1741
|
+
|
1742
|
+
}
|
1743
|
+
}.open
|
1744
|
+
end
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
HelloSpinbox.new.launch
|
1748
|
+
```
|
1749
|
+
|
1750
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1751
|
+
|
1752
|
+
```
|
1753
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_spinbox'"
|
1754
|
+
```
|
1755
|
+
|
1756
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
1757
|
+
|
1758
|
+
```
|
1759
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_spinbox.rb
|
1760
|
+
```
|
1761
|
+
|
1762
|
+
Glimmer app:
|
1763
|
+
|
1764
|
+
![glimmer dsl tk screenshot sample hello spinbox](images/glimmer-dsl-tk-screenshot-sample-hello-spinbox.png)
|
1765
|
+
|
1628
1766
|
### Hello, Computed!
|
1629
1767
|
|
1630
1768
|
Glimmer code (from [samples/hello/hello_computed.rb](samples/hello/hello_computed.rb)):
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.25
|
data/glimmer-dsl-tk.gemspec
CHANGED
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright (c) 2021 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/static_expression'
|
23
|
+
require 'glimmer/tk/spinbox_proxy'
|
24
|
+
|
25
|
+
module Glimmer
|
26
|
+
module DSL
|
27
|
+
module Tk
|
28
|
+
class FormatExpression < StaticExpression
|
29
|
+
def can_interpret?(parent, keyword, *args, &block)
|
30
|
+
super && parent.is_a?(Glimmer::Tk::SpinboxProxy) && args.size == 1 && block.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
def interpret(parent, keyword, *args, &block)
|
34
|
+
parent.tk.format(*args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -20,6 +20,7 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'glimmer/tk/widget_proxy'
|
23
|
+
require 'glimmer/tk/notebook_proxy'
|
23
24
|
|
24
25
|
module Glimmer
|
25
26
|
module Tk
|
@@ -38,6 +39,13 @@ module Glimmer
|
|
38
39
|
end
|
39
40
|
super
|
40
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def initialize_defaults
|
46
|
+
super unless @parent_proxy.is_a?(NotebookProxy)
|
47
|
+
self.padding = 15
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
@@ -31,9 +31,11 @@ module Glimmer
|
|
31
31
|
DEFAULT_WIDTH = 190
|
32
32
|
DEFAULT_HEIGHT = 95
|
33
33
|
|
34
|
-
def initialize(*args)
|
34
|
+
def initialize(*args, &block)
|
35
35
|
@tk = ::TkRoot.new
|
36
36
|
@tk.minsize = DEFAULT_WIDTH, DEFAULT_HEIGHT
|
37
|
+
initialize_defaults
|
38
|
+
post_add_content if block.nil?
|
37
39
|
end
|
38
40
|
|
39
41
|
def post_add_content
|
@@ -176,6 +178,10 @@ module Glimmer
|
|
176
178
|
def geometry_signs
|
177
179
|
geometry.chars.select {|char| char.match(/[+-]/)}
|
178
180
|
end
|
181
|
+
|
182
|
+
def initialize_defaults
|
183
|
+
self.background = '#ececec' if OS.mac?
|
184
|
+
end
|
179
185
|
end
|
180
186
|
end
|
181
187
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright (c) 2020-2021 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
|
+
require 'glimmer/tk/text_variable_owner'
|
24
|
+
|
25
|
+
module Glimmer
|
26
|
+
module Tk
|
27
|
+
# Proxy for Tk::Tile::TSpinbox
|
28
|
+
#
|
29
|
+
# Follows the Proxy Design Pattern
|
30
|
+
class SpinboxProxy < WidgetProxy
|
31
|
+
include TextVariableOwner
|
32
|
+
|
33
|
+
def command_block=(proc)
|
34
|
+
tk.command(proc)
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle_listener(listener_name, &listener)
|
38
|
+
case listener_name.to_s.downcase
|
39
|
+
when 'command', 'change'
|
40
|
+
command(&listener)
|
41
|
+
when 'increment', '<increment>', '<<increment>>'
|
42
|
+
bind('<Increment>', listener)
|
43
|
+
when 'decrement', '<decrement>', '<<decrement>>'
|
44
|
+
bind('<Decrement>', listener)
|
45
|
+
else
|
46
|
+
super
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Copyright (c) 2020-2021 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::Text
|
27
|
+
#
|
28
|
+
# Follows the Proxy Design Pattern
|
29
|
+
class TextProxy < WidgetProxy
|
30
|
+
def handle_listener(listener_name, &listener)
|
31
|
+
listener_name = listener_name.to_s.downcase
|
32
|
+
case listener_name
|
33
|
+
when '<<modified>>', '<modified>', 'modified'
|
34
|
+
modified_listener = Proc.new do |*args|
|
35
|
+
listener.call(*args)
|
36
|
+
@tk.modified = false
|
37
|
+
end
|
38
|
+
bind('<Modified>', modified_listener)
|
39
|
+
when '<<selection>>', '<selection>', 'selection'
|
40
|
+
bind('<Selection>', listener)
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def text=(value)
|
47
|
+
if value != @text
|
48
|
+
@text = value
|
49
|
+
delete('1.0', 'end')
|
50
|
+
insert('end', value)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def text(value = nil)
|
55
|
+
if value.nil?
|
56
|
+
@text = get("1.0", 'end')
|
57
|
+
else
|
58
|
+
self.text = value
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def initialize_defaults
|
65
|
+
super
|
66
|
+
self.padx = 5
|
67
|
+
self.pady = 5
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -74,8 +74,8 @@ module Glimmer
|
|
74
74
|
tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name)
|
75
75
|
@tk = tk_widget_class.new(@parent_proxy.tk, *args)
|
76
76
|
# a common widget initializer
|
77
|
-
initialize_defaults
|
78
77
|
@parent_proxy.post_initialize_child(self)
|
78
|
+
initialize_defaults
|
79
79
|
post_add_content if @block.nil?
|
80
80
|
end
|
81
81
|
|
@@ -276,6 +276,12 @@ module Glimmer
|
|
276
276
|
setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
|
277
277
|
},
|
278
278
|
},
|
279
|
+
::Tk::Tile::TSpinbox => {
|
280
|
+
'text' => {
|
281
|
+
getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
|
282
|
+
setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
|
283
|
+
},
|
284
|
+
},
|
279
285
|
::Tk::Root => {
|
280
286
|
'text' => {
|
281
287
|
getter: {name: 'text', invoker: lambda { |widget, args| @tk.title }},
|
@@ -309,11 +315,25 @@ module Glimmer
|
|
309
315
|
},
|
310
316
|
::Tk::Tile::TEntry => {
|
311
317
|
'text' => lambda do |observer|
|
312
|
-
tk.textvariable.trace('write') {
|
318
|
+
@tk.textvariable.trace('write') {
|
313
319
|
observer.call(@tk.textvariable.value)
|
314
320
|
}
|
315
321
|
end,
|
316
322
|
},
|
323
|
+
::Tk::Tile::TSpinbox => {
|
324
|
+
'text' => lambda do |observer|
|
325
|
+
@tk.command {
|
326
|
+
observer.call(@tk.textvariable&.value)
|
327
|
+
}
|
328
|
+
end,
|
329
|
+
},
|
330
|
+
::Tk::Text => {
|
331
|
+
'text' => lambda do |observer|
|
332
|
+
handle_listener('modified') do
|
333
|
+
observer.call(text)
|
334
|
+
end
|
335
|
+
end,
|
336
|
+
},
|
317
337
|
::Tk::Tile::TRadiobutton => {
|
318
338
|
'variable' => lambda do |observer|
|
319
339
|
@tk.command {
|
@@ -384,7 +404,10 @@ module Glimmer
|
|
384
404
|
private
|
385
405
|
|
386
406
|
def initialize_defaults
|
387
|
-
|
407
|
+
options = {}
|
408
|
+
options[:sticky] = 'nsew'
|
409
|
+
options[:column_weight] = 1 if @parent_proxy.children.count == 1
|
410
|
+
grid(options) unless @tk.is_a?(::Tk::Toplevel)
|
388
411
|
end
|
389
412
|
end
|
390
413
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# Copyright (c) 2020-2021 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-tk'
|
23
|
+
require 'facets'
|
24
|
+
require 'fileutils'
|
25
|
+
|
26
|
+
class MetaSample
|
27
|
+
include Glimmer
|
28
|
+
|
29
|
+
attr_accessor :selected_sample_index
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@selected_sample_index = 0
|
33
|
+
end
|
34
|
+
|
35
|
+
def samples
|
36
|
+
if @samples.nil?
|
37
|
+
sample_files = Dir.glob(File.join(File.expand_path('../hello', __dir__), '**', 'hello_*.rb'))
|
38
|
+
sample_file_names = sample_files.map { |f| File.basename(f, '.rb') }
|
39
|
+
sample_file_names = sample_file_names.reject { |f| f == 'meta_sample' || f.match(/\d$/) }
|
40
|
+
@samples = sample_file_names.map { |f| f.underscore.titlecase }
|
41
|
+
end
|
42
|
+
@samples
|
43
|
+
end
|
44
|
+
|
45
|
+
def file_path_for(sample)
|
46
|
+
File.join(File.expand_path('../hello', __dir__), "#{sample.underscore}.rb")
|
47
|
+
end
|
48
|
+
|
49
|
+
def glimmer_dsl_tk_file
|
50
|
+
File.expand_path('../../lib/glimmer-dsl-tk', __dir__)
|
51
|
+
end
|
52
|
+
|
53
|
+
def selected_sample
|
54
|
+
samples[@selected_sample_index]
|
55
|
+
end
|
56
|
+
|
57
|
+
def run_sample(sample)
|
58
|
+
Thread.new do
|
59
|
+
command = "ruby -r #{glimmer_dsl_tk_file} #{sample} 2>&1"
|
60
|
+
result = ''
|
61
|
+
IO.popen(command) do |f|
|
62
|
+
f.each_line do |line|
|
63
|
+
result << line
|
64
|
+
puts line
|
65
|
+
$stdout.flush
|
66
|
+
end
|
67
|
+
end
|
68
|
+
::Tk.after(100) do
|
69
|
+
message_box(parent: @root, title: 'Error Running Sample', message: result) if result.downcase.include?('error')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def launch
|
75
|
+
@root = root {
|
76
|
+
title 'Glimmer Meta-Sample'
|
77
|
+
width 700
|
78
|
+
height 500
|
79
|
+
|
80
|
+
frame {
|
81
|
+
grid row: 0, column: 0, column_weight: 0, row_weight: 1
|
82
|
+
|
83
|
+
samples.each_with_index do |sample, index|
|
84
|
+
radiobutton {
|
85
|
+
text sample
|
86
|
+
variable <=> [self, :selected_sample_index, on_write: ->(v) {v ? index : selected_sample_index}, on_read: ->(v) {v == index}]
|
87
|
+
|
88
|
+
on('command') do
|
89
|
+
@selected_sample_index = index
|
90
|
+
@code_text.text = File.read(file_path_for(selected_sample))
|
91
|
+
end
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
95
|
+
frame {
|
96
|
+
button {
|
97
|
+
grid row: 0, column: 0
|
98
|
+
text 'Launch'
|
99
|
+
|
100
|
+
on('command') do
|
101
|
+
begin
|
102
|
+
parent_dir = File.join(Dir.home, '.glimmer-dsl-tk', 'samples', 'hello')
|
103
|
+
FileUtils.mkdir_p(parent_dir)
|
104
|
+
sample_file = File.join(parent_dir, "#{selected_sample.underscore}.rb")
|
105
|
+
File.write(sample_file, @code_text.text)
|
106
|
+
FileUtils.cp_r(File.expand_path('../../icons', __dir__), File.dirname(File.dirname(parent_dir)))
|
107
|
+
FileUtils.cp_r(File.expand_path('../hello/images', __dir__), parent_dir)
|
108
|
+
sample_namespace_directory = File.expand_path("../hello/#{selected_sample.underscore}", __dir__)
|
109
|
+
FileUtils.cp_r(sample_namespace_directory, parent_dir) if Dir.exist?(sample_namespace_directory)
|
110
|
+
run_sample(sample_file)
|
111
|
+
rescue => e
|
112
|
+
puts e.full_message
|
113
|
+
puts 'Unable to write code changes! Running original sample...'
|
114
|
+
run_sample(file_path_for(selected_sample))
|
115
|
+
end
|
116
|
+
end
|
117
|
+
}
|
118
|
+
button {
|
119
|
+
grid row: 0, column: 1
|
120
|
+
text 'Reset'
|
121
|
+
|
122
|
+
on('command') do
|
123
|
+
@code_text.text = File.read(file_path_for(selected_sample))
|
124
|
+
end
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
@code_text = text {
|
130
|
+
grid row: 0, column: 1, column_weight: 1
|
131
|
+
text File.read(file_path_for(selected_sample))
|
132
|
+
}
|
133
|
+
}
|
134
|
+
@root.open
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
MetaSample.new.launch
|
@@ -1,3 +1,24 @@
|
|
1
|
+
# Copyright (c) 2020-2021 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
|
+
|
1
22
|
require 'glimmer-dsl-tk'
|
2
23
|
|
3
24
|
class HelloRadiobutton
|
@@ -27,7 +48,6 @@ class HelloRadiobutton
|
|
27
48
|
def launch
|
28
49
|
root {
|
29
50
|
title 'Hello, Radio!'
|
30
|
-
background '#ececec' if OS.mac?
|
31
51
|
|
32
52
|
label {
|
33
53
|
text 'Gender:'
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright (c) 2020-2021 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-tk'
|
23
|
+
|
24
|
+
class HelloSpinbox
|
25
|
+
class Person
|
26
|
+
attr_accessor :donation
|
27
|
+
end
|
28
|
+
|
29
|
+
include Glimmer
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@person = Person.new
|
33
|
+
@person.donation = 5.0 # in dollars
|
34
|
+
end
|
35
|
+
|
36
|
+
def launch
|
37
|
+
root {
|
38
|
+
title 'Hello, Spinbox!'
|
39
|
+
|
40
|
+
label {
|
41
|
+
text 'Please select the amount you would like to donate to the poor:'
|
42
|
+
}
|
43
|
+
|
44
|
+
frame {
|
45
|
+
label {
|
46
|
+
grid row: 0, column: 0
|
47
|
+
text 'Amount:'
|
48
|
+
font 'caption'
|
49
|
+
}
|
50
|
+
|
51
|
+
label {
|
52
|
+
grid row: 0, column: 1
|
53
|
+
text '$'
|
54
|
+
}
|
55
|
+
|
56
|
+
spinbox {
|
57
|
+
grid row: 0, column: 2
|
58
|
+
from 1.0 # minimum value
|
59
|
+
to 150.0 # maximum value
|
60
|
+
increment 5.0 # increment on up and down
|
61
|
+
format '%0.2f'
|
62
|
+
text <=> [@person, :donation]
|
63
|
+
}
|
64
|
+
|
65
|
+
label {
|
66
|
+
grid row: 1, column: 0, columnspan: 3
|
67
|
+
text <=> [@person, :donation, on_read: ->(value) { "Thank you for your donation of $#{"%.2f" % value.to_f}"}]
|
68
|
+
}
|
69
|
+
|
70
|
+
}
|
71
|
+
}.open
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
HelloSpinbox.new.launch
|
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
|
+
version: 0.0.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-10-
|
11
|
+
date: 2021-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -217,6 +217,7 @@ files:
|
|
217
217
|
- lib/glimmer/dsl/tk/block_attribute_expression.rb
|
218
218
|
- lib/glimmer/dsl/tk/data_binding_expression.rb
|
219
219
|
- lib/glimmer/dsl/tk/dsl.rb
|
220
|
+
- lib/glimmer/dsl/tk/format_expression.rb
|
220
221
|
- lib/glimmer/dsl/tk/list_selection_data_binding_expression.rb
|
221
222
|
- lib/glimmer/dsl/tk/message_box_expression.rb
|
222
223
|
- lib/glimmer/dsl/tk/on_expression.rb
|
@@ -234,10 +235,13 @@ files:
|
|
234
235
|
- lib/glimmer/tk/notebook_proxy.rb
|
235
236
|
- lib/glimmer/tk/radiobutton_proxy.rb
|
236
237
|
- lib/glimmer/tk/root_proxy.rb
|
238
|
+
- lib/glimmer/tk/spinbox_proxy.rb
|
239
|
+
- lib/glimmer/tk/text_proxy.rb
|
237
240
|
- lib/glimmer/tk/text_variable_owner.rb
|
238
241
|
- lib/glimmer/tk/treeview_proxy.rb
|
239
242
|
- lib/glimmer/tk/variable_owner.rb
|
240
243
|
- lib/glimmer/tk/widget_proxy.rb
|
244
|
+
- samples/elaborate/meta_sample.rb
|
241
245
|
- samples/hello/hello_button.rb
|
242
246
|
- samples/hello/hello_checkbutton.rb
|
243
247
|
- samples/hello/hello_combobox.rb
|
@@ -252,6 +256,7 @@ files:
|
|
252
256
|
- samples/hello/hello_notebook.rb
|
253
257
|
- samples/hello/hello_radiobutton.rb
|
254
258
|
- samples/hello/hello_root.rb
|
259
|
+
- samples/hello/hello_spinbox.rb
|
255
260
|
- samples/hello/hello_world.rb
|
256
261
|
- samples/hello/images/denmark.png
|
257
262
|
- samples/hello/images/finland.png
|