glimmer-dsl-tk 0.0.30 → 0.0.34
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 +4 -4
- data/CHANGELOG.md +32 -2
- data/README.md +143 -57
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/data_binding/tk/one_time_observer.rb +39 -0
- data/lib/glimmer/dsl/tk/data_binding_expression.rb +3 -2
- data/lib/glimmer/dsl/tk/widget_expression.rb +5 -1
- data/lib/glimmer/tk/entry_proxy.rb +1 -1
- data/lib/glimmer/tk/root_proxy.rb +2 -77
- data/lib/glimmer/tk/text_proxy.rb +137 -25
- data/lib/glimmer/tk/toplevel_proxy.rb +119 -0
- data/lib/glimmer/tk/widget_proxy.rb +57 -13
- data/samples/hello/hello_text.rb +110 -38
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69e1f06607f60b2864e78e6e1eb9bfde7cf98f8d8eca2d14f12bf218d781dcb3
|
4
|
+
data.tar.gz: 7c552bb85c6b87eeefe8117b5f3d2df922ff27618f564e6dd37df63b57c17d98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6dad9353a12a78f0e8c4a2be45e440c2bebb3e0998957447332d0ab65ec3668eb447395cb32bb8bfa4c6feed3bee991d78b07dbe500c3716e914ed0e51b312c
|
7
|
+
data.tar.gz: 36bfc6aa1b337b33b6c6a658549b603658677ea0e4e1840ec1ef58727bb12c76031d08b22fd50960001c2881819e7ec1a7e672f1c29e57d63797d0ea106531f0
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,40 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## 0.0.
|
3
|
+
## 0.0.34
|
4
|
+
|
5
|
+
- When applying a `text` selection format without having a selection, have it apply to current insert mark word
|
6
|
+
- Support registering multiple general event listeners on `text` widget (previously, later event listener registrations replaced former ones)
|
7
|
+
- Implement `:no_selection_default` option of `:insert_word`, `insert_letter`, or `none` for `text` selection formatting methods (`add_selection_format`, `remove_selection_format`, `toggle_selection_format`, `add_selection_font_format`, `remove_selection_font_format`, `toggle_selection_font_format`)
|
8
|
+
- Make sure to only allow `text` undo/redo when there are changes to be undoed/redoed
|
9
|
+
- Fix issue with Hello, Text! Find Dialog not coming up with keyboard shortcut (e.g. CMD+F) anymore
|
10
|
+
- Fix issue with Hello, Text! whereby after applying background, and foreground to a selection, you cannot apply bold, italic, or underline for the same selection (or font-size or font-family)
|
11
|
+
|
12
|
+
## 0.0.33
|
13
|
+
|
14
|
+
- Support `text` widget `InsertMarkMoved` listener event to track insert mark movement (or aliases `InsertMarkMove`, `insert_mark_move`, `insert_mark_moved`, all case-insensitive)
|
15
|
+
- Support `entry` widget `changed` and `modified` listener event aliases for `change` event
|
16
|
+
- Autodiscover format options when moving cursor in `text` widget (auto-derive from applied tags and widget font) and show in top Hello, Text! toolbar comboboxes and buttons
|
17
|
+
- Fix issue with encountering error 'NoMethodError: undefined method "size" for' when launching Hello, Text!, performing Select-All (CMD+A or CONTROL+A) and then attempting to Bold all the text.
|
18
|
+
- Fix issue in Hello, Text! whereby bolding a small region of text affects the font of the following region of text till the end of the document
|
19
|
+
- Fix issue in Hello, Text! where if all text is copied and then pasted multiple times, the `text` widget loses its keyboard/mouse listeners and CMD+F does not work anymore to bring Find dialog
|
20
|
+
|
21
|
+
## 0.0.32
|
22
|
+
|
23
|
+
- Hello, Text! Find Dialog toolbar button
|
24
|
+
- Hello, Text! Find Dialog Windows/Linux CONTROL+F shortcut alternative to Mac CMD+F
|
25
|
+
|
26
|
+
## 0.0.31
|
4
27
|
|
5
28
|
- Improve Hello, Text! (toolbar buttons: justify left, justify center, justify right)
|
6
|
-
-
|
29
|
+
- `on('destroy') {|widget| ...}` support in widgets to better track calls to "destroy" method and `'<Destroy>'` binding event (as opposed to the unreliable tracking of '<Destroy>' alone)
|
30
|
+
- Support observing `text` general events (e.g. `'<KeyPress>'`) through `on(event) {}` (was not working before because it required applying a tag, a general `__all__` tag is applied automatically now on full range (`1.0` to `end`))
|
31
|
+
- Ensure unregistering observers (like data-binding observers) when destroying a widget
|
32
|
+
- Add `Glimmer::Tk::ToplevelProxy` widget proxy support similar to `Glimmer::Tk::RootProxy`
|
7
33
|
|
34
|
+
## 0.0.30
|
35
|
+
|
36
|
+
- Improve Hello, Text! (toolbar buttons: find dialog)
|
37
|
+
- Fixed Hello, Built-in Dialog! Font Dialog issue
|
8
38
|
## 0.0.29
|
9
39
|
|
10
40
|
- Hello, Built-in Dialog! (demonstrating all built-in dialogs like get_open_file and choose_color)
|
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.34
|
2
2
|
## MRI Ruby Desktop Development GUI Library
|
3
3
|
[](http://badge.fury.io/rb/glimmer-dsl-tk)
|
4
4
|
[](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml)
|
@@ -120,8 +120,9 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
120
120
|
- [Applications](#applications)
|
121
121
|
- [Glimmer Tk Calculator](#glimmer-tk-calculator)
|
122
122
|
- [Y3network Ruby UI](#y3network-ruby-ui)
|
123
|
-
- [
|
123
|
+
- [CryptoPunks GUI](#cryptopunks-gui)
|
124
124
|
- [Process](#process)
|
125
|
+
- [Resources](#resources)
|
125
126
|
- [Help](#help)
|
126
127
|
- [Issues](#issues)
|
127
128
|
- [Chat](#chat)
|
@@ -157,7 +158,7 @@ gem install glimmer-dsl-tk
|
|
157
158
|
|
158
159
|
Add the following to `Gemfile`:
|
159
160
|
```
|
160
|
-
gem 'glimmer-dsl-tk', '~> 0.0.
|
161
|
+
gem 'glimmer-dsl-tk', '~> 0.0.34'
|
161
162
|
```
|
162
163
|
|
163
164
|
And, then run:
|
@@ -199,7 +200,7 @@ The Glimmer GUI DSL follows these simple concepts in mapping from Tk syntax:
|
|
199
200
|
- **Widget Keyword**: Any Tk widget (e.g. `Tk::Tile::Label`) or toplevel window (e.g. `TkRoot`) may be declared by its lower-case underscored name without the namespace (e.g. `label` or `root`). This is called a keyword and is represented in the Glimmer GUI DSL by a Ruby method behind the scenes.
|
200
201
|
- **Args**: Any keyword method may optionally take arguments surrounded by parentheses (e.g. a `frame` nested under a `notebook` may receive tab options like `frame(text: 'Users')`, which gets used behind the scenes by Tk code such as `notebook.add tab, text: 'Users'`)
|
201
202
|
- **Content/Options Block**: Any keyword may optionally be followed by a Ruby curly-brace block containing nested widgets (content) and attributes (options). Attributes are simply Tk option keywords followed by arguments and no block (e.g. `title 'Hello, World!'` under a `root`)
|
202
|
-
- **Event Binding Block**: `on(event) {}` keyword receiving a Tk binding event name (e.g. `KeyPress` or `ComboboxSelected`).
|
203
|
+
- **Event Binding Block**: `on(event) {}` keyword receiving a Tk binding event name (e.g. `KeyPress` or `ComboboxSelected`). Surrounding event by `<>` is optional as [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) can take care of that automatically.
|
203
204
|
|
204
205
|
Example of an app written in [Tk](https://www.tcl.tk/) imperative syntax:
|
205
206
|
|
@@ -272,7 +273,7 @@ keyword(args) | attributes | event bindings & callbacks
|
|
272
273
|
`choose_directory(options = nil)` | None | None
|
273
274
|
`choose_font(options = nil) {|font| ... }` | None | None
|
274
275
|
`combobox` | `state`, `text` | `'ComboboxSelected'`
|
275
|
-
`entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'
|
276
|
+
`entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'` (alias: `'changed'`), `validatecommand {}`, `invalidcommand {}`
|
276
277
|
`get_multiple_open_file(options = nil)` | None | None
|
277
278
|
`get_open_file(options = nil)` | None | None
|
278
279
|
`get_save_file(options = nil)` | None | None
|
@@ -285,7 +286,7 @@ keyword(args) | attributes | event bindings & callbacks
|
|
285
286
|
`radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
|
286
287
|
`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'`
|
287
288
|
`separator` | `orient` (`'horizontal' (default) or 'vertical'`) | None
|
288
|
-
`text` | `value`, [many more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `'modified'`, `'selection'`
|
289
|
+
`text` | `value`, [many more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `'modified'`, `'selection'`, `'insert_mark_moved'` (alias: `'insert_mark_move', 'InsertMarkMove', 'InsertMarkMoved'`)
|
289
290
|
|
290
291
|
Options for `get_open_file` and `get_multiple_open_file` include:
|
291
292
|
- `filetypes`: `Hash` of `'Group Name' => '.ext'` entries (e.g. `filetypes: {'PNG Images' => '.png'}`
|
@@ -348,15 +349,20 @@ The `text` widget is enhanced by [Glimmer DSL for Tk](https://rubygems.org/gems/
|
|
348
349
|
- `add_font_format(region_start, region_end, font_option, value)`
|
349
350
|
- `remove_font_format(region_start, region_end, font_option, value)`
|
350
351
|
- `toggle_font_format(region_start, region_end, font_option, value)`
|
351
|
-
- `add_selection_format(
|
352
|
-
- `remove_selection_format(
|
353
|
-
- `toggle_selection_format(
|
354
|
-
- `add_selection_font_format(
|
355
|
-
- `remove_selection_font_format(
|
356
|
-
- `toggle_selection_font_format(
|
352
|
+
- `add_selection_format(option, value, no_selection_default: :insert_word)`: adds format to selection. If there is no selection, then applies format to current insert mark word.
|
353
|
+
- `remove_selection_format(option, value, no_selection_default: :insert_word)`
|
354
|
+
- `toggle_selection_format(option, value, no_selection_default: :insert_word)`: toggles format on selection. If there is no selection, then toggles format on current insert mark word.
|
355
|
+
- `add_selection_font_format(font_option, value, no_selection_default: :insert_word)`
|
356
|
+
- `remove_selection_font_format(font_option, value, no_selection_default: :insert_word)`
|
357
|
+
- `toggle_selection_font_format(font_option, value, no_selection_default: :insert_word)`
|
357
358
|
- `text#insert_image(text_index, *image_args)`: inserts image into `text` `value` content at `text_index` location (e.g. `'insert'`)
|
358
359
|
- `text#get_open_file_to_insert_image(text_index = 'insert')`: opens a file dialog to select one of the available image formats and then inserts image into `text` `value` content
|
359
360
|
|
361
|
+
The `:no_selection_default` keyword arg to `*_selection_*` methods determines what region to cover when no explicit selection is set:
|
362
|
+
- `:insert_word`: current word for insert mark
|
363
|
+
- `:insert_letter`: current letter for insert mark
|
364
|
+
- `:none`: no behavior when no selection is in place
|
365
|
+
|
360
366
|
Available options:
|
361
367
|
|
362
368
|
- `background`
|
@@ -730,6 +736,7 @@ More details can be found in the [Hello, Button!](#hello-button) sample below.
|
|
730
736
|
## Gotchas
|
731
737
|
|
732
738
|
- Setting `background` attribute on `frame` or `label` does not work in `'aqua'` theme on the Mac (only in `'classic'` theme)
|
739
|
+
- `text` widget does not track `KeyPress`/`KeyRelease` events perfectly (installed via `on()` listener keyword). It seems that when all text is deleted, it stops tracking key presses/releases until a number of new lines have been added to `text` `value` attribute
|
733
740
|
|
734
741
|
## Samples
|
735
742
|
|
@@ -1868,6 +1875,8 @@ Glimmer app:
|
|
1868
1875
|
|
1869
1876
|
### Hello, Text!
|
1870
1877
|
|
1878
|
+
You may press META+F to bring up the Find Dialog on the Mac and CONTROL+F to bring it up on Windows/Linux.
|
1879
|
+
|
1871
1880
|
Icons used in this sample were made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon"> www.flaticon.com</a>
|
1872
1881
|
|
1873
1882
|
Glimmer code (from [samples/hello/hello_text.rb](samples/hello/hello_text.rb)):
|
@@ -1918,7 +1927,7 @@ class HelloText
|
|
1918
1927
|
MULTI_LINE_STRING
|
1919
1928
|
end
|
1920
1929
|
|
1921
|
-
attr_accessor :document
|
1930
|
+
attr_accessor :document, :find_text
|
1922
1931
|
|
1923
1932
|
attr_accessor :foreground
|
1924
1933
|
|
@@ -1944,8 +1953,16 @@ class HelloText
|
|
1944
1953
|
[FONT_SIZE_PROMPT] + (9..64).to_a.map(&:to_s)
|
1945
1954
|
end
|
1946
1955
|
|
1956
|
+
def find
|
1957
|
+
text_index = @text.search(/#{find_text}/i, @text.tag_ranges('sel')&.first&.last || @text.index('insert'))
|
1958
|
+
unless text_index.to_s.empty?
|
1959
|
+
@text.tag_remove('sel', '1.0', 'end')
|
1960
|
+
@text.tag_add('sel', text_index, "#{text_index} + #{find_text.size} chars")
|
1961
|
+
end
|
1962
|
+
end
|
1963
|
+
|
1947
1964
|
def launch
|
1948
|
-
root {
|
1965
|
+
@root = root {
|
1949
1966
|
title 'Hello, Text!'
|
1950
1967
|
width 1280
|
1951
1968
|
height 800
|
@@ -1953,11 +1970,6 @@ class HelloText
|
|
1953
1970
|
frame {
|
1954
1971
|
grid row: 0, column: 0
|
1955
1972
|
|
1956
|
-
label {
|
1957
|
-
grid row: 0, column: 0, columnspan: 17
|
1958
|
-
text 'Select a region of text and then apply formatting from the toolbar'
|
1959
|
-
}
|
1960
|
-
|
1961
1973
|
column_index = -1
|
1962
1974
|
|
1963
1975
|
combobox {
|
@@ -1989,7 +2001,7 @@ class HelloText
|
|
1989
2001
|
orient 'vertical'
|
1990
2002
|
}
|
1991
2003
|
|
1992
|
-
button {
|
2004
|
+
@bold_button = button {
|
1993
2005
|
grid row: 1, column: column_index += 1, column_weight: 0
|
1994
2006
|
text 'B'
|
1995
2007
|
style font: {weight: 'bold'}
|
@@ -1999,7 +2011,7 @@ class HelloText
|
|
1999
2011
|
end
|
2000
2012
|
}
|
2001
2013
|
|
2002
|
-
button {
|
2014
|
+
@italic_button = button {
|
2003
2015
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2004
2016
|
text 'I'
|
2005
2017
|
style font: {slant: 'italic'}
|
@@ -2009,7 +2021,7 @@ class HelloText
|
|
2009
2021
|
end
|
2010
2022
|
}
|
2011
2023
|
|
2012
|
-
button {
|
2024
|
+
@underline_button = button {
|
2013
2025
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2014
2026
|
text 'U'
|
2015
2027
|
style font: {underline: true}
|
@@ -2018,36 +2030,36 @@ class HelloText
|
|
2018
2030
|
@text.toggle_selection_font_format('underline', true)
|
2019
2031
|
end
|
2020
2032
|
}
|
2021
|
-
|
2033
|
+
|
2022
2034
|
separator {
|
2023
2035
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2024
2036
|
orient 'vertical'
|
2025
2037
|
}
|
2026
2038
|
|
2027
|
-
button {
|
2039
|
+
@justify_left_button = button {
|
2028
2040
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2029
|
-
image File.expand_path("images/
|
2041
|
+
image File.expand_path("images/align-left.png", __dir__), subsample: 32
|
2030
2042
|
|
2031
2043
|
on('command') do
|
2032
|
-
@text.
|
2044
|
+
@text.add_selection_format('justify', 'left')
|
2033
2045
|
end
|
2034
2046
|
}
|
2035
2047
|
|
2036
|
-
button {
|
2048
|
+
@justify_center_button = button {
|
2037
2049
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2038
|
-
image File.expand_path("images/
|
2050
|
+
image File.expand_path("images/align-center.png", __dir__), subsample: 32
|
2039
2051
|
|
2040
2052
|
on('command') do
|
2041
|
-
@text.
|
2053
|
+
@text.add_selection_format('justify', 'center')
|
2042
2054
|
end
|
2043
2055
|
}
|
2044
2056
|
|
2045
|
-
button {
|
2057
|
+
@justify_right_button = button {
|
2046
2058
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2047
|
-
image File.expand_path("images/
|
2059
|
+
image File.expand_path("images/align-right.png", __dir__), subsample: 32
|
2048
2060
|
|
2049
2061
|
on('command') do
|
2050
|
-
@text.
|
2062
|
+
@text.add_selection_format('justify', 'right')
|
2051
2063
|
end
|
2052
2064
|
}
|
2053
2065
|
|
@@ -2058,51 +2070,51 @@ class HelloText
|
|
2058
2070
|
|
2059
2071
|
button {
|
2060
2072
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2061
|
-
image File.expand_path("images/
|
2073
|
+
image File.expand_path("images/picture.png", __dir__), subsample: 32
|
2062
2074
|
|
2063
2075
|
on('command') do
|
2064
|
-
@text.
|
2076
|
+
@text.get_open_file_to_insert_image
|
2065
2077
|
end
|
2066
2078
|
}
|
2067
2079
|
|
2068
2080
|
button {
|
2069
2081
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2070
|
-
image File.expand_path("images/
|
2082
|
+
image File.expand_path("images/search.png", __dir__), subsample: 32
|
2071
2083
|
|
2072
2084
|
on('command') do
|
2073
|
-
|
2085
|
+
show_find_dialog
|
2074
2086
|
end
|
2075
2087
|
}
|
2076
2088
|
|
2089
|
+
separator {
|
2090
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2091
|
+
orient 'vertical'
|
2092
|
+
}
|
2093
|
+
|
2077
2094
|
button {
|
2078
2095
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2079
|
-
image File.expand_path("images/
|
2096
|
+
image File.expand_path("images/cut.png", __dir__), subsample: 32
|
2080
2097
|
|
2081
2098
|
on('command') do
|
2082
|
-
@text.
|
2099
|
+
@text.text_cut
|
2083
2100
|
end
|
2084
2101
|
}
|
2085
2102
|
|
2086
|
-
separator {
|
2087
|
-
grid row: 1, column: column_index += 1, column_weight: 0
|
2088
|
-
orient 'vertical'
|
2089
|
-
}
|
2090
|
-
|
2091
2103
|
button {
|
2092
2104
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2093
|
-
image File.expand_path("images/
|
2105
|
+
image File.expand_path("images/copy.png", __dir__), subsample: 32
|
2094
2106
|
|
2095
2107
|
on('command') do
|
2096
|
-
@text.
|
2108
|
+
@text.text_copy
|
2097
2109
|
end
|
2098
2110
|
}
|
2099
2111
|
|
2100
2112
|
button {
|
2101
2113
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2102
|
-
image File.expand_path("images/
|
2114
|
+
image File.expand_path("images/paste.png", __dir__), subsample: 32
|
2103
2115
|
|
2104
2116
|
on('command') do
|
2105
|
-
@text.
|
2117
|
+
@text.text_paste
|
2106
2118
|
end
|
2107
2119
|
}
|
2108
2120
|
|
@@ -2111,12 +2123,22 @@ class HelloText
|
|
2111
2123
|
orient 'vertical'
|
2112
2124
|
}
|
2113
2125
|
|
2126
|
+
|
2114
2127
|
button {
|
2115
2128
|
grid row: 1, column: column_index += 1, column_weight: 0
|
2116
|
-
image File.expand_path("images/
|
2129
|
+
image File.expand_path("images/undo.png", __dir__), subsample: 32
|
2117
2130
|
|
2118
2131
|
on('command') do
|
2119
|
-
@text.
|
2132
|
+
@text.edit_undo
|
2133
|
+
end
|
2134
|
+
}
|
2135
|
+
|
2136
|
+
button {
|
2137
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2138
|
+
image File.expand_path("images/redo.png", __dir__), subsample: 32
|
2139
|
+
|
2140
|
+
on('command') do
|
2141
|
+
@text.edit_redo
|
2120
2142
|
end
|
2121
2143
|
}
|
2122
2144
|
}
|
@@ -2126,8 +2148,67 @@ class HelloText
|
|
2126
2148
|
wrap 'word'
|
2127
2149
|
undo true
|
2128
2150
|
value <=> [self, :document]
|
2151
|
+
|
2152
|
+
on('KeyPress') do |event|
|
2153
|
+
show_find_dialog if (event.keysym == 'f') && ((OS.mac? && event.state == 8) || (!OS.mac? && event.state == 4))
|
2154
|
+
end
|
2155
|
+
|
2156
|
+
on('InsertMarkMoved') do
|
2157
|
+
self.font_family = @text.applied_font_format_value('family')
|
2158
|
+
self.font_size = @text.applied_font_format_value('size')
|
2159
|
+
@bold_button.default = @text.applied_font_format_value('weight') == 'bold' ? 'active' : 'normal'
|
2160
|
+
@italic_button.default = @text.applied_font_format_value('slant') == 'italic' ? 'active' : 'normal'
|
2161
|
+
@underline_button.default = @text.applied_font_format_value('underline') == true ? 'active' : 'normal'
|
2162
|
+
self.background = @text.applied_format_value('background')
|
2163
|
+
self.foreground = @text.applied_format_value('foreground')
|
2164
|
+
@justify_left_button.default = @text.applied_format_value('justify') == 'left' ? 'active' : 'normal'
|
2165
|
+
@justify_center_button.default = @text.applied_format_value('justify') == 'center' ? 'active' : 'normal'
|
2166
|
+
@justify_right_button.default = @text.applied_format_value('justify') == 'right' ? 'active' : 'normal'
|
2167
|
+
end
|
2129
2168
|
}
|
2130
|
-
}
|
2169
|
+
}
|
2170
|
+
@root.open
|
2171
|
+
end
|
2172
|
+
|
2173
|
+
def show_find_dialog
|
2174
|
+
toplevel(@root) { |tl|
|
2175
|
+
title 'Find'
|
2176
|
+
|
2177
|
+
label {
|
2178
|
+
text 'Text:'
|
2179
|
+
}
|
2180
|
+
entry { |e|
|
2181
|
+
focus true
|
2182
|
+
text <=> [
|
2183
|
+
self,
|
2184
|
+
:find_text,
|
2185
|
+
after_write: lambda do
|
2186
|
+
text_index = @text.search(/#{find_text}/i, 'insert')
|
2187
|
+
unless text_index.to_s.empty?
|
2188
|
+
@text.tag_remove('sel', '1.0', 'end')
|
2189
|
+
@text.tag_add('sel', text_index, "#{text_index} + #{find_text.size} chars")
|
2190
|
+
end
|
2191
|
+
end
|
2192
|
+
]
|
2193
|
+
|
2194
|
+
on('KeyPress') do |event|
|
2195
|
+
if event.keysym == 'Return'
|
2196
|
+
find
|
2197
|
+
elsif event.keysym == 'Escape'
|
2198
|
+
tl.grab_release
|
2199
|
+
tl.destroy
|
2200
|
+
end
|
2201
|
+
end
|
2202
|
+
}
|
2203
|
+
button {
|
2204
|
+
text 'Find'
|
2205
|
+
default 'active'
|
2206
|
+
|
2207
|
+
on('command') do
|
2208
|
+
find
|
2209
|
+
end
|
2210
|
+
}
|
2211
|
+
}
|
2131
2212
|
end
|
2132
2213
|
end
|
2133
2214
|
|
@@ -2150,6 +2231,8 @@ Glimmer app:
|
|
2150
2231
|
|
2151
2232
|

|
2152
2233
|
|
2234
|
+

|
2235
|
+
|
2153
2236
|
### Hello, Spinbox!
|
2154
2237
|
|
2155
2238
|
Glimmer code (from [samples/hello/hello_spinbox.rb](samples/hello/hello_spinbox.rb)):
|
@@ -2624,31 +2707,34 @@ Glimmer app:
|
|
2624
2707
|
|
2625
2708
|
https://github.com/ancorgs/glimmer-tk-calculator
|
2626
2709
|
|
2627
|
-
https://raw.githubusercontent.com/ancorgs/glimmer-tk-calculator/master/screenshot.png
|
2710
|
+

|
2628
2711
|
|
2629
2712
|
### Y3network Ruby UI
|
2630
2713
|
|
2631
2714
|
https://github.com/ancorgs/y3network-ruby-ui
|
2632
2715
|
|
2633
|
-
###
|
2716
|
+
### CryptoPunks GUI
|
2634
2717
|
|
2635
|
-
This is a Graphical User Interface for the famous [
|
2718
|
+
This is a Graphical User Interface for the famous [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
|
2636
2719
|
|
2637
2720
|
https://github.com/AndyObtiva/cryptopunks-gui
|
2638
2721
|
|
2639
|
-

|
2640
2723
|
|
2641
2724
|
## Process
|
2642
2725
|
|
2643
2726
|
[Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
|
2644
2727
|
|
2728
|
+
## Resources
|
2729
|
+
|
2730
|
+
- [Tk Tutorial](https://tkdocs.com/tutorial/index.html)
|
2731
|
+
- [Code Master Blog](https://andymaleh.blogspot.com/search/label/Tk)
|
2732
|
+
|
2645
2733
|
## Help
|
2646
2734
|
|
2647
2735
|
### Issues
|
2648
2736
|
|
2649
|
-
|
2650
|
-
|
2651
|
-
[Click here to submit an issue.](https://github.com/AndyObtiva/glimmer/issues)
|
2737
|
+
If you encounter [issues](https://github.com/AndyObtiva/glimmer-dsl-tk/issues) that are not reported, discover missing features that are not mentioned in [TODO.md](TODO.md), or think up better ways to use [Tk](https://www.tcl.tk/) than what is possible with [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk), you may submit an [issue](https://github.com/AndyObtiva/glimmer-dsl-tk/issues/new) or [pull request](https://github.com/AndyObtiva/glimmer-dsl-tk/compare) on [GitHub](https://github.com).
|
2652
2738
|
|
2653
2739
|
### Chat
|
2654
2740
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.34
|
data/glimmer-dsl-tk.gemspec
CHANGED
Binary file
|
@@ -0,0 +1,39 @@
|
|
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/data_binding/observer'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module DataBinding
|
26
|
+
module Tk
|
27
|
+
# Decorator for Observer that ensures it is only called once
|
28
|
+
# (subsequent invocations of call method do nothing)
|
29
|
+
module OneTimeObserver
|
30
|
+
def call(value)
|
31
|
+
unless @called
|
32
|
+
super
|
33
|
+
@called = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -38,12 +38,13 @@ module Glimmer
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def interpret(parent, keyword, *args, &block)
|
41
|
-
parent.class
|
42
41
|
model_binding = args[0]
|
43
42
|
widget_binding_parameters = [parent, keyword]
|
44
43
|
widget_binding = DataBinding::Tk::WidgetBinding.new(*widget_binding_parameters)
|
45
44
|
#TODO make this options observer dependent and all similar observers in widget specific data binding handlers
|
46
|
-
widget_binding.observe(model_binding)
|
45
|
+
registration = widget_binding.observe(model_binding)
|
46
|
+
parent.on('destroy') { registration.deregister }
|
47
|
+
|
47
48
|
# TODO simplify this logic and put it where it belongs
|
48
49
|
parent.add_observer(model_binding, keyword) if parent.respond_to?(:add_observer, [model_binding, keyword])
|
49
50
|
widget_binding.call(model_binding.evaluate_property)
|
@@ -33,11 +33,15 @@ module Glimmer
|
|
33
33
|
|
34
34
|
def can_interpret?(parent, keyword, *args, &block)
|
35
35
|
!EXCLUDED_KEYWORDS.include?(keyword) and
|
36
|
-
parent.respond_to?(:tk) and
|
37
36
|
Glimmer::Tk::WidgetProxy.widget_exists?(keyword)
|
37
|
+
(parent.respond_to?(:tk) or args.first.respond_to?(:tk))
|
38
38
|
end
|
39
39
|
|
40
40
|
def interpret(parent, keyword, *args, &block)
|
41
|
+
if keyword == 'toplevel' && args.first.respond_to?(:tk)
|
42
|
+
parent = args.first
|
43
|
+
args[0] = args.first.tk
|
44
|
+
end
|
41
45
|
Glimmer::Tk::WidgetProxy.create(keyword, parent, args, &block)
|
42
46
|
end
|
43
47
|
|