glimmer-dsl-tk 0.0.28 → 0.0.32
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 +31 -0
- data/README.md +549 -55
- 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/built_in_dialog_expression.rb +57 -0
- data/lib/glimmer/dsl/tk/data_binding_expression.rb +3 -2
- data/lib/glimmer/dsl/tk/dsl.rb +1 -0
- data/lib/glimmer/dsl/tk/widget_expression.rb +5 -1
- data/lib/glimmer/tk/root_proxy.rb +2 -77
- data/lib/glimmer/tk/text_proxy.rb +30 -22
- data/lib/glimmer/tk/toplevel_proxy.rb +119 -0
- data/lib/glimmer/tk/widget_proxy.rb +61 -14
- data/samples/elaborate/meta_sample.rb +4 -4
- data/samples/hello/hello_built_in_dialog.rb +68 -0
- data/samples/hello/hello_message_box.rb +0 -4
- data/samples/hello/hello_separator.rb +69 -0
- data/samples/hello/hello_text.rb +164 -43
- data/samples/hello/images/align-center.png +0 -0
- data/samples/hello/images/align-left.png +0 -0
- data/samples/hello/images/align-right.png +0 -0
- data/samples/hello/images/picture.png +0 -0
- data/samples/hello/images/search.png +0 -0
- metadata +13 -3
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.32
|
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)
|
@@ -75,6 +75,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
75
75
|
- [Common Attributes](#common-attributes)
|
76
76
|
- [Common Themed Widget States](#common-themed-widget-states)
|
77
77
|
- [Text API](#text-api)
|
78
|
+
- [Drag and Drop API](#drag-and-drop-api)
|
78
79
|
- [Smart Defaults and Conventions](#smart-defaults-and-conventions)
|
79
80
|
- [Grid Layout](#grid-layout)
|
80
81
|
- [Image Attribute](#image-attribute)
|
@@ -90,6 +91,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
90
91
|
- [List Single Selection Data-Binding](#list-single-selection-data-binding)
|
91
92
|
- [List Multi Selection Data-Binding](#list-multi-selection-data-binding)
|
92
93
|
- [Entry Data-Binding](#entry-data-binding)
|
94
|
+
- [Text Data-Binding](#text-data-binding)
|
93
95
|
- [Spinbox Data-Binding](#spinbox-data-binding)
|
94
96
|
- [Checkbutton Data-Binding](#checkbutton-data-binding)
|
95
97
|
- [Radiobutton Data-Binding](#radiobutton-data-binding)
|
@@ -113,10 +115,17 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
113
115
|
- [Hello, Spinbox!](#hello-spinbox)
|
114
116
|
- [Hello, Computed!](#hello-computed)
|
115
117
|
- [Hello, Drag and Drop!](#hello-drag-and-drop)
|
118
|
+
- [Hello, Built-in Dialog!](#hello-built-in-dialog)
|
119
|
+
- [Hello, Separator!](#hello-separator)
|
120
|
+
- [Applications](#applications)
|
121
|
+
- [Glimmer Tk Calculator](#glimmer-tk-calculator)
|
122
|
+
- [Y3network Ruby UI](#y3network-ruby-ui)
|
123
|
+
- [CryptoPunks GUI](#cryptopunks-gui)
|
124
|
+
- [Process](#process)
|
125
|
+
- [Resources](#resources)
|
116
126
|
- [Help](#help)
|
117
127
|
- [Issues](#issues)
|
118
128
|
- [Chat](#chat)
|
119
|
-
- [Process](#process)
|
120
129
|
- [Planned Features and Feature Suggestions](#planned-features-and-feature-suggestions)
|
121
130
|
- [Change Log](#change-log)
|
122
131
|
- [Contributing](#contributing)
|
@@ -149,7 +158,7 @@ gem install glimmer-dsl-tk
|
|
149
158
|
|
150
159
|
Add the following to `Gemfile`:
|
151
160
|
```
|
152
|
-
gem 'glimmer-dsl-tk', '~> 0.0.
|
161
|
+
gem 'glimmer-dsl-tk', '~> 0.0.32'
|
153
162
|
```
|
154
163
|
|
155
164
|
And, then run:
|
@@ -191,7 +200,7 @@ The Glimmer GUI DSL follows these simple concepts in mapping from Tk syntax:
|
|
191
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.
|
192
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'`)
|
193
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`)
|
194
|
-
- **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.
|
195
204
|
|
196
205
|
Example of an app written in [Tk](https://www.tcl.tk/) imperative syntax:
|
197
206
|
|
@@ -260,8 +269,14 @@ keyword(args) | attributes | event bindings & callbacks
|
|
260
269
|
------------- | ---------- | ---------
|
261
270
|
`button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command {}`
|
262
271
|
`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 {}`
|
272
|
+
`choose_color(options = nil)` | None | None
|
273
|
+
`choose_directory(options = nil)` | None | None
|
274
|
+
`choose_font(options = nil) {|font| ... }` | None | None
|
263
275
|
`combobox` | `state`, `text` | `'ComboboxSelected'`
|
264
276
|
`entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'`, `validatecommand {}`, `invalidcommand {}`
|
277
|
+
`get_multiple_open_file(options = nil)` | None | None
|
278
|
+
`get_open_file(options = nil)` | None | None
|
279
|
+
`get_save_file(options = nil)` | None | None
|
265
280
|
`spinbox` | `text`, `from`, `to`, `increment`, `format`, [more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `command {}`, `'increment'`, `'decrement'`
|
266
281
|
`frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
|
267
282
|
`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
|
@@ -270,7 +285,11 @@ keyword(args) | attributes | event bindings & callbacks
|
|
270
285
|
`notebook` | None | None
|
271
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 {}`
|
272
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'`
|
273
|
-
`
|
288
|
+
`separator` | `orient` (`'horizontal' (default) or 'vertical'`) | None
|
289
|
+
`text` | `value`, [many more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `'modified'`, `'selection'`
|
290
|
+
|
291
|
+
Options for `get_open_file` and `get_multiple_open_file` include:
|
292
|
+
- `filetypes`: `Hash` of `'Group Name' => '.ext'` entries (e.g. `filetypes: {'PNG Images' => '.png'}`
|
274
293
|
|
275
294
|
#### Common Attributes
|
276
295
|
|
@@ -322,9 +341,7 @@ keyword(args) | attributes | event bindings & callbacks
|
|
322
341
|
|
323
342
|
#### Text API
|
324
343
|
|
325
|
-
[Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk)
|
326
|
-
|
327
|
-
Also, the `text` widget is enhanced by [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) to enable simpler manipulation of text options without dealing with [tags](https://tkdocs.com/tutorial/text.html) directly. Simply specify region to mutate and option/value or font_option/value, and [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) takes care of the rest by automating work of adding/removing [tags](https://tkdocs.com/tutorial/text.html) behind the scenes.
|
344
|
+
The `text` widget is enhanced by [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) to enable simpler manipulation of text options without dealing with [tags](https://tkdocs.com/tutorial/text.html) directly. Simply specify region to mutate and option/value or font_option/value, and [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) takes care of the rest by automating work of adding/removing [tags](https://tkdocs.com/tutorial/text.html) behind the scenes.
|
328
345
|
|
329
346
|
- `add_format(region_start, region_end, option, value)`
|
330
347
|
- `remove_format(region_start, region_end, option, value)`
|
@@ -338,6 +355,8 @@ Also, the `text` widget is enhanced by [Glimmer DSL for Tk](https://rubygems.org
|
|
338
355
|
- `add_selection_font_format(region_start, region_end, font_option, value)`
|
339
356
|
- `remove_selection_font_format(region_start, region_end, font_option, value)`
|
340
357
|
- `toggle_selection_font_format(region_start, region_end, font_option, value)`
|
358
|
+
- `text#insert_image(text_index, *image_args)`: inserts image into `text` `value` content at `text_index` location (e.g. `'insert'`)
|
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
|
341
360
|
|
342
361
|
Available options:
|
343
362
|
|
@@ -381,6 +400,19 @@ Other useful built-in API methods:
|
|
381
400
|
|
382
401
|
Check out the [Hello, Text!](#hello-text) sample for a good demonstration of the `text` widget features.
|
383
402
|
|
403
|
+
#### Drag and Drop API
|
404
|
+
|
405
|
+
Drag and drop works by simply designating a widget as a drag source with attribute `drag_source true`
|
406
|
+
|
407
|
+
Alternatively, add listeners:
|
408
|
+
- `on_drag_start {|event| ...}`: fires on drag start receiving an `event` arg to set `data` and configure `source`
|
409
|
+
- `on_drag_motion {|event| ...}`: fires on drag motion receiving an `event` arg to check `event#drop_accepted`, and configure `source` and `tooltip`
|
410
|
+
|
411
|
+
On the drop target, you simply define:
|
412
|
+
- `on_drop { |event| ...}`: fires on drop, receiving an `event` arg with `event#target` and `event#data` (set during drag). You can even destroy the `event#source` if you want to get rid of the dragged widget.
|
413
|
+
|
414
|
+
Learn more at the [Hello, Drag and Drop!](#hello-drag-and-drop) sample.
|
415
|
+
|
384
416
|
### Smart Defaults and Conventions
|
385
417
|
|
386
418
|
#### Event Bindings
|
@@ -466,6 +498,8 @@ Example:
|
|
466
498
|
```
|
467
499
|
|
468
500
|
Extra convenience options may be passed to `grid` when using [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk):
|
501
|
+
- `column_span`: alias for `columnspan` keyword arg
|
502
|
+
- `row_span`: alias for `rowspan` keyword arg
|
469
503
|
- `min_width`: alias for `columnminsize` being called on `TkGrid.columnconfigure`
|
470
504
|
- `min_height`: alias for `rowminsize` being called on `TkGrid.rowconfigure`
|
471
505
|
- `column_weight`: alias for `columnweight` being called on `TkGrid.columnconfigure`
|
@@ -578,6 +612,24 @@ It automatically handles all the Tk plumbing behind the scenes.
|
|
578
612
|
|
579
613
|
More details can be found in [Hello, Entry!](#hello-entry) and [Hello, Computed!](#hello-computed) samples below.
|
580
614
|
|
615
|
+
### Text Data-Binding
|
616
|
+
|
617
|
+
Example:
|
618
|
+
|
619
|
+
This assumes a `Person` model with a `biography` attribute.
|
620
|
+
|
621
|
+
```ruby
|
622
|
+
text {
|
623
|
+
value <=> [person, :biography]
|
624
|
+
}
|
625
|
+
```
|
626
|
+
|
627
|
+
That code binds the `value` of `text` to the `biography` attribute on the `person` model.
|
628
|
+
|
629
|
+
It automatically handles all the Tk plumbing behind the scenes.
|
630
|
+
|
631
|
+
More details can be found in [Hello, Text!](#hello-text) sample below.
|
632
|
+
|
581
633
|
### Spinbox Data-Binding
|
582
634
|
|
583
635
|
Example:
|
@@ -698,6 +750,128 @@ ruby -r ./lib/glimmer-dsl-tk.rb samples/elaborate/meta_sample.rb
|
|
698
750
|
|
699
751
|

|
700
752
|
|
753
|
+
Code:
|
754
|
+
|
755
|
+
```ruby
|
756
|
+
require 'glimmer-dsl-tk'
|
757
|
+
require 'facets'
|
758
|
+
require 'fileutils'
|
759
|
+
|
760
|
+
class MetaSample
|
761
|
+
include Glimmer
|
762
|
+
|
763
|
+
attr_accessor :selected_sample_index
|
764
|
+
|
765
|
+
def initialize
|
766
|
+
@selected_sample_index = 0
|
767
|
+
end
|
768
|
+
|
769
|
+
def samples
|
770
|
+
if @samples.nil?
|
771
|
+
sample_files = Dir.glob(File.join(File.expand_path('../hello', __dir__), '**', 'hello_*.rb'))
|
772
|
+
sample_file_names = sample_files.map { |f| File.basename(f, '.rb') }
|
773
|
+
sample_file_names = sample_file_names.reject { |f| f == 'meta_sample' || f.match(/\d$/) }
|
774
|
+
@samples = sample_file_names.map { |f| f.underscore.titlecase }
|
775
|
+
end
|
776
|
+
@samples
|
777
|
+
end
|
778
|
+
|
779
|
+
def file_path_for(sample)
|
780
|
+
File.join(File.expand_path('../hello', __dir__), "#{sample.underscore}.rb")
|
781
|
+
end
|
782
|
+
|
783
|
+
def glimmer_dsl_tk_file
|
784
|
+
File.expand_path('../../lib/glimmer-dsl-tk', __dir__)
|
785
|
+
end
|
786
|
+
|
787
|
+
def selected_sample
|
788
|
+
samples[@selected_sample_index]
|
789
|
+
end
|
790
|
+
|
791
|
+
def run_sample(sample)
|
792
|
+
Thread.new do
|
793
|
+
command = "ruby -r #{glimmer_dsl_tk_file} #{sample} 2>&1"
|
794
|
+
result = ''
|
795
|
+
IO.popen(command) do |f|
|
796
|
+
f.each_line do |line|
|
797
|
+
result << line
|
798
|
+
puts line
|
799
|
+
$stdout.flush
|
800
|
+
end
|
801
|
+
end
|
802
|
+
::Tk.after(100) do
|
803
|
+
message_box(parent: @root, title: 'Error Running Sample', message: result) if result.downcase.include?('error')
|
804
|
+
end
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
def launch
|
809
|
+
@root = root {
|
810
|
+
title 'Glimmer Meta-Sample'
|
811
|
+
width 1280
|
812
|
+
height 720
|
813
|
+
|
814
|
+
frame {
|
815
|
+
grid row: 0, column: 0, column_weight: 0, row_weight: 1
|
816
|
+
|
817
|
+
samples.each_with_index do |sample, index|
|
818
|
+
radiobutton {
|
819
|
+
text sample
|
820
|
+
variable <=> [self, :selected_sample_index, on_write: ->(v) {v ? index : selected_sample_index}, on_read: ->(v) {v == index}]
|
821
|
+
|
822
|
+
on('command') do
|
823
|
+
@selected_sample_index = index
|
824
|
+
@code_text.value = File.read(file_path_for(selected_sample))
|
825
|
+
end
|
826
|
+
}
|
827
|
+
end
|
828
|
+
|
829
|
+
frame {
|
830
|
+
button {
|
831
|
+
grid row: 0, column: 0
|
832
|
+
text 'Launch'
|
833
|
+
|
834
|
+
on('command') do
|
835
|
+
begin
|
836
|
+
parent_dir = File.join(Dir.home, '.glimmer-dsl-tk', 'samples', 'hello')
|
837
|
+
FileUtils.mkdir_p(parent_dir)
|
838
|
+
sample_file = File.join(parent_dir, "#{selected_sample.underscore}.rb")
|
839
|
+
File.write(sample_file, @code_text.value)
|
840
|
+
FileUtils.cp_r(File.expand_path('../../icons', __dir__), File.dirname(File.dirname(parent_dir)))
|
841
|
+
FileUtils.cp_r(File.expand_path('../hello/images', __dir__), parent_dir)
|
842
|
+
sample_namespace_directory = File.expand_path("../hello/#{selected_sample.underscore}", __dir__)
|
843
|
+
FileUtils.cp_r(sample_namespace_directory, parent_dir) if Dir.exist?(sample_namespace_directory)
|
844
|
+
run_sample(sample_file)
|
845
|
+
rescue => e
|
846
|
+
puts e.full_message
|
847
|
+
puts 'Unable to write code changes! Running original sample...'
|
848
|
+
run_sample(file_path_for(selected_sample))
|
849
|
+
end
|
850
|
+
end
|
851
|
+
}
|
852
|
+
button {
|
853
|
+
grid row: 0, column: 1
|
854
|
+
text 'Reset'
|
855
|
+
|
856
|
+
on('command') do
|
857
|
+
@code_text.value = File.read(file_path_for(selected_sample))
|
858
|
+
end
|
859
|
+
}
|
860
|
+
}
|
861
|
+
}
|
862
|
+
|
863
|
+
@code_text = text {
|
864
|
+
grid row: 0, column: 1, column_weight: 1
|
865
|
+
value File.read(file_path_for(selected_sample))
|
866
|
+
}
|
867
|
+
}
|
868
|
+
@root.open
|
869
|
+
end
|
870
|
+
end
|
871
|
+
|
872
|
+
MetaSample.new.launch
|
873
|
+
```
|
874
|
+
|
701
875
|
### Hello, World!
|
702
876
|
|
703
877
|
Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
|
@@ -1389,8 +1563,6 @@ root { |r|
|
|
1389
1563
|
title 'Hello, Message Box!'
|
1390
1564
|
|
1391
1565
|
frame {
|
1392
|
-
grid sticky: 'nsew', padx: 15, pady: 15
|
1393
|
-
|
1394
1566
|
button {
|
1395
1567
|
text 'Please Click To Win a Surprise'
|
1396
1568
|
|
@@ -1442,8 +1614,6 @@ root { |r|
|
|
1442
1614
|
}
|
1443
1615
|
|
1444
1616
|
frame {
|
1445
|
-
grid sticky: 'nsew', padx: 15, pady: 15
|
1446
|
-
|
1447
1617
|
label {
|
1448
1618
|
grid row: 0, column: 0
|
1449
1619
|
text 'Result:'
|
@@ -1471,7 +1641,6 @@ ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_message_box.rb
|
|
1471
1641
|
Glimmer app:
|
1472
1642
|
|
1473
1643
|

|
1474
|
-

|
1475
1644
|
|
1476
1645
|
### Hello, Combobox!
|
1477
1646
|
|
@@ -1700,6 +1869,8 @@ Glimmer app:
|
|
1700
1869
|
|
1701
1870
|
### Hello, Text!
|
1702
1871
|
|
1872
|
+
You may use the META+F shortcut to bring up the Find Dialog.
|
1873
|
+
|
1703
1874
|
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>
|
1704
1875
|
|
1705
1876
|
Glimmer code (from [samples/hello/hello_text.rb](samples/hello/hello_text.rb)):
|
@@ -1711,14 +1882,47 @@ class HelloText
|
|
1711
1882
|
include Glimmer
|
1712
1883
|
|
1713
1884
|
COLOR_OPTIONS = %w[black purple blue green orange yellow red white].map(&:capitalize)
|
1714
|
-
|
1715
|
-
|
1885
|
+
FONT_FAMILY_OPTIONS = ::TkFont.families
|
1886
|
+
FOREGROUND_PROMPT = '<foreground>'
|
1887
|
+
BACKGROUND_PROMPT = '<background>'
|
1888
|
+
FONT_FAMILY_PROMPT = '<font family>'
|
1889
|
+
FONT_SIZE_PROMPT = '<font size>'
|
1716
1890
|
|
1717
1891
|
def initialize
|
1718
1892
|
@foreground = FOREGROUND_PROMPT
|
1719
1893
|
@background = BACKGROUND_PROMPT
|
1894
|
+
@font_family = FONT_FAMILY_PROMPT
|
1895
|
+
@font_size = FONT_SIZE_PROMPT
|
1896
|
+
@document = <<~MULTI_LINE_STRING
|
1897
|
+
According to the National Post, a heavy metal-loving high school principal in Canada will be allowed to keep her job, days after a public campaign to oust her made headlines around the globe.
|
1898
|
+
|
1899
|
+
Parents at Eden High School in St. Catharines, Ontario launched a petition to remove principal Sharon Burns after discovering she's an IRON MAIDEN fan.
|
1900
|
+
|
1901
|
+
The petition, titled "Eden High School Principal, Sharon Burns, Needs to Be Transferred Immediately!" read, "We are deeply disturbed that the principal assigned to the school blatantly showed Satanic symbols and her allegiance to Satanic practices on her public social media platforms where all the students can see them under @edenprincipal (not her personal account)."
|
1902
|
+
|
1903
|
+
More than 500 people signed the petition to transfer Burns after she posted a picture of herself flashing the "devil horns" hand sign with a doll of the MAIDEN zombie mascot Eddie behind her as well as a personalized license plate reading "IRNMADEN" and a handwritten note that reads "Eddie 666" on a car's dashboard.
|
1904
|
+
|
1905
|
+
|
1906
|
+
The number 666 is used to represent the devil, and is featured prominently in MAIDEN's artwork by the band, whose classic third album is titled "The Number Of The Beast".
|
1907
|
+
|
1908
|
+
The petition was later updated to state that the demand for her transfer is not because of her love for metal, but for "openly displaying her own handmade sign with the 666 clearly displayed on it".
|
1909
|
+
|
1910
|
+
The creator of the original petition wrote: "Sharon knows full well what she did was simply inappropriate, unnecessary and not professional but has yet to publicly admit so and is willing to allow people to believe a completely different story, making very real concerns seem petty."
|
1911
|
+
|
1912
|
+
Meanwhile, a counter-petition supporting Burns garnered over 20,000 signatures.
|
1913
|
+
|
1914
|
+
"It is ridiculous that a couple of parents judge her role as a principal only based on an Instagram post. (About liking the band IRON MAIDEN. That's it.) Eden High School is a public school. Not a Christian school," the petition titled "We need Mrs Burns" stated. "She has made Eden a safe space for so many people. She spreads nothing but love and kindness."
|
1915
|
+
|
1916
|
+
After the complaints were aired, the District School Board of Niagara spoke with Burns and the parents who launched the petition, and the issue is over as far as the board is concerned, Kim Sweeney, the board's chief communications officer, told the National Post. No disciplinary action or policy changes were needed.
|
1917
|
+
|
1918
|
+
"Our belief is that taste in music is subjective and we support that both students and staff enjoy a wide variety of genres," Sweeney said.
|
1919
|
+
|
1920
|
+
The original petition has since been removed.
|
1921
|
+
MULTI_LINE_STRING
|
1720
1922
|
end
|
1721
1923
|
|
1924
|
+
attr_accessor :document
|
1925
|
+
|
1722
1926
|
attr_accessor :foreground
|
1723
1927
|
|
1724
1928
|
def foreground_options
|
@@ -1731,15 +1935,65 @@ class HelloText
|
|
1731
1935
|
[BACKGROUND_PROMPT] + COLOR_OPTIONS
|
1732
1936
|
end
|
1733
1937
|
|
1938
|
+
attr_accessor :font_family
|
1939
|
+
|
1940
|
+
def font_family_options
|
1941
|
+
[FONT_FAMILY_PROMPT] + FONT_FAMILY_OPTIONS
|
1942
|
+
end
|
1943
|
+
|
1944
|
+
attr_accessor :font_size
|
1945
|
+
|
1946
|
+
def font_size_options
|
1947
|
+
[FONT_SIZE_PROMPT] + (9..64).to_a.map(&:to_s)
|
1948
|
+
end
|
1949
|
+
|
1734
1950
|
def launch
|
1735
1951
|
root {
|
1736
1952
|
title 'Hello, Text!'
|
1953
|
+
width 1280
|
1954
|
+
height 800
|
1737
1955
|
|
1738
1956
|
frame {
|
1739
1957
|
grid row: 0, column: 0
|
1740
1958
|
|
1959
|
+
label {
|
1960
|
+
grid row: 0, column: 0, columnspan: 17
|
1961
|
+
text 'Select a region of text and then apply formatting from the toolbar'
|
1962
|
+
}
|
1963
|
+
|
1964
|
+
column_index = -1
|
1965
|
+
|
1966
|
+
combobox {
|
1967
|
+
grid row: 1, column: column_index += 1, column_weight: 1
|
1968
|
+
readonly true
|
1969
|
+
text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value) }]
|
1970
|
+
}
|
1971
|
+
|
1972
|
+
combobox {
|
1973
|
+
grid row: 1, column: column_index += 1, column_weight: 1
|
1974
|
+
readonly true
|
1975
|
+
text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value) }]
|
1976
|
+
}
|
1977
|
+
|
1978
|
+
combobox {
|
1979
|
+
grid row: 1, column: column_index += 1, column_weight: 1
|
1980
|
+
readonly true
|
1981
|
+
text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value) }]
|
1982
|
+
}
|
1983
|
+
|
1984
|
+
combobox {
|
1985
|
+
grid row: 1, column: column_index += 1, column_weight: 1
|
1986
|
+
readonly true
|
1987
|
+
text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value) }]
|
1988
|
+
}
|
1989
|
+
|
1990
|
+
separator {
|
1991
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
1992
|
+
orient 'vertical'
|
1993
|
+
}
|
1994
|
+
|
1741
1995
|
button {
|
1742
|
-
grid row:
|
1996
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
1743
1997
|
text 'B'
|
1744
1998
|
style font: {weight: 'bold'}
|
1745
1999
|
|
@@ -1749,7 +2003,7 @@ class HelloText
|
|
1749
2003
|
}
|
1750
2004
|
|
1751
2005
|
button {
|
1752
|
-
grid row:
|
2006
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
1753
2007
|
text 'I'
|
1754
2008
|
style font: {slant: 'italic'}
|
1755
2009
|
|
@@ -1759,7 +2013,7 @@ class HelloText
|
|
1759
2013
|
}
|
1760
2014
|
|
1761
2015
|
button {
|
1762
|
-
grid row:
|
2016
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
1763
2017
|
text 'U'
|
1764
2018
|
style font: {underline: true}
|
1765
2019
|
|
@@ -1768,48 +2022,113 @@ class HelloText
|
|
1768
2022
|
end
|
1769
2023
|
}
|
1770
2024
|
|
1771
|
-
|
1772
|
-
grid row:
|
1773
|
-
|
1774
|
-
text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value) }]
|
2025
|
+
separator {
|
2026
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2027
|
+
orient 'vertical'
|
1775
2028
|
}
|
1776
2029
|
|
1777
|
-
|
1778
|
-
grid row:
|
1779
|
-
|
1780
|
-
text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'black' : value) }]
|
1781
|
-
}
|
1782
|
-
}
|
1783
|
-
|
1784
|
-
@text = text {
|
1785
|
-
grid row: 1, column: 0, row_weight: 1
|
1786
|
-
wrap 'word'
|
1787
|
-
text <<~MULTI_LINE_STRING
|
1788
|
-
According to the National Post, a heavy metal-loving high school principal in Canada will be allowed to keep her job, days after a public campaign to oust her made headlines around the globe.
|
1789
|
-
|
1790
|
-
Parents at Eden High School in St. Catharines, Ontario launched a petition to remove principal Sharon Burns after discovering she's an IRON MAIDEN fan.
|
1791
|
-
|
1792
|
-
The petition, titled "Eden High School Principal, Sharon Burns, Needs to Be Transferred Immediately!" read, "We are deeply disturbed that the principal assigned to the school blatantly showed Satanic symbols and her allegiance to Satanic practices on her public social media platforms where all the students can see them under @edenprincipal (not her personal account)."
|
1793
|
-
|
1794
|
-
More than 500 people signed the petition to transfer Burns after she posted a picture of herself flashing the "devil horns" hand sign with a doll of the MAIDEN zombie mascot Eddie behind her as well as a personalized license plate reading "IRNMADEN" and a handwritten note that reads "Eddie 666" on a car's dashboard.
|
2030
|
+
button {
|
2031
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2032
|
+
image File.expand_path("images/cut.png", __dir__), subsample: 32
|
1795
2033
|
|
2034
|
+
on('command') do
|
2035
|
+
@text.text_cut
|
2036
|
+
end
|
2037
|
+
}
|
2038
|
+
|
2039
|
+
button {
|
2040
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2041
|
+
image File.expand_path("images/copy.png", __dir__), subsample: 32
|
1796
2042
|
|
1797
|
-
|
2043
|
+
on('command') do
|
2044
|
+
@text.text_copy
|
2045
|
+
end
|
2046
|
+
}
|
2047
|
+
|
2048
|
+
button {
|
2049
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2050
|
+
image File.expand_path("images/paste.png", __dir__), subsample: 32
|
1798
2051
|
|
1799
|
-
|
2052
|
+
on('command') do
|
2053
|
+
@text.text_paste
|
2054
|
+
end
|
2055
|
+
}
|
2056
|
+
|
2057
|
+
separator {
|
2058
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2059
|
+
orient 'vertical'
|
2060
|
+
}
|
2061
|
+
|
2062
|
+
button {
|
2063
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2064
|
+
image File.expand_path("images/align-left.png", __dir__), subsample: 32
|
1800
2065
|
|
1801
|
-
|
2066
|
+
on('command') do
|
2067
|
+
@text.add_selection_format('justify', 'left')
|
2068
|
+
end
|
2069
|
+
}
|
2070
|
+
|
2071
|
+
button {
|
2072
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2073
|
+
image File.expand_path("images/align-center.png", __dir__), subsample: 32
|
1802
2074
|
|
1803
|
-
|
2075
|
+
on('command') do
|
2076
|
+
@text.add_selection_format('justify', 'center')
|
2077
|
+
end
|
2078
|
+
}
|
2079
|
+
|
2080
|
+
button {
|
2081
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2082
|
+
image File.expand_path("images/align-right.png", __dir__), subsample: 32
|
1804
2083
|
|
1805
|
-
|
2084
|
+
on('command') do
|
2085
|
+
@text.add_selection_format('justify', 'right')
|
2086
|
+
end
|
2087
|
+
}
|
2088
|
+
|
2089
|
+
separator {
|
2090
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2091
|
+
orient 'vertical'
|
2092
|
+
}
|
2093
|
+
|
2094
|
+
button {
|
2095
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2096
|
+
image File.expand_path("images/undo.png", __dir__), subsample: 32
|
1806
2097
|
|
1807
|
-
|
2098
|
+
on('command') do
|
2099
|
+
@text.edit_undo
|
2100
|
+
end
|
2101
|
+
}
|
2102
|
+
|
2103
|
+
button {
|
2104
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2105
|
+
image File.expand_path("images/redo.png", __dir__), subsample: 32
|
1808
2106
|
|
1809
|
-
|
2107
|
+
on('command') do
|
2108
|
+
@text.edit_redo
|
2109
|
+
end
|
2110
|
+
}
|
2111
|
+
|
2112
|
+
separator {
|
2113
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2114
|
+
orient 'vertical'
|
2115
|
+
}
|
2116
|
+
|
2117
|
+
button {
|
2118
|
+
grid row: 1, column: column_index += 1, column_weight: 0
|
2119
|
+
image File.expand_path("images/picture.png", __dir__), subsample: 32
|
1810
2120
|
|
1811
|
-
|
1812
|
-
|
2121
|
+
on('command') do
|
2122
|
+
@text.get_open_file_to_insert_image
|
2123
|
+
end
|
2124
|
+
}
|
2125
|
+
}
|
2126
|
+
|
2127
|
+
@text = text {
|
2128
|
+
grid row: 1, column: 0, row_weight: 1
|
2129
|
+
wrap 'word'
|
2130
|
+
undo true
|
2131
|
+
value <=> [self, :document]
|
1813
2132
|
}
|
1814
2133
|
}.open
|
1815
2134
|
end
|
@@ -1834,6 +2153,8 @@ Glimmer app:
|
|
1834
2153
|
|
1835
2154
|

|
1836
2155
|
|
2156
|
+

|
2157
|
+
|
1837
2158
|
### Hello, Spinbox!
|
1838
2159
|
|
1839
2160
|
Glimmer code (from [samples/hello/hello_spinbox.rb](samples/hello/hello_spinbox.rb)):
|
@@ -2152,22 +2473,195 @@ Glimmer app:
|
|
2152
2473
|
|
2153
2474
|

|
2154
2475
|
|
2155
|
-
|
2476
|
+
### Hello, Built-in Dialog!
|
2156
2477
|
|
2157
|
-
|
2478
|
+
Glimmer code (from [samples/hello/hello_built_in_dialog.rb](samples/hello/hello_built_in_dialog.rb)):
|
2158
2479
|
|
2159
|
-
|
2480
|
+
```ruby
|
2481
|
+
require 'glimmer-dsl-tk'
|
2160
2482
|
|
2161
|
-
|
2483
|
+
include Glimmer
|
2162
2484
|
|
2163
|
-
|
2485
|
+
root { |w|
|
2486
|
+
title 'Hello, Built-in Dialog!'
|
2487
|
+
width 400
|
2488
|
+
height 400
|
2489
|
+
x 150
|
2490
|
+
y 150
|
2491
|
+
|
2492
|
+
frame {
|
2493
|
+
%w[get_open_file get_multiple_open_file get_save_file choose_directory choose_color].each do |dialog|
|
2494
|
+
button {
|
2495
|
+
text dialog.split('_').map(&:capitalize).join(' ')
|
2496
|
+
|
2497
|
+
on('command') do
|
2498
|
+
result = send(dialog, parent: w)
|
2499
|
+
@result_label.text = [result].flatten.join("\n")
|
2500
|
+
end
|
2501
|
+
}
|
2502
|
+
end
|
2503
|
+
|
2504
|
+
button {
|
2505
|
+
text 'Choose Font'
|
2506
|
+
|
2507
|
+
on('command') do
|
2508
|
+
choose_font(family: 'Courier New', size: '30', weight: 'bold') do |chosen_font|
|
2509
|
+
@result_label.text = chosen_font
|
2510
|
+
end
|
2511
|
+
end
|
2512
|
+
}
|
2513
|
+
}
|
2514
|
+
|
2515
|
+
frame {
|
2516
|
+
grid sticky: 'nsew', padx: 15, pady: 15
|
2517
|
+
|
2518
|
+
label {
|
2519
|
+
grid row: 0, column: 0
|
2520
|
+
text 'Result:'
|
2521
|
+
}
|
2522
|
+
|
2523
|
+
@result_label = label {
|
2524
|
+
grid row: 0, column: 1
|
2525
|
+
}
|
2526
|
+
}
|
2527
|
+
}.open
|
2528
|
+
```
|
2164
2529
|
|
2165
|
-
|
2530
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
2531
|
+
|
2532
|
+
```
|
2533
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_built_in_dialog'"
|
2534
|
+
```
|
2535
|
+
|
2536
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
2537
|
+
|
2538
|
+
```
|
2539
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_built_in_dialog.rb
|
2540
|
+
```
|
2541
|
+
|
2542
|
+
Glimmer app:
|
2543
|
+
|
2544
|
+

|
2545
|
+

|
2546
|
+
|
2547
|
+

|
2548
|
+

|
2549
|
+
|
2550
|
+

|
2551
|
+

|
2552
|
+
|
2553
|
+
### Hello, Separator!
|
2554
|
+
|
2555
|
+
Glimmer code (from [samples/hello/hello_separator.rb](samples/hello/hello_separator.rb)):
|
2556
|
+
|
2557
|
+
```ruby
|
2558
|
+
require 'glimmer-dsl-tk'
|
2559
|
+
|
2560
|
+
include Glimmer
|
2561
|
+
|
2562
|
+
root {
|
2563
|
+
title 'Hello, Separator!'
|
2564
|
+
width 200
|
2565
|
+
height 200
|
2566
|
+
|
2567
|
+
label {
|
2568
|
+
grid row: 0, column: 0, min_width: 100, min_height: 100, column_weight: 0, sticky: 'nsew'
|
2569
|
+
text 'Label 1'
|
2570
|
+
anchor 'center'
|
2571
|
+
}
|
2572
|
+
|
2573
|
+
separator {
|
2574
|
+
grid row: 0, column: 1
|
2575
|
+
orient 'vertical'
|
2576
|
+
}
|
2577
|
+
|
2578
|
+
label {
|
2579
|
+
grid row: 0, column: 2, min_width: 100, min_height: 100, sticky: 'nsew'
|
2580
|
+
text 'Label 2'
|
2581
|
+
anchor 'center'
|
2582
|
+
}
|
2583
|
+
|
2584
|
+
separator {
|
2585
|
+
grid row: 1, column: 0, column_span: 3
|
2586
|
+
# orient 'horizontal' # default
|
2587
|
+
}
|
2588
|
+
|
2589
|
+
label {
|
2590
|
+
grid row: 2, column: 0, min_width: 100, min_height: 100, sticky: 'nsew'
|
2591
|
+
text 'Label 3'
|
2592
|
+
anchor 'center'
|
2593
|
+
}
|
2594
|
+
|
2595
|
+
separator {
|
2596
|
+
grid row: 2, column: 1
|
2597
|
+
orient 'vertical'
|
2598
|
+
}
|
2599
|
+
|
2600
|
+
label {
|
2601
|
+
grid row: 2, column: 2, min_width: 100, min_height: 100, sticky: 'nsew'
|
2602
|
+
text 'Label 4'
|
2603
|
+
anchor 'center'
|
2604
|
+
}
|
2605
|
+
}.open
|
2606
|
+
```
|
2607
|
+
|
2608
|
+
Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
2609
|
+
|
2610
|
+
```
|
2611
|
+
ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_separator'"
|
2612
|
+
```
|
2613
|
+
|
2614
|
+
Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
|
2615
|
+
|
2616
|
+
```
|
2617
|
+
ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_separator.rb
|
2618
|
+
```
|
2619
|
+
|
2620
|
+
Glimmer app:
|
2621
|
+
|
2622
|
+

|
2623
|
+
|
2624
|
+
## Applications
|
2625
|
+
|
2626
|
+
### Glimmer Tk Calculator
|
2627
|
+
|
2628
|
+
"I wanted to try how it feels to write an UI in glimmer-dsl-tk so I decided to write an alternative version of the [Glimmer Calculator](https://github.com/AndyObtiva/glimmer-cs-calculator) that uses [Tk]([Tk](https://www.tcl.tk/)) and runs in the regular [MRI Ruby interpreter](https://www.ruby-lang.org/en/)." - [Ancor Gonzalez Sosa](https://github.com/ancorgs)
|
2629
|
+
|
2630
|
+
https://github.com/ancorgs/glimmer-tk-calculator
|
2631
|
+
|
2632
|
+

|
2633
|
+
|
2634
|
+
### Y3network Ruby UI
|
2635
|
+
|
2636
|
+
https://github.com/ancorgs/y3network-ruby-ui
|
2637
|
+
|
2638
|
+
### CryptoPunks GUI
|
2639
|
+
|
2640
|
+
This is a Graphical User Interface for the famous [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
|
2641
|
+
|
2642
|
+
https://github.com/AndyObtiva/cryptopunks-gui
|
2643
|
+
|
2644
|
+

|
2166
2645
|
|
2167
2646
|
## Process
|
2168
2647
|
|
2169
2648
|
[Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
|
2170
2649
|
|
2650
|
+
## Resources
|
2651
|
+
|
2652
|
+
- [Tk Tutorial](https://tkdocs.com/tutorial/index.html)
|
2653
|
+
- [Code Master Blog](https://andymaleh.blogspot.com/search/label/Tk)
|
2654
|
+
|
2655
|
+
## Help
|
2656
|
+
|
2657
|
+
### Issues
|
2658
|
+
|
2659
|
+
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).
|
2660
|
+
|
2661
|
+
### Chat
|
2662
|
+
|
2663
|
+
If you need live help, try to [](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2664
|
+
|
2171
2665
|
## Planned Features and Feature Suggestions
|
2172
2666
|
|
2173
2667
|
These features have been planned or suggested. You might see them in a future version of [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk). You are welcome to contribute more feature suggestions.
|