glimmer-dsl-tk 0.0.26 → 0.0.30

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.
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.26
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.30
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)
@@ -10,11 +10,9 @@
10
10
 
11
11
  [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [Tk](https://www.tcl.tk/) enables desktop development with [Glimmer](https://github.com/AndyObtiva/glimmer) in [Ruby](https://github.com/ruby/ruby).
12
12
 
13
- [Tcl/Tk](https://www.tcl.tk/) has recently improved by gaining native looking themed widgets on Mac, Windows, and Linux in [Tk version 8.5](https://www.tcl.tk/software/tcltk/8.5.html#:~:text=Highlights%20of%20Tk%208.5&text=Font%20rendering%3A%20Now%20uses%20anti,and%20window%20layout%2C%20and%20more.).
13
+ [Tcl/Tk](https://www.tcl.tk/) has recently improved by gaining native looking themed widgets on Mac, Windows, and Linux in [Tk version 8.5](https://www.tcl.tk/software/tcltk/8.5.html#:~:text=Highlights%20of%20Tk%208.5&text=Font%20rendering%3A%20Now%20uses%20anti,and%20window%20layout%2C%20and%20more.). Additionally, [Ruby](https://www.ruby-lang.org/en/) 3.0 Ractor (formerly known as [Guilds](https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/)) supports truly parallel multi-threading, making both [MRI](https://github.com/ruby/ruby) and [Tk](https://www.tcl.tk/) finally viable for support in [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library) as an alternative to [JRuby on SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
14
14
 
15
- Additionally, [Ruby](https://www.ruby-lang.org/en/) 3.0 Ractor (formerly known as [Guilds](https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/)) supports truly parallel multi-threading, making both [MRI](https://github.com/ruby/ruby) and [Tk](https://www.tcl.tk/) finally viable for support in [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library) as an alternative to [JRuby on SWT](https://github.com/AndyObtiva/glimmer-dsl-swt).
16
-
17
- The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a plethora of high quality reusable widgets for the Enterprise (such as [Nebula](https://www.eclipse.org/nebula/)), [Tk](https://www.tcl.tk/) enables very fast app startup time and a small memory footprint via [MRI Ruby](https://www.ruby-lang.org/en/).
15
+ The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a plethora of high quality reusable widgets for the Enterprise (such as [Nebula](https://github.com/AndyObtiva/glimmer-cw-nebula)), [Tk](https://www.tcl.tk/) has a very fast app startup time and a small memory footprint courtesy of [MRI Ruby](https://www.ruby-lang.org/en/).
18
16
 
19
17
  [Glimmer DSL for Tk](https://github.com/AndyObtiva/glimmer-dsl-tk) aims to provide a DSL similar to the [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) to enable more productive desktop development in Ruby with:
20
18
  - Declarative DSL syntax that visually maps to the GUI widget hierarchy
@@ -76,11 +74,16 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
76
74
  - [Supported Widgets](#supported-widgets)
77
75
  - [Common Attributes](#common-attributes)
78
76
  - [Common Themed Widget States](#common-themed-widget-states)
77
+ - [Text API](#text-api)
78
+ - [Drag and Drop API](#drag-and-drop-api)
79
79
  - [Smart Defaults and Conventions](#smart-defaults-and-conventions)
80
80
  - [Grid Layout](#grid-layout)
81
- - [Label/Button Image](#labelbutton-image)
81
+ - [Image Attribute](#image-attribute)
82
+ - [Frame Padding](#frame-padding)
82
83
  - [Notebook Frame](#notebook-frame)
83
84
  - [Icon Photo](#icon-photo)
85
+ - [Root Background](#root-background)
86
+ - [Text Defaults](#text-defaults)
84
87
  - [The Grid Geometry Manager](#the-grid-geometry-manager)
85
88
  - [Data-Binding](#data-binding)
86
89
  - [Label Data-Binding](#label-data-binding)
@@ -88,6 +91,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
88
91
  - [List Single Selection Data-Binding](#list-single-selection-data-binding)
89
92
  - [List Multi Selection Data-Binding](#list-multi-selection-data-binding)
90
93
  - [Entry Data-Binding](#entry-data-binding)
94
+ - [Text Data-Binding](#text-data-binding)
91
95
  - [Spinbox Data-Binding](#spinbox-data-binding)
92
96
  - [Checkbutton Data-Binding](#checkbutton-data-binding)
93
97
  - [Radiobutton Data-Binding](#radiobutton-data-binding)
@@ -110,10 +114,17 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
110
114
  - [Hello, Text!](#hello-text)
111
115
  - [Hello, Spinbox!](#hello-spinbox)
112
116
  - [Hello, Computed!](#hello-computed)
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)
113
125
  - [Help](#help)
114
126
  - [Issues](#issues)
115
127
  - [Chat](#chat)
116
- - [Process](#process)
117
128
  - [Planned Features and Feature Suggestions](#planned-features-and-feature-suggestions)
118
129
  - [Change Log](#change-log)
119
130
  - [Contributing](#contributing)
@@ -146,7 +157,7 @@ gem install glimmer-dsl-tk
146
157
 
147
158
  Add the following to `Gemfile`:
148
159
  ```
149
- gem 'glimmer-dsl-tk', '~> 0.0.26'
160
+ gem 'glimmer-dsl-tk', '~> 0.0.30'
150
161
  ```
151
162
 
152
163
  And, then run:
@@ -257,8 +268,14 @@ keyword(args) | attributes | event bindings & callbacks
257
268
  ------------- | ---------- | ---------
258
269
  `button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command {}`
259
270
  `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 {}`
271
+ `choose_color(options = nil)` | None | None
272
+ `choose_directory(options = nil)` | None | None
273
+ `choose_font(options = nil) {|font| ... }` | None | None
260
274
  `combobox` | `state`, `text` | `'ComboboxSelected'`
261
275
  `entry` | `width`, `text`, `validate`, `show` (`'none', 'focus', 'focusin', 'focusout', 'key', or 'all'`) | `'validate'`, `'invalid'`, `'change'`, `validatecommand {}`, `invalidcommand {}`
276
+ `get_multiple_open_file(options = nil)` | None | None
277
+ `get_open_file(options = nil)` | None | None
278
+ `get_save_file(options = nil)` | None | None
262
279
  `spinbox` | `text`, `from`, `to`, `increment`, `format`, [more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `command {}`, `'increment'`, `'decrement'`
263
280
  `frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
264
281
  `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
@@ -267,7 +284,11 @@ keyword(args) | attributes | event bindings & callbacks
267
284
  `notebook` | None | None
268
285
  `radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
269
286
  `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'`
287
+ `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
+
290
+ Options for `get_open_file` and `get_multiple_open_file` include:
291
+ - `filetypes`: `Hash` of `'Group Name' => '.ext'` entries (e.g. `filetypes: {'PNG Images' => '.png'}`
271
292
 
272
293
  #### Common Attributes
273
294
 
@@ -317,6 +338,80 @@ keyword(args) | attributes | event bindings & callbacks
317
338
  - `invalid?`
318
339
  - `hover?`
319
340
 
341
+ #### Text API
342
+
343
+ 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
+
345
+ - `add_format(region_start, region_end, option, value)`
346
+ - `remove_format(region_start, region_end, option, value)`
347
+ - `toggle_format(region_start, region_end, option, value)`
348
+ - `add_font_format(region_start, region_end, font_option, value)`
349
+ - `remove_font_format(region_start, region_end, font_option, value)`
350
+ - `toggle_font_format(region_start, region_end, font_option, value)`
351
+ - `add_selection_format(region_start, region_end, option, value)`
352
+ - `remove_selection_format(region_start, region_end, option, value)`
353
+ - `toggle_selection_format(region_start, region_end, option, value)`
354
+ - `add_selection_font_format(region_start, region_end, font_option, value)`
355
+ - `remove_selection_font_format(region_start, region_end, font_option, value)`
356
+ - `toggle_selection_font_format(region_start, region_end, font_option, value)`
357
+ - `text#insert_image(text_index, *image_args)`: inserts image into `text` `value` content at `text_index` location (e.g. `'insert'`)
358
+ - `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
+ Available options:
361
+
362
+ - `background`
363
+ - `bgstipple`
364
+ - `borderwidth`
365
+ - `elide`
366
+ - `fgstipple`
367
+ - `foreground`
368
+ - `justify`
369
+ - `lmargin1`
370
+ - `lmargin2`
371
+ - `offset`
372
+ - `overstrike`
373
+ - `relief`
374
+ - `rmargin`
375
+ - `spacing1`
376
+ - `spacing2`
377
+ - `spacing3`
378
+ - `tabs`
379
+ - `tabstyle`
380
+ - `underline`
381
+ - `wrap`
382
+
383
+ Available font options:
384
+
385
+ - `family` (default: `'Courier New'`)
386
+ - `size` (default: `13`)
387
+ - `weight` (default: `'normal'`) (e.g. `'bold'`)
388
+ - `slant` (default: `'roman'`) (e.g. `'italic`')
389
+ - `underline` (default: `false`)
390
+ - `overstrike` (default: `false`)
391
+
392
+ Other useful built-in API methods:
393
+
394
+ - `text_cut`
395
+ - `text_copy`
396
+ - `text_paste`
397
+ - `text_edit_undo`
398
+ - `text_edit_redo`
399
+
400
+ Check out the [Hello, Text!](#hello-text) sample for a good demonstration of the `text` widget features.
401
+
402
+ #### Drag and Drop API
403
+
404
+ Drag and drop works by simply designating a widget as a drag source with attribute `drag_source true`
405
+
406
+ Alternatively, add listeners:
407
+ - `on_drag_start {|event| ...}`: fires on drag start receiving an `event` arg to set `data` and configure `source`
408
+ - `on_drag_motion {|event| ...}`: fires on drag motion receiving an `event` arg to check `event#drop_accepted`, and configure `source` and `tooltip`
409
+
410
+ On the drop target, you simply define:
411
+ - `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.
412
+
413
+ Learn more at the [Hello, Drag and Drop!](#hello-drag-and-drop) sample.
414
+
320
415
  ### Smart Defaults and Conventions
321
416
 
322
417
  #### Event Bindings
@@ -331,9 +426,19 @@ Also, any widget that is the first in a series of siblings has `column_weight` a
331
426
 
332
427
  To override that behavior, you may set alternative `grid` keyword args if needed (e.g. `grid sticky: '', column_weight: 0` disables the smart defaults).
333
428
 
334
- #### Label/Button Image
429
+ #### Image Attribute
430
+
431
+ Widget `image` attribute (e.g. `label` `image`) can accept image path directly as an alternative to `TkPhotoImage` object in addition to key values for automatic processing of image:
432
+ - `subsample(x_divider, y_divider)`: Specifies that the source image should be reduced in size by using only every xth pixel in the X direction and yth pixel in the Y direction. Negative values will cause the image to be flipped about the Y or X axes, respectively. If y is not given, the default value is the same as x.
433
+ - `zoom(x_multiplier, y_multiplier)`: Specifies that the source region should be magnified by a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x. With this option, each pixel in the source image will be expanded into a block of x x y pixels in the destination image, all the same color. x and y must be greater than 0.
434
+ - `from(x1, y1, x2, y2)`: Specifies a rectangular sub-region of the source image to be copied. (x1,y1) and (x2,y2) specify diagonally opposite corners of the rectangle. If x2 and y2 are not specified, the default value is the bottom-right corner of the source image. The pixels copied will include the left and top edges of the specified rectangle but not the bottom or right edges. If the :from option is not given, the default is the whole source image.
435
+ - `to(x1, y1, x2, y2)`: Specifies a rectangular sub-region of the destination image to be affected. (x1,y1) and (x2,y2) specify diagonally opposite corners of the rectangle. If x2 and y2 are not specified, the default value is (x1,y1) plus the size of the source region (after subsampling and zooming, if specified). If x2 and y2 are specified, the source region will be replicated if necessary to fill the destination region in a tiled fashion.
436
+ - `shrink`: Specifies that the size of the destination image should be reduced, if necessary, so that the region being copied into is at the bottom-right corner of the image. This option will not affect the width or height of the image if the user has specified a non-zero value for the :width or :height configuration option, respectively.
437
+ - `compositingrule` (can be `'overlay'` or `'set'`): Specifies how transparent pixels in the source image are combined with the destination image. When a compositing rule of <tt>overlay</tt> is set, the old contents of the destination image are visible, as if the source image were printed on a piece of transparent film and placed over the top of the destination. When a compositing rule of <tt>set</tt> is set, the old contents of the destination image are discarded and the source image is used as-is. The default compositing rule is <tt>overlay</tt>.
335
438
 
336
- Label and Button `image` attribute can accept image path directly as an alternative to `TkPhotoImage` object in addition to key values for automatic processing of image (`subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`)
439
+ #### Frame Padding
440
+
441
+ Frames have a padding of `15` all around by default to produce more user-friendly graphical user interfaces.
337
442
 
338
443
  #### Notebook Frame
339
444
 
@@ -367,6 +472,12 @@ root {
367
472
 
368
473
  `root` `background` color attribute is automatically set to `'#ececec'` on the Mac to avoid having a non-native-looking light-colored background.
369
474
 
475
+ #### Text Defaults
476
+
477
+ `text` widget has these defaults:
478
+ - `wrap = 'none'`
479
+ - `font = {family: 'Courier New'}`
480
+
370
481
  ## The Grid Geometry Manager
371
482
 
372
483
  The Grid Geometry Manager is supported via the `grid` keyword just as per the [Tk documentation](https://tkdocs.com/tutorial/grid.html), except by nesting under the widget it concerns.
@@ -386,6 +497,8 @@ Example:
386
497
  ```
387
498
 
388
499
  Extra convenience options may be passed to `grid` when using [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk):
500
+ - `column_span`: alias for `columnspan` keyword arg
501
+ - `row_span`: alias for `rowspan` keyword arg
389
502
  - `min_width`: alias for `columnminsize` being called on `TkGrid.columnconfigure`
390
503
  - `min_height`: alias for `rowminsize` being called on `TkGrid.rowconfigure`
391
504
  - `column_weight`: alias for `columnweight` being called on `TkGrid.columnconfigure`
@@ -498,45 +611,45 @@ It automatically handles all the Tk plumbing behind the scenes.
498
611
 
499
612
  More details can be found in [Hello, Entry!](#hello-entry) and [Hello, Computed!](#hello-computed) samples below.
500
613
 
501
- ### Spinbox Data-Binding
614
+ ### Text Data-Binding
502
615
 
503
616
  Example:
504
617
 
505
- This assumes a `Person` model with a `donation` attribute.
618
+ This assumes a `Person` model with a `biography` attribute.
506
619
 
507
620
  ```ruby
508
- spinbox {
509
- from 1.0 # minimum value
510
- to 150.0 # maximum value
511
- increment 5.0 # increment on up and down
512
- format '%0.2f'
513
- text <=> [person, :country]
621
+ text {
622
+ value <=> [person, :biography]
514
623
  }
515
624
  ```
516
625
 
517
- That code binds the `textvariable` value of the `spinbox` to the `donation` attribute on the `person` model.
626
+ That code binds the `value` of `text` to the `biography` attribute on the `person` model.
518
627
 
519
628
  It automatically handles all the Tk plumbing behind the scenes.
520
629
 
521
- More details can be found in [Hello, Spinbox!](#hello-spinbox) sample below.
630
+ More details can be found in [Hello, Text!](#hello-text) sample below.
522
631
 
523
- ### Text Data-Binding
632
+ ### Spinbox Data-Binding
524
633
 
525
634
  Example:
526
635
 
527
- This assumes a `Person` model with a `address` attribute.
636
+ This assumes a `Person` model with a `donation` attribute.
528
637
 
529
638
  ```ruby
530
- text {
531
- text <=> [person, :address]
639
+ spinbox {
640
+ from 1.0 # minimum value
641
+ to 150.0 # maximum value
642
+ increment 5.0 # increment on up and down
643
+ format '%0.2f'
644
+ text <=> [person, :country]
532
645
  }
533
646
  ```
534
647
 
535
- That code binds the text content of `text` to the `address` attribute on the `person` model.
648
+ That code binds the `textvariable` value of the `spinbox` to the `donation` attribute on the `person` model.
536
649
 
537
- It automatically handles all the Tk plumbing behind the scenes (including fine-grained inserts and deletes, abstracting them all away).
650
+ It automatically handles all the Tk plumbing behind the scenes.
538
651
 
539
- More details can be found in [Glimmer Meta-Sample](#samples) below.
652
+ More details can be found in [Hello, Spinbox!](#hello-spinbox) sample below.
540
653
 
541
654
  ### Checkbutton Data-Binding
542
655
 
@@ -636,6 +749,128 @@ ruby -r ./lib/glimmer-dsl-tk.rb samples/elaborate/meta_sample.rb
636
749
 
637
750
  ![glimmer dsl tk screenshot sample meta sample](images/glimmer-dsl-tk-screenshot-sample-elaborate-meta-sample.png)
638
751
 
752
+ Code:
753
+
754
+ ```ruby
755
+ require 'glimmer-dsl-tk'
756
+ require 'facets'
757
+ require 'fileutils'
758
+
759
+ class MetaSample
760
+ include Glimmer
761
+
762
+ attr_accessor :selected_sample_index
763
+
764
+ def initialize
765
+ @selected_sample_index = 0
766
+ end
767
+
768
+ def samples
769
+ if @samples.nil?
770
+ sample_files = Dir.glob(File.join(File.expand_path('../hello', __dir__), '**', 'hello_*.rb'))
771
+ sample_file_names = sample_files.map { |f| File.basename(f, '.rb') }
772
+ sample_file_names = sample_file_names.reject { |f| f == 'meta_sample' || f.match(/\d$/) }
773
+ @samples = sample_file_names.map { |f| f.underscore.titlecase }
774
+ end
775
+ @samples
776
+ end
777
+
778
+ def file_path_for(sample)
779
+ File.join(File.expand_path('../hello', __dir__), "#{sample.underscore}.rb")
780
+ end
781
+
782
+ def glimmer_dsl_tk_file
783
+ File.expand_path('../../lib/glimmer-dsl-tk', __dir__)
784
+ end
785
+
786
+ def selected_sample
787
+ samples[@selected_sample_index]
788
+ end
789
+
790
+ def run_sample(sample)
791
+ Thread.new do
792
+ command = "ruby -r #{glimmer_dsl_tk_file} #{sample} 2>&1"
793
+ result = ''
794
+ IO.popen(command) do |f|
795
+ f.each_line do |line|
796
+ result << line
797
+ puts line
798
+ $stdout.flush
799
+ end
800
+ end
801
+ ::Tk.after(100) do
802
+ message_box(parent: @root, title: 'Error Running Sample', message: result) if result.downcase.include?('error')
803
+ end
804
+ end
805
+ end
806
+
807
+ def launch
808
+ @root = root {
809
+ title 'Glimmer Meta-Sample'
810
+ width 1280
811
+ height 720
812
+
813
+ frame {
814
+ grid row: 0, column: 0, column_weight: 0, row_weight: 1
815
+
816
+ samples.each_with_index do |sample, index|
817
+ radiobutton {
818
+ text sample
819
+ variable <=> [self, :selected_sample_index, on_write: ->(v) {v ? index : selected_sample_index}, on_read: ->(v) {v == index}]
820
+
821
+ on('command') do
822
+ @selected_sample_index = index
823
+ @code_text.value = File.read(file_path_for(selected_sample))
824
+ end
825
+ }
826
+ end
827
+
828
+ frame {
829
+ button {
830
+ grid row: 0, column: 0
831
+ text 'Launch'
832
+
833
+ on('command') do
834
+ begin
835
+ parent_dir = File.join(Dir.home, '.glimmer-dsl-tk', 'samples', 'hello')
836
+ FileUtils.mkdir_p(parent_dir)
837
+ sample_file = File.join(parent_dir, "#{selected_sample.underscore}.rb")
838
+ File.write(sample_file, @code_text.value)
839
+ FileUtils.cp_r(File.expand_path('../../icons', __dir__), File.dirname(File.dirname(parent_dir)))
840
+ FileUtils.cp_r(File.expand_path('../hello/images', __dir__), parent_dir)
841
+ sample_namespace_directory = File.expand_path("../hello/#{selected_sample.underscore}", __dir__)
842
+ FileUtils.cp_r(sample_namespace_directory, parent_dir) if Dir.exist?(sample_namespace_directory)
843
+ run_sample(sample_file)
844
+ rescue => e
845
+ puts e.full_message
846
+ puts 'Unable to write code changes! Running original sample...'
847
+ run_sample(file_path_for(selected_sample))
848
+ end
849
+ end
850
+ }
851
+ button {
852
+ grid row: 0, column: 1
853
+ text 'Reset'
854
+
855
+ on('command') do
856
+ @code_text.value = File.read(file_path_for(selected_sample))
857
+ end
858
+ }
859
+ }
860
+ }
861
+
862
+ @code_text = text {
863
+ grid row: 0, column: 1, column_weight: 1
864
+ value File.read(file_path_for(selected_sample))
865
+ }
866
+ }
867
+ @root.open
868
+ end
869
+ end
870
+
871
+ MetaSample.new.launch
872
+ ```
873
+
639
874
  ### Hello, World!
640
875
 
641
876
  Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
@@ -1196,6 +1431,8 @@ Glimmer app:
1196
1431
 
1197
1432
  ### Hello, Label!
1198
1433
 
1434
+ 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>
1435
+
1199
1436
  Glimmer code (from [samples/hello/hello_label.rb](samples/hello/hello_label.rb)):
1200
1437
 
1201
1438
  ```ruby
@@ -1325,8 +1562,6 @@ root { |r|
1325
1562
  title 'Hello, Message Box!'
1326
1563
 
1327
1564
  frame {
1328
- grid sticky: 'nsew', padx: 15, pady: 15
1329
-
1330
1565
  button {
1331
1566
  text 'Please Click To Win a Surprise'
1332
1567
 
@@ -1378,8 +1613,6 @@ root { |r|
1378
1613
  }
1379
1614
 
1380
1615
  frame {
1381
- grid sticky: 'nsew', padx: 15, pady: 15
1382
-
1383
1616
  label {
1384
1617
  grid row: 0, column: 0
1385
1618
  text 'Result:'
@@ -1407,7 +1640,6 @@ ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_message_box.rb
1407
1640
  Glimmer app:
1408
1641
 
1409
1642
  ![glimmer dsl tk screenshot sample hello message box](images/glimmer-dsl-tk-screenshot-sample-hello-message-box.png)
1410
- ![glimmer dsl tk screenshot sample hello message box open](images/glimmer-dsl-tk-screenshot-sample-hello-message-box-open.png)
1411
1643
 
1412
1644
  ### Hello, Combobox!
1413
1645
 
@@ -1636,7 +1868,7 @@ Glimmer app:
1636
1868
 
1637
1869
  ### Hello, Text!
1638
1870
 
1639
- [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) automatically provides a `text` attribute for the `text` widget that enables updating its content simply without worrying about whether to manually insert by index, delete, or append.
1871
+ 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>
1640
1872
 
1641
1873
  Glimmer code (from [samples/hello/hello_text.rb](samples/hello/hello_text.rb)):
1642
1874
 
@@ -1647,14 +1879,47 @@ class HelloText
1647
1879
  include Glimmer
1648
1880
 
1649
1881
  COLOR_OPTIONS = %w[black purple blue green orange yellow red white].map(&:capitalize)
1650
- FOREGROUND_PROMPT = '<select foreground>'
1651
- BACKGROUND_PROMPT = '<select background>'
1882
+ FONT_FAMILY_OPTIONS = ::TkFont.families
1883
+ FOREGROUND_PROMPT = '<foreground>'
1884
+ BACKGROUND_PROMPT = '<background>'
1885
+ FONT_FAMILY_PROMPT = '<font family>'
1886
+ FONT_SIZE_PROMPT = '<font size>'
1652
1887
 
1653
1888
  def initialize
1654
1889
  @foreground = FOREGROUND_PROMPT
1655
1890
  @background = BACKGROUND_PROMPT
1891
+ @font_family = FONT_FAMILY_PROMPT
1892
+ @font_size = FONT_SIZE_PROMPT
1893
+ @document = <<~MULTI_LINE_STRING
1894
+ 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.
1895
+
1896
+ 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.
1897
+
1898
+ 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)."
1899
+
1900
+ 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.
1901
+
1902
+
1903
+ 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".
1904
+
1905
+ 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".
1906
+
1907
+ 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."
1908
+
1909
+ Meanwhile, a counter-petition supporting Burns garnered over 20,000 signatures.
1910
+
1911
+ "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."
1912
+
1913
+ 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.
1914
+
1915
+ "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.
1916
+
1917
+ The original petition has since been removed.
1918
+ MULTI_LINE_STRING
1656
1919
  end
1657
1920
 
1921
+ attr_accessor :document
1922
+
1658
1923
  attr_accessor :foreground
1659
1924
 
1660
1925
  def foreground_options
@@ -1667,54 +1932,200 @@ class HelloText
1667
1932
  [BACKGROUND_PROMPT] + COLOR_OPTIONS
1668
1933
  end
1669
1934
 
1935
+ attr_accessor :font_family
1936
+
1937
+ def font_family_options
1938
+ [FONT_FAMILY_PROMPT] + FONT_FAMILY_OPTIONS
1939
+ end
1940
+
1941
+ attr_accessor :font_size
1942
+
1943
+ def font_size_options
1944
+ [FONT_SIZE_PROMPT] + (9..64).to_a.map(&:to_s)
1945
+ end
1946
+
1670
1947
  def launch
1671
1948
  root {
1672
1949
  title 'Hello, Text!'
1950
+ width 1280
1951
+ height 800
1673
1952
 
1674
1953
  frame {
1675
1954
  grid row: 0, column: 0
1676
1955
 
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
+ column_index = -1
1962
+
1963
+ combobox {
1964
+ grid row: 1, column: column_index += 1, column_weight: 1
1965
+ readonly true
1966
+ text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value) }]
1967
+ }
1968
+
1677
1969
  combobox {
1678
- grid row: 0, column: 0, column_weight: 1
1970
+ grid row: 1, column: column_index += 1, column_weight: 1
1971
+ readonly true
1972
+ text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value) }]
1973
+ }
1974
+
1975
+ combobox {
1976
+ grid row: 1, column: column_index += 1, column_weight: 1
1679
1977
  readonly true
1680
1978
  text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value) }]
1681
1979
  }
1682
1980
 
1683
1981
  combobox {
1684
- grid row: 0, column: 1, column_weight: 1
1982
+ grid row: 1, column: column_index += 1, column_weight: 1
1685
1983
  readonly true
1686
- text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'black' : value) }]
1984
+ text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value) }]
1687
1985
  }
1688
- }
1689
-
1690
- @text = text {
1691
- grid row: 1, column: 0, row_weight: 1
1692
- text <<~MULTI_LINE_STRING
1693
- 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.
1986
+
1987
+ separator {
1988
+ grid row: 1, column: column_index += 1, column_weight: 0
1989
+ orient 'vertical'
1990
+ }
1991
+
1992
+ button {
1993
+ grid row: 1, column: column_index += 1, column_weight: 0
1994
+ text 'B'
1995
+ style font: {weight: 'bold'}
1694
1996
 
1695
- 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.
1997
+ on('command') do
1998
+ @text.toggle_selection_font_format('weight', 'bold')
1999
+ end
2000
+ }
2001
+
2002
+ button {
2003
+ grid row: 1, column: column_index += 1, column_weight: 0
2004
+ text 'I'
2005
+ style font: {slant: 'italic'}
1696
2006
 
1697
- 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)."
2007
+ on('command') do
2008
+ @text.toggle_selection_font_format('slant', 'italic')
2009
+ end
2010
+ }
2011
+
2012
+ button {
2013
+ grid row: 1, column: column_index += 1, column_weight: 0
2014
+ text 'U'
2015
+ style font: {underline: true}
1698
2016
 
1699
- 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.
2017
+ on('command') do
2018
+ @text.toggle_selection_font_format('underline', true)
2019
+ end
2020
+ }
2021
+
2022
+ separator {
2023
+ grid row: 1, column: column_index += 1, column_weight: 0
2024
+ orient 'vertical'
2025
+ }
2026
+
2027
+ button {
2028
+ grid row: 1, column: column_index += 1, column_weight: 0
2029
+ image File.expand_path("images/cut.png", __dir__), subsample: 32
1700
2030
 
2031
+ on('command') do
2032
+ @text.text_cut
2033
+ end
2034
+ }
2035
+
2036
+ button {
2037
+ grid row: 1, column: column_index += 1, column_weight: 0
2038
+ image File.expand_path("images/copy.png", __dir__), subsample: 32
1701
2039
 
1702
- 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".
2040
+ on('command') do
2041
+ @text.text_copy
2042
+ end
2043
+ }
2044
+
2045
+ button {
2046
+ grid row: 1, column: column_index += 1, column_weight: 0
2047
+ image File.expand_path("images/paste.png", __dir__), subsample: 32
1703
2048
 
1704
- 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".
2049
+ on('command') do
2050
+ @text.text_paste
2051
+ end
2052
+ }
2053
+
2054
+ separator {
2055
+ grid row: 1, column: column_index += 1, column_weight: 0
2056
+ orient 'vertical'
2057
+ }
2058
+
2059
+ button {
2060
+ grid row: 1, column: column_index += 1, column_weight: 0
2061
+ image File.expand_path("images/align-left.png", __dir__), subsample: 32
1705
2062
 
1706
- 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."
2063
+ on('command') do
2064
+ @text.add_selection_format('justify', 'left')
2065
+ end
2066
+ }
2067
+
2068
+ button {
2069
+ grid row: 1, column: column_index += 1, column_weight: 0
2070
+ image File.expand_path("images/align-center.png", __dir__), subsample: 32
1707
2071
 
1708
- Meanwhile, a counter-petition supporting Burns garnered over 20,000 signatures.
2072
+ on('command') do
2073
+ @text.add_selection_format('justify', 'center')
2074
+ end
2075
+ }
2076
+
2077
+ button {
2078
+ grid row: 1, column: column_index += 1, column_weight: 0
2079
+ image File.expand_path("images/align-right.png", __dir__), subsample: 32
1709
2080
 
1710
- "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."
2081
+ on('command') do
2082
+ @text.add_selection_format('justify', 'right')
2083
+ end
2084
+ }
2085
+
2086
+ separator {
2087
+ grid row: 1, column: column_index += 1, column_weight: 0
2088
+ orient 'vertical'
2089
+ }
2090
+
2091
+ button {
2092
+ grid row: 1, column: column_index += 1, column_weight: 0
2093
+ image File.expand_path("images/undo.png", __dir__), subsample: 32
1711
2094
 
1712
- 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.
2095
+ on('command') do
2096
+ @text.edit_undo
2097
+ end
2098
+ }
2099
+
2100
+ button {
2101
+ grid row: 1, column: column_index += 1, column_weight: 0
2102
+ image File.expand_path("images/redo.png", __dir__), subsample: 32
1713
2103
 
1714
- "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.
2104
+ on('command') do
2105
+ @text.edit_redo
2106
+ end
2107
+ }
2108
+
2109
+ separator {
2110
+ grid row: 1, column: column_index += 1, column_weight: 0
2111
+ orient 'vertical'
2112
+ }
2113
+
2114
+ button {
2115
+ grid row: 1, column: column_index += 1, column_weight: 0
2116
+ image File.expand_path("images/picture.png", __dir__), subsample: 32
1715
2117
 
1716
- The original petition has since been removed.
1717
- MULTI_LINE_STRING
2118
+ on('command') do
2119
+ @text.get_open_file_to_insert_image
2120
+ end
2121
+ }
2122
+ }
2123
+
2124
+ @text = text {
2125
+ grid row: 1, column: 0, row_weight: 1
2126
+ wrap 'word'
2127
+ undo true
2128
+ value <=> [self, :document]
1718
2129
  }
1719
2130
  }.open
1720
2131
  end
@@ -1896,6 +2307,341 @@ Glimmer app:
1896
2307
 
1897
2308
  ![glimmer dsl tk screenshot sample hello computed](images/glimmer-dsl-tk-screenshot-sample-hello-computed.png)
1898
2309
 
2310
+ ### Hello, Drag and Drop!
2311
+
2312
+ Glimmer code (from [samples/hello/hello_drag_and_drop.rb](samples/hello/hello_drag_and_drop.rb)):
2313
+
2314
+ ```ruby
2315
+ require "glimmer-dsl-tk"
2316
+ require "glimmer/tk/drag_and_drop_extension"
2317
+
2318
+ include Glimmer
2319
+
2320
+ root {
2321
+ title "Hello, Drag and Drop!"
2322
+ frame {
2323
+ padding 5
2324
+ labelframe {
2325
+ text "Drag sources"
2326
+ padding 5
2327
+ label {
2328
+ text "Entry"
2329
+ grid :row => 0, :column => 0
2330
+ }
2331
+ entry {
2332
+ text "Drag entry text"
2333
+ width 30
2334
+ grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
2335
+ on_drag_start { |event|
2336
+ event.data = event.source.textvariable&.value
2337
+ event.source.configure(:cursor => "hand2")
2338
+ TkLabel.new(event.tooltip) {
2339
+ text event.data + " "
2340
+ bg "yellow"
2341
+ bitmap "warning"
2342
+ compound "right"
2343
+ }.pack
2344
+ }
2345
+ on_drag_motion { |event|
2346
+ if event.drop_accepted
2347
+ event.source.configure(:cursor => "hand1")
2348
+ else
2349
+ event.source.configure(:cursor => "hand2")
2350
+ end
2351
+ event.tooltip.geometry("+#{event.x_root + 10}+#{event.y_root - 4}")
2352
+ }
2353
+ }
2354
+ label {
2355
+ text "Label"
2356
+ grid :row => 1, :column => 0
2357
+ }
2358
+ label {
2359
+ text "Drag label text"
2360
+ width 30
2361
+ grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
2362
+ drag_source true
2363
+ }
2364
+ label {
2365
+ text "Combobox"
2366
+ grid :row => 2, :column => 0
2367
+ }
2368
+ combobox {
2369
+ text "Spain"
2370
+ values %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
2371
+ width 27
2372
+ grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
2373
+ on_drag_start { |event|
2374
+ event.data = event.source.textvariable&.value
2375
+ }
2376
+ }
2377
+ label {
2378
+ text "Button"
2379
+ grid :row => 3, :column => 0
2380
+ }
2381
+ button {
2382
+ text "Drag it"
2383
+ grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
2384
+ drag_source true
2385
+ }
2386
+ }
2387
+
2388
+ labelframe {
2389
+ text "Drop targets"
2390
+ grid :sticky => "nsew", :pady => 15
2391
+ padding 5
2392
+ label {
2393
+ text "Entry"
2394
+ grid :row => 0, :column => 0
2395
+ }
2396
+ entry {
2397
+ width 30
2398
+ grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
2399
+ on_drop { |event|
2400
+ event.target.textvariable.value = event.data
2401
+ }
2402
+ }
2403
+ label {
2404
+ text "Label"
2405
+ grid :row => 1, :column => 0
2406
+ }
2407
+ label {
2408
+ width 30
2409
+ grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
2410
+ borderwidth 2
2411
+ relief "solid"
2412
+ on_drop { |event|
2413
+ event.target.textvariable.value = event.data
2414
+ }
2415
+ }
2416
+ label {
2417
+ text "Combobox"
2418
+ grid :row => 2, :column => 0
2419
+ }
2420
+ combobox {
2421
+ width 27
2422
+ grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
2423
+ on_drop { |event|
2424
+ event.target.textvariable.value = event.data
2425
+ }
2426
+ }
2427
+ label {
2428
+ text "Button"
2429
+ grid :row => 3, :column => 0
2430
+ }
2431
+ button {
2432
+ text "Drop here"
2433
+ grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
2434
+ on_drop { |event|
2435
+ event.target.text = event.data
2436
+ }
2437
+ }
2438
+ label {
2439
+ text "Checkbutton"
2440
+ grid :row => 4, :column => 0
2441
+ }
2442
+ checkbutton {
2443
+ text "Drop here to destroy a widget\n(except button)"
2444
+ grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
2445
+ on_drop { |event|
2446
+ event.target.text = event.data
2447
+ event.source.destroy unless event.source.is_a? Tk::Button
2448
+ }
2449
+ }
2450
+ }
2451
+ }
2452
+ }.open
2453
+ ```
2454
+
2455
+ Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
2456
+
2457
+ ```
2458
+ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_drag_and_drop'"
2459
+ ```
2460
+
2461
+ Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
2462
+
2463
+ ```
2464
+ ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_drag_and_drop.rb
2465
+ ```
2466
+
2467
+ Glimmer app:
2468
+
2469
+ ![glimmer dsl tk screenshot sample hello drag and drop](images/glimmer-dsl-tk-screenshot-sample-hello-drag-and-drop.png)
2470
+
2471
+ ### Hello, Built-in Dialog!
2472
+
2473
+ Glimmer code (from [samples/hello/hello_built_in_dialog.rb](samples/hello/hello_built_in_dialog.rb)):
2474
+
2475
+ ```ruby
2476
+ require 'glimmer-dsl-tk'
2477
+
2478
+ include Glimmer
2479
+
2480
+ root { |w|
2481
+ title 'Hello, Built-in Dialog!'
2482
+ width 400
2483
+ height 400
2484
+ x 150
2485
+ y 150
2486
+
2487
+ frame {
2488
+ %w[get_open_file get_multiple_open_file get_save_file choose_directory choose_color].each do |dialog|
2489
+ button {
2490
+ text dialog.split('_').map(&:capitalize).join(' ')
2491
+
2492
+ on('command') do
2493
+ result = send(dialog, parent: w)
2494
+ @result_label.text = [result].flatten.join("\n")
2495
+ end
2496
+ }
2497
+ end
2498
+
2499
+ button {
2500
+ text 'Choose Font'
2501
+
2502
+ on('command') do
2503
+ choose_font(family: 'Courier New', size: '30', weight: 'bold') do |chosen_font|
2504
+ @result_label.text = chosen_font
2505
+ end
2506
+ end
2507
+ }
2508
+ }
2509
+
2510
+ frame {
2511
+ grid sticky: 'nsew', padx: 15, pady: 15
2512
+
2513
+ label {
2514
+ grid row: 0, column: 0
2515
+ text 'Result:'
2516
+ }
2517
+
2518
+ @result_label = label {
2519
+ grid row: 0, column: 1
2520
+ }
2521
+ }
2522
+ }.open
2523
+ ```
2524
+
2525
+ Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
2526
+
2527
+ ```
2528
+ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_built_in_dialog'"
2529
+ ```
2530
+
2531
+ Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
2532
+
2533
+ ```
2534
+ ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_built_in_dialog.rb
2535
+ ```
2536
+
2537
+ Glimmer app:
2538
+
2539
+ ![glimmer dsl tk screenshot sample hello built in dialog 1](images/glimmer-dsl-tk-screenshot-sample-hello-built-in-dialog-get-open-file.png)
2540
+ ![glimmer dsl tk screenshot sample hello built in dialog 2](images/glimmer-dsl-tk-screenshot-sample-hello-built-in-dialog-get-open-file-done.png)
2541
+
2542
+ ![glimmer dsl tk screenshot sample hello built in dialog 3](images/glimmer-dsl-tk-screenshot-sample-hello-built-in-dialog-choose-color.png)
2543
+ ![glimmer dsl tk screenshot sample hello built in dialog 4](images/glimmer-dsl-tk-screenshot-sample-hello-built-in-dialog-choose-color-done.png)
2544
+
2545
+ ![glimmer dsl tk screenshot sample hello built in dialog 5](images/glimmer-dsl-tk-screenshot-sample-hello-built-in-dialog-choose-font.png)
2546
+ ![glimmer dsl tk screenshot sample hello built in dialog 6](images/glimmer-dsl-tk-screenshot-sample-hello-built-in-dialog-choose-font-done.png)
2547
+
2548
+ ### Hello, Separator!
2549
+
2550
+ Glimmer code (from [samples/hello/hello_separator.rb](samples/hello/hello_separator.rb)):
2551
+
2552
+ ```ruby
2553
+ require 'glimmer-dsl-tk'
2554
+
2555
+ include Glimmer
2556
+
2557
+ root {
2558
+ title 'Hello, Separator!'
2559
+ width 200
2560
+ height 200
2561
+
2562
+ label {
2563
+ grid row: 0, column: 0, min_width: 100, min_height: 100, column_weight: 0, sticky: 'nsew'
2564
+ text 'Label 1'
2565
+ anchor 'center'
2566
+ }
2567
+
2568
+ separator {
2569
+ grid row: 0, column: 1
2570
+ orient 'vertical'
2571
+ }
2572
+
2573
+ label {
2574
+ grid row: 0, column: 2, min_width: 100, min_height: 100, sticky: 'nsew'
2575
+ text 'Label 2'
2576
+ anchor 'center'
2577
+ }
2578
+
2579
+ separator {
2580
+ grid row: 1, column: 0, column_span: 3
2581
+ # orient 'horizontal' # default
2582
+ }
2583
+
2584
+ label {
2585
+ grid row: 2, column: 0, min_width: 100, min_height: 100, sticky: 'nsew'
2586
+ text 'Label 3'
2587
+ anchor 'center'
2588
+ }
2589
+
2590
+ separator {
2591
+ grid row: 2, column: 1
2592
+ orient 'vertical'
2593
+ }
2594
+
2595
+ label {
2596
+ grid row: 2, column: 2, min_width: 100, min_height: 100, sticky: 'nsew'
2597
+ text 'Label 4'
2598
+ anchor 'center'
2599
+ }
2600
+ }.open
2601
+ ```
2602
+
2603
+ Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
2604
+
2605
+ ```
2606
+ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_separator'"
2607
+ ```
2608
+
2609
+ Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
2610
+
2611
+ ```
2612
+ ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_separator.rb
2613
+ ```
2614
+
2615
+ Glimmer app:
2616
+
2617
+ ![glimmer dsl tk screenshot sample hello separator](images/glimmer-dsl-tk-screenshot-sample-hello-separator.png)
2618
+
2619
+ ## Applications
2620
+
2621
+ ### Glimmer Tk Calculator
2622
+
2623
+ "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)
2624
+
2625
+ https://github.com/ancorgs/glimmer-tk-calculator
2626
+
2627
+ https://raw.githubusercontent.com/ancorgs/glimmer-tk-calculator/master/screenshot.png
2628
+
2629
+ ### Y3network Ruby UI
2630
+
2631
+ https://github.com/ancorgs/y3network-ruby-ui
2632
+
2633
+ ### Cryptopunks GUI
2634
+
2635
+ This is a Graphical User Interface for the famous [Cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
2636
+
2637
+ https://github.com/AndyObtiva/cryptopunks-gui
2638
+
2639
+ ![Cryptopunks GUI Screenshot](https://raw.githubusercontent.com/AndyObtiva/cryptopunks-gui/master/screenshots/cryptopunks-gui-screenshot.png)
2640
+
2641
+ ## Process
2642
+
2643
+ [Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
2644
+
1899
2645
  ## Help
1900
2646
 
1901
2647
  ### Issues
@@ -1908,10 +2654,6 @@ You may submit [issues](https://github.com/AndyObtiva/glimmer/issues) on [GitHub
1908
2654
 
1909
2655
  If you need live help, try to [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1910
2656
 
1911
- ## Process
1912
-
1913
- [Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
1914
-
1915
2657
  ## Planned Features and Feature Suggestions
1916
2658
 
1917
2659
  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.
@@ -1929,6 +2671,7 @@ These features have been planned or suggested. You might see them in a future ve
1929
2671
  ## Contributors
1930
2672
 
1931
2673
  * [Andy Maleh](https://github.com/AndyObtiva) (Founder)
2674
+ * [vin1antme](https://github.com/vin1antme)
1932
2675
 
1933
2676
  [Click here to view contributor commits.](https://github.com/AndyObtiva/glimmer-dsl-tk/graphs/contributors)
1934
2677