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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -0
- data/README.md +804 -61
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/built_in_dialog_expression.rb +57 -0
- data/lib/glimmer/dsl/tk/dsl.rb +1 -0
- data/lib/glimmer/tk/drag_and_drop_extension.rb +112 -0
- data/lib/glimmer/tk/label_proxy.rb +0 -10
- data/lib/glimmer/tk/text_proxy.rb +210 -50
- data/lib/glimmer/tk/widget_proxy.rb +23 -8
- data/samples/elaborate/meta_sample.rb +6 -6
- data/samples/hello/hello_built_in_dialog.rb +68 -0
- data/samples/hello/hello_drag_and_drop.rb +159 -0
- data/samples/hello/hello_message_box.rb +0 -4
- data/samples/hello/hello_separator.rb +69 -0
- data/samples/hello/hello_text.rb +202 -23
- 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/copy.png +0 -0
- data/samples/hello/images/cut.png +0 -0
- data/samples/hello/images/paste.png +0 -0
- data/samples/hello/images/picture.png +0 -0
- data/samples/hello/images/redo.png +0 -0
- data/samples/hello/images/search.png +0 -0
- data/samples/hello/images/undo.png +0 -0
- metadata +19 -4
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.30
|
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)
|
@@ -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
|
-
|
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
|
-
- [
|
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.
|
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
|
-
`
|
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
|
-
####
|
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
|
-
|
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
|
-
###
|
614
|
+
### Text Data-Binding
|
502
615
|
|
503
616
|
Example:
|
504
617
|
|
505
|
-
This assumes a `Person` model with a `
|
618
|
+
This assumes a `Person` model with a `biography` attribute.
|
506
619
|
|
507
620
|
```ruby
|
508
|
-
|
509
|
-
|
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 `
|
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,
|
630
|
+
More details can be found in [Hello, Text!](#hello-text) sample below.
|
522
631
|
|
523
|
-
###
|
632
|
+
### Spinbox Data-Binding
|
524
633
|
|
525
634
|
Example:
|
526
635
|
|
527
|
-
This assumes a `Person` model with a `
|
636
|
+
This assumes a `Person` model with a `donation` attribute.
|
528
637
|
|
529
638
|
```ruby
|
530
|
-
|
531
|
-
|
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
|
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
|
650
|
+
It automatically handles all the Tk plumbing behind the scenes.
|
538
651
|
|
539
|
-
More details can be found in [
|
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
|

|
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
|

|
1410
|
-

|
1411
1643
|
|
1412
1644
|
### Hello, Combobox!
|
1413
1645
|
|
@@ -1636,7 +1868,7 @@ Glimmer app:
|
|
1636
1868
|
|
1637
1869
|
### Hello, Text!
|
1638
1870
|
|
1639
|
-
|
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
|
-
|
1651
|
-
|
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:
|
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:
|
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 ? '
|
1984
|
+
text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value) }]
|
1687
1985
|
}
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1717
|
-
|
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
|

|
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
|
+

|
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
|
+

|
2540
|
+

|
2541
|
+
|
2542
|
+

|
2543
|
+

|
2544
|
+
|
2545
|
+

|
2546
|
+

|
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
|
+

|
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
|
+

|
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 [](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
|
|