glimmer-dsl-tk 0.0.13 → 0.0.17
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 +34 -0
- data/README.md +328 -33
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/tk/label_proxy.rb +8 -8
- data/lib/glimmer/tk/root_proxy.rb +1 -3
- data/lib/glimmer/tk/widget_proxy.rb +62 -6
- data/samples/hello/hello_button.rb +97 -0
- data/samples/hello/hello_label.rb +110 -0
- data/samples/hello/hello_message_box.rb +1 -1
- data/samples/hello/images/denmark.png +0 -0
- data/samples/hello/images/finland.png +0 -0
- data/samples/hello/images/france.png +0 -0
- data/samples/hello/images/germany.png +0 -0
- data/samples/hello/images/italy.png +0 -0
- data/samples/hello/images/mexico.png +0 -0
- data/samples/hello/images/netherlands.png +0 -0
- data/samples/hello/images/norway.png +0 -0
- data/samples/hello/images/usa.png +0 -0
- metadata +13 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 21a6a1f1d2d85928c9bac3b9fd14ce7d8ca39f1ddec7ad82b8bafa733a0e4caa
         | 
| 4 | 
            +
              data.tar.gz: 3d3acdb3c53c63d45a54188e956fedc8fa010dadaa3b3edb697f4b5f23a85126
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2c118bbcd96a99bbd4037e8df41595e7e514e16a0077d895e3b1808d62f7a62062f784b450fbdb299f2e48d59f60dce1e5de6ab08267a55123d4cffd100d494b
         | 
| 7 | 
            +
              data.tar.gz: fe21b7c7cc00eb47c9313ea953b4fdce36b8a2bc2aa86de010fd8f68fde9c0487bb86b629263d0fc47ac2b64ce6fcdf2003879fd124607f4ea9c666800093660
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,39 @@ | |
| 1 1 | 
             
            # Change Log
         | 
| 2 2 |  | 
| 3 | 
            +
            ## 0.0.17
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            - Support `label` `anchor` attribute (`'e'`, `'se'`, `'s'`, `'sw'`, `'w'`, `'nw'` or `'center'`)
         | 
| 6 | 
            +
            - Support `label` `width` attributes
         | 
| 7 | 
            +
            - Support `label` `image` attribute
         | 
| 8 | 
            +
            - Support `label` `justify` attribute (`'left', 'center', 'right'`)
         | 
| 9 | 
            +
            - Support `label` `font` attribute (`'default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip'`)
         | 
| 10 | 
            +
            - Support `label` `foreground` attribute
         | 
| 11 | 
            +
            - Support `label` `background` attribute (note that it does not work in Mac 'aqua' theme)
         | 
| 12 | 
            +
            - Support `label` `compound` attribute
         | 
| 13 | 
            +
            - Support `label` `relief` attributes (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ## 0.0.16
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            - Support common themed widget state attributes: `active`, `disabled`, `focus`, `pressed`, `selected`, `background`, `readonly`, `alternate`, `invalid`, and `hover`
         | 
| 18 | 
            +
            - Update Hello, Button! to utilize `focus true` in first button.
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            ## 0.0.15
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            - Update Hello, Button! to demo all button attributes
         | 
| 23 | 
            +
            - Support `button` `image` attribute (accepting image arguments: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule` to automatically process image)
         | 
| 24 | 
            +
            - Update `root` `iconphoto` support to accept image arguments: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule` to automatically process image
         | 
| 25 | 
            +
            - Support `button` `compound` attribute (`'center', 'top', 'bottom', 'left', 'right'`)
         | 
| 26 | 
            +
            - Support `button` `default` attribute (`'active'` or `'normal'`)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            ## 0.0.14
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            - Hello, Button!
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ## 0.0.13
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            - Hello, Message Box!
         | 
| 35 | 
            +
            - Support `message_box`
         | 
| 36 | 
            +
             | 
| 3 37 | 
             
            ## 0.0.12
         | 
| 4 38 |  | 
| 5 39 | 
             
            - Upgrade to glimmer 2.3.0
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 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.17
         | 
| 2 2 | 
             
            ## MRI Ruby Desktop Development GUI Library
         | 
| 3 3 | 
             
            [](http://badge.fury.io/rb/glimmer-dsl-tk)
         | 
| 4 | 
            +
            [](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml)
         | 
| 4 5 | 
             
            [](https://coveralls.io/github/AndyObtiva/glimmer-dsl-tk?branch=master)
         | 
| 5 6 | 
             
            [](https://codeclimate.com/github/AndyObtiva/glimmer-dsl-tk/maintainability)
         | 
| 6 7 | 
             
            [](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
         | 
| @@ -29,7 +30,13 @@ The trade-off is that while [SWT](https://www.eclipse.org/swt/) provides a pleth | |
| 29 30 | 
             
            Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
         | 
| 30 31 |  | 
| 31 32 | 
             
            ```ruby
         | 
| 33 | 
            +
            require 'glimmer-dsl-tk'
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            include Glimmer
         | 
| 36 | 
            +
             | 
| 32 37 | 
             
            root {
         | 
| 38 | 
            +
              title 'Hello, World!'
         | 
| 39 | 
            +
              
         | 
| 33 40 | 
             
              label {
         | 
| 34 41 | 
             
                text 'Hello, World!'
         | 
| 35 42 | 
             
              }
         | 
| @@ -55,6 +62,52 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems: | |
| 55 62 | 
             
            - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
         | 
| 56 63 | 
             
            - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
         | 
| 57 64 |  | 
| 65 | 
            +
            ## Table of Contents
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            - [Glimmer DSL for Tk](#)
         | 
| 68 | 
            +
              - [MRI Ruby Desktop Development GUI Library](#mri-ruby-desktop-development-gui-library)
         | 
| 69 | 
            +
              - [Pre-requisites](#pre-requisites)
         | 
| 70 | 
            +
              - [Setup](#setup)
         | 
| 71 | 
            +
                - [Option 1: Install](#option-1-install)
         | 
| 72 | 
            +
                - [Option 2: Bundler](#option-2-bundler)
         | 
| 73 | 
            +
              - [Girb (Glimmer IRB)](#girb-glimmer-irb)
         | 
| 74 | 
            +
              - [Tk Concepts](#tk-concepts)
         | 
| 75 | 
            +
              - [Glimmer GUI DSL Concepts](#glimmer-gui-dsl-concepts)
         | 
| 76 | 
            +
                - [Supported Widgets](#supported-widgets)
         | 
| 77 | 
            +
                  - [Common Attributes](#common-attributes)
         | 
| 78 | 
            +
                  - [Common Themed Widget States](#common-themed-widget-states)
         | 
| 79 | 
            +
                - [Smart Defaults and Convensions](#smart-defaults-and-convensions)
         | 
| 80 | 
            +
                  - [Grid Layout](#grid-layout)
         | 
| 81 | 
            +
                  - [Label/Button Image](#labelbutton-image)
         | 
| 82 | 
            +
                  - [Icon Photo](#icon-photo)
         | 
| 83 | 
            +
              - [The Grid Geometry Manager](#the-grid-geometry-manager)
         | 
| 84 | 
            +
              - [Bidirectional Data-Binding](#bidirectional-data-binding)
         | 
| 85 | 
            +
                - [General Property Data-Binding](#general-property-data-binding)
         | 
| 86 | 
            +
                - [Combobox Data-Binding](#combobox-data-binding)
         | 
| 87 | 
            +
                - [List Single Selection Data-Binding](#list-single-selection-data-binding)
         | 
| 88 | 
            +
                - [List Multi Selection Data-Binding](#list-multi-selection-data-binding)
         | 
| 89 | 
            +
                - [Entry Data-Binding](#entry-data-binding)
         | 
| 90 | 
            +
              - [Command Observer](#command-observer)
         | 
| 91 | 
            +
              - [Samples](#samples)
         | 
| 92 | 
            +
                - [Hello, World!](#hello-world)
         | 
| 93 | 
            +
                - [Hello, Button!](#hello-button)
         | 
| 94 | 
            +
                - [Hello, Tab!](#hello-tab)
         | 
| 95 | 
            +
                - [Hello, Label!](#hello-label)
         | 
| 96 | 
            +
                - [Hello, Message Box!](#hello-message-box)
         | 
| 97 | 
            +
                - [Hello, Combobox!](#hello-combobox)
         | 
| 98 | 
            +
                - [Hello, List Single Selection!](#hello-list-single-selection)
         | 
| 99 | 
            +
                - [Hello, List Multi Selection!](#hello-list-multi-selection)
         | 
| 100 | 
            +
                - [Hello, Computed!](#hello-computed)
         | 
| 101 | 
            +
              - [Help](#help)
         | 
| 102 | 
            +
                - [Issues](#issues)
         | 
| 103 | 
            +
                - [Chat](#chat)
         | 
| 104 | 
            +
              - [Process](#process)
         | 
| 105 | 
            +
              - [Planned Features and Feature Suggestions](#planned-features-and-feature-suggestions)
         | 
| 106 | 
            +
              - [Change Log](#change-log)
         | 
| 107 | 
            +
              - [Contributing](#contributing)
         | 
| 108 | 
            +
              - [Contributors](#contributors)
         | 
| 109 | 
            +
              - [License](#license)
         | 
| 110 | 
            +
             | 
| 58 111 | 
             
            ## Pre-requisites
         | 
| 59 112 |  | 
| 60 113 | 
             
            - [Tcl/Tk](https://www.tcl.tk/): Follow the [install instructions](https://tkdocs.com/tutorial/install.html)
         | 
| @@ -81,7 +134,7 @@ gem install glimmer-dsl-tk | |
| 81 134 |  | 
| 82 135 | 
             
            Add the following to `Gemfile`:
         | 
| 83 136 | 
             
            ```
         | 
| 84 | 
            -
            gem 'glimmer-dsl-tk', '~> 0.0. | 
| 137 | 
            +
            gem 'glimmer-dsl-tk', '~> 0.0.17'
         | 
| 85 138 | 
             
            ```
         | 
| 86 139 |  | 
| 87 140 | 
             
            And, then run:
         | 
| @@ -169,12 +222,12 @@ root { | |
| 169 222 |  | 
| 170 223 | 
             
            ### Supported Widgets
         | 
| 171 224 |  | 
| 172 | 
            -
            keyword(args) | attributes |  | 
| 225 | 
            +
            keyword(args) | attributes | event bindings & callbacks
         | 
| 173 226 | 
             
            ------------- | ---------- | ---------
         | 
| 174 | 
            -
            `button` | `text` | `command`
         | 
| 227 | 
            +
            `button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command`
         | 
| 175 228 | 
             
            `entry` | `width`, `text` | None
         | 
| 176 | 
            -
            `frame(text: )` | None | None
         | 
| 177 | 
            -
            `label` | `text` | None
         | 
| 229 | 
            +
            `frame(text: nil)` | None | None
         | 
| 230 | 
            +
            `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
         | 
| 178 231 | 
             
            `list` | `selectmode`, `selection` | None
         | 
| 179 232 | 
             
            `message_box(type: , message: , detail: , title: , icon: , default: , parent: )` | None | None
         | 
| 180 233 | 
             
            `notebook` | None | None
         | 
| @@ -182,7 +235,20 @@ keyword(args) | attributes | listeners/events | |
| 182 235 |  | 
| 183 236 | 
             
            #### Common Attributes
         | 
| 184 237 |  | 
| 185 | 
            -
            - `grid`
         | 
| 238 | 
            +
            - `grid`: `Hash` of `:row`, `:column`, `:padx`, `:pady`, `:sticky` (`'e', 'w', 'n', 's'` or any combination of direction letters)
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            #### Common Themed Widget States
         | 
| 241 | 
            +
             | 
| 242 | 
            +
            - `active?`
         | 
| 243 | 
            +
            - `disabled?`
         | 
| 244 | 
            +
            - `focus?`
         | 
| 245 | 
            +
            - `pressed?`
         | 
| 246 | 
            +
            - `selected?`
         | 
| 247 | 
            +
            - `background?`
         | 
| 248 | 
            +
            - `readonly?`
         | 
| 249 | 
            +
            - `alternate?`
         | 
| 250 | 
            +
            - `invalid?`
         | 
| 251 | 
            +
            - `hover?`
         | 
| 186 252 |  | 
| 187 253 | 
             
            ### Smart Defaults and Convensions
         | 
| 188 254 |  | 
| @@ -190,6 +256,10 @@ keyword(args) | attributes | listeners/events | |
| 190 256 |  | 
| 191 257 | 
             
            `grid` layout is the default on most widgets (which support it).
         | 
| 192 258 |  | 
| 259 | 
            +
            #### Label/Button Image
         | 
| 260 | 
            +
             | 
| 261 | 
            +
            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`)
         | 
| 262 | 
            +
             | 
| 193 263 | 
             
            #### Icon Photo
         | 
| 194 264 |  | 
| 195 265 | 
             
            The `iconphoto` attribute on `root` is set to the Glimmer icon by default if no icon photo is supplied.
         | 
| @@ -238,6 +308,24 @@ More details can be found in the [Hello, Computed!](#hello-computed) sample belo | |
| 238 308 |  | 
| 239 309 | 
             
            Glimmer supports Shine syntax bidirectional data-binding via the `<=>` operator (read-write) and unidirectional data-binding via the `<=` operator (read-only), which takes a model and an attribute (the `bind` keyword may also be used as the old-style of data-binding).
         | 
| 240 310 |  | 
| 311 | 
            +
            ### General Property Data-Binding
         | 
| 312 | 
            +
             | 
| 313 | 
            +
            Example:
         | 
| 314 | 
            +
             | 
| 315 | 
            +
            This assumes a `Person` model with a `country` attribute.
         | 
| 316 | 
            +
             | 
| 317 | 
            +
            ```ruby
         | 
| 318 | 
            +
              label {
         | 
| 319 | 
            +
                text <=> [person, :country]
         | 
| 320 | 
            +
              }
         | 
| 321 | 
            +
            ```
         | 
| 322 | 
            +
             | 
| 323 | 
            +
            That code binds the `textvariable` value of the `label` to the `country` property on the `person` model.
         | 
| 324 | 
            +
             | 
| 325 | 
            +
            It automatically handles all the Tk plumbing behind the scenes.
         | 
| 326 | 
            +
             | 
| 327 | 
            +
            More details can be found in the [Hello, Computed!](#hello-computed) sample below.
         | 
| 328 | 
            +
             | 
| 241 329 | 
             
            ### Combobox Data-Binding
         | 
| 242 330 |  | 
| 243 331 | 
             
            Example:
         | 
| @@ -301,24 +389,6 @@ It automatically handles all the Tk plumbing behind the scenes. | |
| 301 389 |  | 
| 302 390 | 
             
            More details can be found in the [Hello, List Multi Selection!](#hello-list-multi-selection) sample below.
         | 
| 303 391 |  | 
| 304 | 
            -
            ### Label Data-Binding
         | 
| 305 | 
            -
             | 
| 306 | 
            -
            Example:
         | 
| 307 | 
            -
             | 
| 308 | 
            -
            This assumes a `Person` model with a `country` attribute.
         | 
| 309 | 
            -
             | 
| 310 | 
            -
            ```ruby
         | 
| 311 | 
            -
              label {
         | 
| 312 | 
            -
                text <=> [person, :country]
         | 
| 313 | 
            -
              }
         | 
| 314 | 
            -
            ```
         | 
| 315 | 
            -
             | 
| 316 | 
            -
            That code binds the `textvariable` value of the `label` to the `country` property on the `person` model.
         | 
| 317 | 
            -
             | 
| 318 | 
            -
            It automatically handles all the Tk plumbing behind the scenes.
         | 
| 319 | 
            -
             | 
| 320 | 
            -
            More details can be found in the [Hello, Computed!](#hello-computed) sample below.
         | 
| 321 | 
            -
             | 
| 322 392 | 
             
            ### Entry Data-Binding
         | 
| 323 393 |  | 
| 324 394 | 
             
            Example:
         | 
| @@ -363,9 +433,13 @@ More details can be found in the [Hello, Combobox!](#hello-combobox) sample belo | |
| 363 433 | 
             
            Glimmer code (from [samples/hello/hello_world.rb](samples/hello/hello_world.rb)):
         | 
| 364 434 |  | 
| 365 435 | 
             
            ```ruby
         | 
| 436 | 
            +
            require 'glimmer-dsl-tk'
         | 
| 437 | 
            +
             | 
| 366 438 | 
             
            include Glimmer
         | 
| 367 439 |  | 
| 368 440 | 
             
            root {
         | 
| 441 | 
            +
              title 'Hello, World!'
         | 
| 442 | 
            +
              
         | 
| 369 443 | 
             
              label {
         | 
| 370 444 | 
             
                text 'Hello, World!'
         | 
| 371 445 | 
             
              }
         | 
| @@ -381,13 +455,112 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_world'" | |
| 381 455 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 382 456 |  | 
| 383 457 | 
             
            ```
         | 
| 384 | 
            -
            ruby - | 
| 458 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_world.rb
         | 
| 385 459 | 
             
            ```
         | 
| 386 460 |  | 
| 387 461 | 
             
            Glimmer app:
         | 
| 388 462 |  | 
| 389 463 | 
             
            
         | 
| 390 464 |  | 
| 465 | 
            +
            ### Hello, Button!
         | 
| 466 | 
            +
             | 
| 467 | 
            +
            Glimmer code (from [samples/hello/hello_button.rb](samples/hello/hello_button.rb)):
         | 
| 468 | 
            +
             | 
| 469 | 
            +
            ```ruby
         | 
| 470 | 
            +
            require 'glimmer-dsl-tk'
         | 
| 471 | 
            +
             | 
| 472 | 
            +
            class HelloButton
         | 
| 473 | 
            +
              include Glimmer
         | 
| 474 | 
            +
              
         | 
| 475 | 
            +
              attr_accessor :count
         | 
| 476 | 
            +
              
         | 
| 477 | 
            +
              def initialize
         | 
| 478 | 
            +
                @count = 0
         | 
| 479 | 
            +
              end
         | 
| 480 | 
            +
              
         | 
| 481 | 
            +
              def launch
         | 
| 482 | 
            +
                root {
         | 
| 483 | 
            +
                  title 'Hello, Button!'
         | 
| 484 | 
            +
                  
         | 
| 485 | 
            +
                  frame {
         | 
| 486 | 
            +
                    grid row: 0, column: 0
         | 
| 487 | 
            +
                    
         | 
| 488 | 
            +
                    label {
         | 
| 489 | 
            +
                      grid pady: 15
         | 
| 490 | 
            +
                      text 'Text Button'
         | 
| 491 | 
            +
                    }
         | 
| 492 | 
            +
                    
         | 
| 493 | 
            +
                    button {
         | 
| 494 | 
            +
                      text <= [self, :count, on_read: ->(value) { "Click To Increment: #{value}  " }]
         | 
| 495 | 
            +
                      default 'active'
         | 
| 496 | 
            +
                      focus true
         | 
| 497 | 
            +
                      
         | 
| 498 | 
            +
                      command {
         | 
| 499 | 
            +
                        self.count += 1
         | 
| 500 | 
            +
                      }
         | 
| 501 | 
            +
                    }
         | 
| 502 | 
            +
                  }
         | 
| 503 | 
            +
                    
         | 
| 504 | 
            +
                  frame {
         | 
| 505 | 
            +
                    grid row: 0, column: 1
         | 
| 506 | 
            +
                    
         | 
| 507 | 
            +
                    label {
         | 
| 508 | 
            +
                      grid pady: 15
         | 
| 509 | 
            +
                      text 'Image Button'
         | 
| 510 | 
            +
                    }
         | 
| 511 | 
            +
                    
         | 
| 512 | 
            +
                    button {
         | 
| 513 | 
            +
                      image File.expand_path('../../icons/glimmer.png', __dir__), subsample: 5
         | 
| 514 | 
            +
                      
         | 
| 515 | 
            +
                      command {
         | 
| 516 | 
            +
                        message_box(title: 'Image Button', message: 'Image Button Clicked!')
         | 
| 517 | 
            +
                      }
         | 
| 518 | 
            +
                    }
         | 
| 519 | 
            +
                  }
         | 
| 520 | 
            +
                  
         | 
| 521 | 
            +
                  frame {
         | 
| 522 | 
            +
                    grid row: 0, column: 2
         | 
| 523 | 
            +
                    
         | 
| 524 | 
            +
                    label {
         | 
| 525 | 
            +
                      grid pady: 15
         | 
| 526 | 
            +
                      text 'Text Image Buttons'
         | 
| 527 | 
            +
                    }
         | 
| 528 | 
            +
                    
         | 
| 529 | 
            +
                    ['center', 'top', 'bottom', 'left', 'right'].each do |compound_option|
         | 
| 530 | 
            +
                      button {
         | 
| 531 | 
            +
                        image File.expand_path('../../icons/glimmer.png', __dir__), subsample: 5
         | 
| 532 | 
            +
                        text 'Text Image Button'
         | 
| 533 | 
            +
                        compound compound_option
         | 
| 534 | 
            +
                        
         | 
| 535 | 
            +
                        command {
         | 
| 536 | 
            +
                          message_box(title: 'Text Image Button', message: 'Text Image Button Clicked!', detail: "(#{compound_option})")
         | 
| 537 | 
            +
                        }
         | 
| 538 | 
            +
                      }
         | 
| 539 | 
            +
                    end
         | 
| 540 | 
            +
                  }
         | 
| 541 | 
            +
                }.open
         | 
| 542 | 
            +
              end
         | 
| 543 | 
            +
            end
         | 
| 544 | 
            +
             | 
| 545 | 
            +
            HelloButton.new.launch
         | 
| 546 | 
            +
            ```
         | 
| 547 | 
            +
             | 
| 548 | 
            +
            Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 549 | 
            +
             | 
| 550 | 
            +
            ```
         | 
| 551 | 
            +
            ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_button'"
         | 
| 552 | 
            +
            ```
         | 
| 553 | 
            +
             | 
| 554 | 
            +
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 555 | 
            +
             | 
| 556 | 
            +
            ```
         | 
| 557 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_button.rb
         | 
| 558 | 
            +
            ```
         | 
| 559 | 
            +
             | 
| 560 | 
            +
            Glimmer app:
         | 
| 561 | 
            +
             | 
| 562 | 
            +
            
         | 
| 563 | 
            +
             | 
| 391 564 | 
             
            ### Hello, Tab!
         | 
| 392 565 |  | 
| 393 566 | 
             
            Glimmer code (from [samples/hello/hello_tab.rb](samples/hello/hello_tab.rb)):
         | 
| @@ -423,7 +596,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_tab'" | |
| 423 596 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 424 597 |  | 
| 425 598 | 
             
            ```
         | 
| 426 | 
            -
            ruby - | 
| 599 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_tab.rb
         | 
| 427 600 | 
             
            ```
         | 
| 428 601 |  | 
| 429 602 | 
             
            Glimmer app:
         | 
| @@ -431,6 +604,128 @@ Glimmer app: | |
| 431 604 | 
             
            
         | 
| 432 605 | 
             
            
         | 
| 433 606 |  | 
| 607 | 
            +
            ### Hello, Label!
         | 
| 608 | 
            +
             | 
| 609 | 
            +
            Glimmer code (from [samples/hello/hello_label.rb](samples/hello/hello_label.rb)):
         | 
| 610 | 
            +
             | 
| 611 | 
            +
            ```ruby
         | 
| 612 | 
            +
            require 'glimmer-dsl-tk'
         | 
| 613 | 
            +
             | 
| 614 | 
            +
            class HelloLabel
         | 
| 615 | 
            +
              include Glimmer
         | 
| 616 | 
            +
              
         | 
| 617 | 
            +
              LABEL_FONTS = ['default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip']
         | 
| 618 | 
            +
              LABEL_RELIEFS = ['flat', 'raised', 'sunken', 'solid', 'ridge', 'groove']
         | 
| 619 | 
            +
              
         | 
| 620 | 
            +
              def launch
         | 
| 621 | 
            +
                root {
         | 
| 622 | 
            +
                  title 'Hello, Label!'
         | 
| 623 | 
            +
                  
         | 
| 624 | 
            +
                  notebook {
         | 
| 625 | 
            +
                    frame(text: 'left-aligned') {
         | 
| 626 | 
            +
                      3.times do |n|
         | 
| 627 | 
            +
                        label {
         | 
| 628 | 
            +
                          text "Field #{n + 1} / default font / flat relief"
         | 
| 629 | 
            +
                          width 60
         | 
| 630 | 
            +
                          anchor 'w'
         | 
| 631 | 
            +
                        }
         | 
| 632 | 
            +
                      end
         | 
| 633 | 
            +
                    }
         | 
| 634 | 
            +
                    
         | 
| 635 | 
            +
                    frame(text: 'centered') {
         | 
| 636 | 
            +
                      9.times do |n|
         | 
| 637 | 
            +
                        label {
         | 
| 638 | 
            +
                          text "Field #{n + 1} / fixed font / raised relief"
         | 
| 639 | 
            +
                          width 80
         | 
| 640 | 
            +
                          anchor 'center'
         | 
| 641 | 
            +
                          font 'fixed'
         | 
| 642 | 
            +
                          relief 'raised'
         | 
| 643 | 
            +
                        }
         | 
| 644 | 
            +
                      end
         | 
| 645 | 
            +
                    }
         | 
| 646 | 
            +
                    
         | 
| 647 | 
            +
                    frame(text: 'right-aligned') {
         | 
| 648 | 
            +
                      9.times do |n|
         | 
| 649 | 
            +
                        label {
         | 
| 650 | 
            +
                          text "Field #{n + 1} / small_caption font / ridge relief"
         | 
| 651 | 
            +
                          width 80
         | 
| 652 | 
            +
                          anchor 'e'
         | 
| 653 | 
            +
                          font 'small_caption'
         | 
| 654 | 
            +
                          relief 'ridge'
         | 
| 655 | 
            +
                        }
         | 
| 656 | 
            +
                      end
         | 
| 657 | 
            +
                    }
         | 
| 658 | 
            +
                    
         | 
| 659 | 
            +
                    frame(text: 'justified') {
         | 
| 660 | 
            +
                      label {
         | 
| 661 | 
            +
                        text <<~MULTI_LINE_STRING
         | 
| 662 | 
            +
                          This is a very long paragraph that spans multiple lines. It looks better and
         | 
| 663 | 
            +
                          is easier to read when justified. In fact, this is how to make it look like a
         | 
| 664 | 
            +
                          new paper column. That results in professional looking text. Magazines use the
         | 
| 665 | 
            +
                          same sort of justified text. Word processors also support justified text. In
         | 
| 666 | 
            +
                          fact, this is how text is made for news papers and magainzes, and then published
         | 
| 667 | 
            +
                          in paper form and digitally.
         | 
| 668 | 
            +
                        MULTI_LINE_STRING
         | 
| 669 | 
            +
                        width 60
         | 
| 670 | 
            +
                        anchor 'center'
         | 
| 671 | 
            +
                        justify 'center' # other options are: 'left' and 'right'
         | 
| 672 | 
            +
                        font 'caption' # other options are: 'default', 'text', 'fixed', 'menu', 'heading', 'small_caption', 'icon', 'tooltip'
         | 
| 673 | 
            +
                        foreground 'blue'
         | 
| 674 | 
            +
                        relief 'sunken' # other options are: 'flat' (default), 'raised', 'solid', 'ridge', 'groove'
         | 
| 675 | 
            +
                      }
         | 
| 676 | 
            +
                    }
         | 
| 677 | 
            +
                    
         | 
| 678 | 
            +
                    frame(text: 'images') {
         | 
| 679 | 
            +
                      ['denmark', 'finland', 'norway'].each do |image_name|
         | 
| 680 | 
            +
                        label {
         | 
| 681 | 
            +
                          image File.expand_path("images/#{image_name}.png", __dir__)
         | 
| 682 | 
            +
                        }
         | 
| 683 | 
            +
                      end
         | 
| 684 | 
            +
                    }
         | 
| 685 | 
            +
                    
         | 
| 686 | 
            +
                    frame(text: 'background images') {
         | 
| 687 | 
            +
                      ['italy', 'france', 'mexico'].each do |image_name|
         | 
| 688 | 
            +
                        label {
         | 
| 689 | 
            +
                          text image_name.capitalize
         | 
| 690 | 
            +
                          image File.expand_path("images/#{image_name}.png", __dir__)
         | 
| 691 | 
            +
                          compound 'center'
         | 
| 692 | 
            +
                        }
         | 
| 693 | 
            +
                      end
         | 
| 694 | 
            +
                    }
         | 
| 695 | 
            +
                  }
         | 
| 696 | 
            +
                }.open
         | 
| 697 | 
            +
              end
         | 
| 698 | 
            +
            end
         | 
| 699 | 
            +
             | 
| 700 | 
            +
            HelloLabel.new.launch
         | 
| 701 | 
            +
            ```
         | 
| 702 | 
            +
             | 
| 703 | 
            +
            Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 704 | 
            +
             | 
| 705 | 
            +
            ```
         | 
| 706 | 
            +
            ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_label'"
         | 
| 707 | 
            +
            ```
         | 
| 708 | 
            +
             | 
| 709 | 
            +
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 710 | 
            +
             | 
| 711 | 
            +
            ```
         | 
| 712 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_label.rb
         | 
| 713 | 
            +
            ```
         | 
| 714 | 
            +
             | 
| 715 | 
            +
            Glimmer app:
         | 
| 716 | 
            +
             | 
| 717 | 
            +
            
         | 
| 718 | 
            +
             | 
| 719 | 
            +
            
         | 
| 720 | 
            +
             | 
| 721 | 
            +
            
         | 
| 722 | 
            +
             | 
| 723 | 
            +
            
         | 
| 724 | 
            +
             | 
| 725 | 
            +
            
         | 
| 726 | 
            +
             | 
| 727 | 
            +
            
         | 
| 728 | 
            +
             | 
| 434 729 | 
             
            ### Hello, Message Box!
         | 
| 435 730 |  | 
| 436 731 | 
             
            Glimmer code (from [samples/hello/hello_message_box.rb](samples/hello/hello_message_box.rb)):
         | 
| @@ -510,13 +805,13 @@ root { |r| | |
| 510 805 | 
             
            Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 511 806 |  | 
| 512 807 | 
             
            ```
         | 
| 513 | 
            -
            ruby -r glimmer-dsl-tk -e "require 'samples/hello/ | 
| 808 | 
            +
            ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_message_box'"
         | 
| 514 809 | 
             
            ```
         | 
| 515 810 |  | 
| 516 811 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 517 812 |  | 
| 518 813 | 
             
            ```
         | 
| 519 | 
            -
            ruby - | 
| 814 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_message_box.rb
         | 
| 520 815 | 
             
            ```
         | 
| 521 816 |  | 
| 522 817 | 
             
            Glimmer app:
         | 
| @@ -557,7 +852,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_combobox'" | |
| 557 852 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 558 853 |  | 
| 559 854 | 
             
            ```
         | 
| 560 | 
            -
            ruby - | 
| 855 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_combobox.rb
         | 
| 561 856 | 
             
            ```
         | 
| 562 857 |  | 
| 563 858 | 
             
            Glimmer app:
         | 
| @@ -597,7 +892,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_list_single_selection'" | |
| 597 892 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 598 893 |  | 
| 599 894 | 
             
            ```
         | 
| 600 | 
            -
            ruby - | 
| 895 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_list_single_selection.rb
         | 
| 601 896 | 
             
            ```
         | 
| 602 897 |  | 
| 603 898 | 
             
            Glimmer app:
         | 
| @@ -635,7 +930,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_list_multi_selection'" | |
| 635 930 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 636 931 |  | 
| 637 932 | 
             
            ```
         | 
| 638 | 
            -
            ruby - | 
| 933 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_list_multi_selection.rb
         | 
| 639 934 | 
             
            ```
         | 
| 640 935 |  | 
| 641 936 | 
             
            Glimmer app:
         | 
| @@ -715,7 +1010,7 @@ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_computed'" | |
| 715 1010 | 
             
            Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
         | 
| 716 1011 |  | 
| 717 1012 | 
             
            ```
         | 
| 718 | 
            -
            ruby - | 
| 1013 | 
            +
            ruby -r ./lib/glimmer-dsl-tk.rb ./samples/hello/hello_computed.rb
         | 
| 719 1014 | 
             
            ```
         | 
| 720 1015 |  | 
| 721 1016 | 
             
            Glimmer app:
         | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0.0. | 
| 1 | 
            +
            0.0.17
         | 
    
        data/glimmer-dsl-tk.gemspec
    CHANGED
    
    | Binary file | 
| @@ -27,14 +27,14 @@ module Glimmer | |
| 27 27 | 
             
                #
         | 
| 28 28 | 
             
                # Follows the Proxy Design Pattern
         | 
| 29 29 | 
             
                class LabelProxy < WidgetProxy
         | 
| 30 | 
            -
                   | 
| 31 | 
            -
             | 
| 32 | 
            -
            # | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 30 | 
            +
                  def set_attribute(attribute, *args)
         | 
| 31 | 
            +
                    if attribute.to_s == 'font'
         | 
| 32 | 
            +
                      args[0] = "tk_#{args[0]}_font".camelcase(:upper) if (args[0].is_a?(Symbol) || args[0].is_a?(String)) && args[0].to_s == args[0].to_s.downcase
         | 
| 33 | 
            +
                      super
         | 
| 34 | 
            +
                    else
         | 
| 35 | 
            +
                      super
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 38 | 
             
                end
         | 
| 39 39 | 
             
              end
         | 
| 40 40 | 
             
            end
         | 
| @@ -45,9 +45,7 @@ module Glimmer | |
| 45 45 |  | 
| 46 46 | 
             
                  def set_attribute(attribute, *args)
         | 
| 47 47 | 
             
                    if attribute.to_s == 'iconphoto'
         | 
| 48 | 
            -
                       | 
| 49 | 
            -
                        args[0] = ::TkPhotoImage.new(file: args.first)
         | 
| 50 | 
            -
                      end
         | 
| 48 | 
            +
                      args[0..-1] = [image_argument(args)]
         | 
| 51 49 | 
             
                      super
         | 
| 52 50 | 
             
                    else
         | 
| 53 51 | 
             
                      super
         | 
| @@ -117,13 +117,34 @@ module Glimmer | |
| 117 117 | 
             
                  end
         | 
| 118 118 |  | 
| 119 119 | 
             
                  def tk_widget_has_attribute_getter_setter?(attribute)
         | 
| 120 | 
            -
                     | 
| 120 | 
            +
                    begin
         | 
| 121 | 
            +
                      # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
         | 
| 122 | 
            +
                      @tk.send(attribute)
         | 
| 123 | 
            +
                      true
         | 
| 124 | 
            +
                    rescue
         | 
| 125 | 
            +
                      false
         | 
| 126 | 
            +
                    end
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
                  
         | 
| 129 | 
            +
                  def has_state?(attribute)
         | 
| 130 | 
            +
                    attribute = attribute.sub(/\?$/, '').sub(/=$/, '')
         | 
| 131 | 
            +
                    if @tk.respond_to?(:tile_state)
         | 
| 132 | 
            +
                      begin
         | 
| 133 | 
            +
                        @tk.tile_instate(attribute)
         | 
| 134 | 
            +
                        true
         | 
| 135 | 
            +
                      rescue
         | 
| 136 | 
            +
                        false
         | 
| 137 | 
            +
                      end
         | 
| 138 | 
            +
                    else
         | 
| 139 | 
            +
                      false
         | 
| 140 | 
            +
                    end
         | 
| 121 141 | 
             
                  end
         | 
| 122 142 |  | 
| 123 143 | 
             
                  def has_attribute?(attribute, *args)
         | 
| 124 | 
            -
                    (widget_custom_attribute_mapping[tk.class]  | 
| 125 | 
            -
                      tk_widget_has_attribute_setter?(attribute)  | 
| 126 | 
            -
                      tk_widget_has_attribute_getter_setter?(attribute)  | 
| 144 | 
            +
                    (widget_custom_attribute_mapping[tk.class] and widget_custom_attribute_mapping[tk.class][attribute.to_s]) or
         | 
| 145 | 
            +
                      tk_widget_has_attribute_setter?(attribute) or
         | 
| 146 | 
            +
                      tk_widget_has_attribute_getter_setter?(attribute) or
         | 
| 147 | 
            +
                      has_state?(attribute) or
         | 
| 127 148 | 
             
                      respond_to?(attribute_setter(attribute), args)
         | 
| 128 149 | 
             
                  end
         | 
| 129 150 |  | 
| @@ -135,6 +156,13 @@ module Glimmer | |
| 135 156 | 
             
                      @tk.send(attribute_setter(attribute), *args) unless @tk.send(attribute) == args.first
         | 
| 136 157 | 
             
                    elsif tk_widget_has_attribute_getter_setter?(attribute)
         | 
| 137 158 | 
             
                      @tk.send(attribute, *args)
         | 
| 159 | 
            +
                    elsif has_state?(attribute)
         | 
| 160 | 
            +
                      attribute = attribute.sub(/=$/, '')
         | 
| 161 | 
            +
                      if !!args.first
         | 
| 162 | 
            +
                        @tk.tile_state(attribute)
         | 
| 163 | 
            +
                      else
         | 
| 164 | 
            +
                        @tk.tile_state("!#{attribute}")
         | 
| 165 | 
            +
                      end
         | 
| 138 166 | 
             
                    else
         | 
| 139 167 | 
             
                      send(attribute_setter(attribute), args)
         | 
| 140 168 | 
             
                    end
         | 
| @@ -146,6 +174,8 @@ module Glimmer | |
| 146 174 | 
             
                      widget_custom_attribute[:getter][:invoker].call(@tk, args)
         | 
| 147 175 | 
             
                    elsif tk_widget_has_attribute_getter_setter?(attribute)
         | 
| 148 176 | 
             
                      @tk.send(attribute)
         | 
| 177 | 
            +
                    elsif has_state?(attribute)
         | 
| 178 | 
            +
                      @tk.tile_instate(attribute.sub(/\?$/, ''))
         | 
| 149 179 | 
             
                    else
         | 
| 150 180 | 
             
                      send(attribute)
         | 
| 151 181 | 
             
                    end
         | 
| @@ -157,6 +187,12 @@ module Glimmer | |
| 157 187 |  | 
| 158 188 | 
             
                  def widget_custom_attribute_mapping
         | 
| 159 189 | 
             
                    @widget_custom_attribute_mapping ||= {
         | 
| 190 | 
            +
                      ::Tk::Tile::TButton => {
         | 
| 191 | 
            +
                        'image' => {
         | 
| 192 | 
            +
                          getter: {name: 'image', invoker: lambda { |widget, args| @tk.image }},
         | 
| 193 | 
            +
                          setter: {name: 'image=', invoker: lambda { |widget, args| @tk.image = image_argument(args) }},
         | 
| 194 | 
            +
                        },
         | 
| 195 | 
            +
                      },
         | 
| 160 196 | 
             
                      ::Tk::Tile::TCombobox => {
         | 
| 161 197 | 
             
                        'text' => {
         | 
| 162 198 | 
             
                          getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
         | 
| @@ -168,6 +204,10 @@ module Glimmer | |
| 168 204 | 
             
                          getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
         | 
| 169 205 | 
             
                          setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
         | 
| 170 206 | 
             
                        },
         | 
| 207 | 
            +
                        'image' => {
         | 
| 208 | 
            +
                          getter: {name: 'image', invoker: lambda { |widget, args| @tk.image }},
         | 
| 209 | 
            +
                          setter: {name: 'image=', invoker: lambda { |widget, args| @tk.image = image_argument(args) }},
         | 
| 210 | 
            +
                        },
         | 
| 171 211 | 
             
                      },
         | 
| 172 212 | 
             
                      ::Tk::Tile::TEntry => {
         | 
| 173 213 | 
             
                        'text' => {
         | 
| @@ -210,6 +250,22 @@ module Glimmer | |
| 210 250 | 
             
                    }
         | 
| 211 251 | 
             
                  end
         | 
| 212 252 |  | 
| 253 | 
            +
                  def image_argument(args)
         | 
| 254 | 
            +
                    if args.first.is_a?(::TkPhotoImage)
         | 
| 255 | 
            +
                      args.first
         | 
| 256 | 
            +
                    else
         | 
| 257 | 
            +
                      image_args = {}
         | 
| 258 | 
            +
                      image_args.merge!(file: args.first.to_s) if args.first.is_a?(String)
         | 
| 259 | 
            +
                      the_image = ::TkPhotoImage.new(image_args)
         | 
| 260 | 
            +
                      if args.last.is_a?(Hash)
         | 
| 261 | 
            +
                        processed_image = ::TkPhotoImage.new
         | 
| 262 | 
            +
                        processed_image.copy(the_image, args.last)
         | 
| 263 | 
            +
                        the_image = processed_image
         | 
| 264 | 
            +
                      end
         | 
| 265 | 
            +
                      the_image
         | 
| 266 | 
            +
                    end
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
                  
         | 
| 213 269 | 
             
                  def add_observer(observer, attribute)
         | 
| 214 270 | 
             
                    attribute_listener_installers = @tk.class.ancestors.map {|ancestor| widget_attribute_listener_installers[ancestor]}.compact
         | 
| 215 271 | 
             
                    widget_listener_installers = attribute_listener_installers.map{|installer| installer[attribute.to_s]}.compact if !attribute_listener_installers.empty?
         | 
| @@ -222,9 +278,9 @@ module Glimmer | |
| 222 278 |  | 
| 223 279 | 
             
                  def method_missing(method, *args, &block)
         | 
| 224 280 | 
             
                    method = method.to_s
         | 
| 225 | 
            -
                    if args.empty? && block.nil? && widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method]
         | 
| 281 | 
            +
                    if args.empty? && block.nil? && ((widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method]) || has_state?(method))
         | 
| 226 282 | 
             
                      get_attribute(method)
         | 
| 227 | 
            -
                    elsif widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method.sub(/=$/, '')]  | 
| 283 | 
            +
                    elsif method.end_with?('=') && block.nil? && ((widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method.sub(/=$/, '')]) || has_state?(method))
         | 
| 228 284 | 
             
                      set_attribute(method.sub(/=$/, ''), *args)
         | 
| 229 285 | 
             
                    else
         | 
| 230 286 | 
             
                      tk.send(method, *args, &block)
         | 
| @@ -0,0 +1,97 @@ | |
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            # a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            # "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            # the following conditions:
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            require 'glimmer-dsl-tk'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            class HelloButton
         | 
| 25 | 
            +
              include Glimmer
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
              attr_accessor :count
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
              def initialize
         | 
| 30 | 
            +
                @count = 0
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              def launch
         | 
| 34 | 
            +
                root {
         | 
| 35 | 
            +
                  title 'Hello, Button!'
         | 
| 36 | 
            +
                  
         | 
| 37 | 
            +
                  frame {
         | 
| 38 | 
            +
                    grid row: 0, column: 0
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    label {
         | 
| 41 | 
            +
                      grid pady: 15
         | 
| 42 | 
            +
                      text 'Text Button'
         | 
| 43 | 
            +
                    }
         | 
| 44 | 
            +
                    
         | 
| 45 | 
            +
                    button { |b|
         | 
| 46 | 
            +
                      text <= [self, :count, on_read: ->(value) { "Click To Increment: #{value}  " }]
         | 
| 47 | 
            +
                      default 'active'
         | 
| 48 | 
            +
                      focus true
         | 
| 49 | 
            +
                      
         | 
| 50 | 
            +
                      command {
         | 
| 51 | 
            +
                        self.count += 1
         | 
| 52 | 
            +
                      }
         | 
| 53 | 
            +
                    }
         | 
| 54 | 
            +
                  }
         | 
| 55 | 
            +
                    
         | 
| 56 | 
            +
                  frame {
         | 
| 57 | 
            +
                    grid row: 0, column: 1
         | 
| 58 | 
            +
                    
         | 
| 59 | 
            +
                    label {
         | 
| 60 | 
            +
                      grid pady: 15
         | 
| 61 | 
            +
                      text 'Image Button'
         | 
| 62 | 
            +
                    }
         | 
| 63 | 
            +
                    
         | 
| 64 | 
            +
                    button {
         | 
| 65 | 
            +
                      image File.expand_path('../../icons/glimmer.png', __dir__), subsample: 5
         | 
| 66 | 
            +
                      
         | 
| 67 | 
            +
                      command {
         | 
| 68 | 
            +
                        message_box(title: 'Image Button', message: 'Image Button Clicked!')
         | 
| 69 | 
            +
                      }
         | 
| 70 | 
            +
                    }
         | 
| 71 | 
            +
                  }
         | 
| 72 | 
            +
                  
         | 
| 73 | 
            +
                  frame {
         | 
| 74 | 
            +
                    grid row: 0, column: 2
         | 
| 75 | 
            +
                    
         | 
| 76 | 
            +
                    label {
         | 
| 77 | 
            +
                      grid pady: 15
         | 
| 78 | 
            +
                      text 'Text Image Buttons'
         | 
| 79 | 
            +
                    }
         | 
| 80 | 
            +
                    
         | 
| 81 | 
            +
                    ['center', 'top', 'bottom', 'left', 'right'].each do |compound_option|
         | 
| 82 | 
            +
                      button {
         | 
| 83 | 
            +
                        image File.expand_path('../../icons/glimmer.png', __dir__), subsample: 5
         | 
| 84 | 
            +
                        text 'Text Image Button'
         | 
| 85 | 
            +
                        compound compound_option
         | 
| 86 | 
            +
                        
         | 
| 87 | 
            +
                        command {
         | 
| 88 | 
            +
                          message_box(title: 'Text Image Button', message: 'Text Image Button Clicked!', detail: "(#{compound_option})")
         | 
| 89 | 
            +
                        }
         | 
| 90 | 
            +
                      }
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
                  }
         | 
| 93 | 
            +
                }.open
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
            end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
            HelloButton.new.launch
         | 
| @@ -0,0 +1,110 @@ | |
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            # a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            # "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            # the following conditions:
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            require 'glimmer-dsl-tk'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            class HelloLabel
         | 
| 25 | 
            +
              include Glimmer
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
              LABEL_FONTS = ['default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip']
         | 
| 28 | 
            +
              LABEL_RELIEFS = ['flat', 'raised', 'sunken', 'solid', 'ridge', 'groove']
         | 
| 29 | 
            +
              
         | 
| 30 | 
            +
              def launch
         | 
| 31 | 
            +
                root {
         | 
| 32 | 
            +
                  title 'Hello, Label!'
         | 
| 33 | 
            +
                  
         | 
| 34 | 
            +
                  notebook {
         | 
| 35 | 
            +
                    frame(text: 'left-aligned') {
         | 
| 36 | 
            +
                      3.times do |n|
         | 
| 37 | 
            +
                        label {
         | 
| 38 | 
            +
                          text "Field #{n + 1} / default font / flat relief"
         | 
| 39 | 
            +
                          width 60
         | 
| 40 | 
            +
                          anchor 'w'
         | 
| 41 | 
            +
                        }
         | 
| 42 | 
            +
                      end
         | 
| 43 | 
            +
                    }
         | 
| 44 | 
            +
                    
         | 
| 45 | 
            +
                    frame(text: 'centered') {
         | 
| 46 | 
            +
                      9.times do |n|
         | 
| 47 | 
            +
                        label {
         | 
| 48 | 
            +
                          text "Field #{n + 1} / fixed font / raised relief"
         | 
| 49 | 
            +
                          width 80
         | 
| 50 | 
            +
                          anchor 'center'
         | 
| 51 | 
            +
                          font 'fixed'
         | 
| 52 | 
            +
                          relief 'raised'
         | 
| 53 | 
            +
                        }
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
                    }
         | 
| 56 | 
            +
                    
         | 
| 57 | 
            +
                    frame(text: 'right-aligned') {
         | 
| 58 | 
            +
                      9.times do |n|
         | 
| 59 | 
            +
                        label {
         | 
| 60 | 
            +
                          text "Field #{n + 1} / small_caption font / ridge relief"
         | 
| 61 | 
            +
                          width 80
         | 
| 62 | 
            +
                          anchor 'e'
         | 
| 63 | 
            +
                          font 'small_caption'
         | 
| 64 | 
            +
                          relief 'ridge'
         | 
| 65 | 
            +
                        }
         | 
| 66 | 
            +
                      end
         | 
| 67 | 
            +
                    }
         | 
| 68 | 
            +
                    
         | 
| 69 | 
            +
                    frame(text: 'justified') {
         | 
| 70 | 
            +
                      label {
         | 
| 71 | 
            +
                        text <<~MULTI_LINE_STRING
         | 
| 72 | 
            +
                          This is a very long paragraph that spans multiple lines. It looks better and
         | 
| 73 | 
            +
                          is easier to read when justified. In fact, this is how to make it look like a
         | 
| 74 | 
            +
                          new paper column. That results in professional looking text. Magazines use the
         | 
| 75 | 
            +
                          same sort of justified text. Word processors also support justified text. In
         | 
| 76 | 
            +
                          fact, this is how text is made for news papers and magainzes, and then published
         | 
| 77 | 
            +
                          in paper form and digitally.
         | 
| 78 | 
            +
                        MULTI_LINE_STRING
         | 
| 79 | 
            +
                        width 60
         | 
| 80 | 
            +
                        anchor 'center'
         | 
| 81 | 
            +
                        justify 'center' # other options are: 'left' and 'right'
         | 
| 82 | 
            +
                        font 'caption' # other options are: 'default', 'text', 'fixed', 'menu', 'heading', 'small_caption', 'icon', 'tooltip'
         | 
| 83 | 
            +
                        foreground 'blue'
         | 
| 84 | 
            +
                        relief 'sunken' # other options are: 'flat' (default), 'raised', 'solid', 'ridge', 'groove'
         | 
| 85 | 
            +
                      }
         | 
| 86 | 
            +
                    }
         | 
| 87 | 
            +
                    
         | 
| 88 | 
            +
                    frame(text: 'images') {
         | 
| 89 | 
            +
                      ['denmark', 'finland', 'norway'].each do |image_name|
         | 
| 90 | 
            +
                        label {
         | 
| 91 | 
            +
                          image File.expand_path("images/#{image_name}.png", __dir__)
         | 
| 92 | 
            +
                        }
         | 
| 93 | 
            +
                      end
         | 
| 94 | 
            +
                    }
         | 
| 95 | 
            +
                    
         | 
| 96 | 
            +
                    frame(text: 'background images') {
         | 
| 97 | 
            +
                      ['italy', 'france', 'mexico'].each do |image_name|
         | 
| 98 | 
            +
                        label {
         | 
| 99 | 
            +
                          text image_name.capitalize
         | 
| 100 | 
            +
                          image File.expand_path("images/#{image_name}.png", __dir__)
         | 
| 101 | 
            +
                          compound 'center'
         | 
| 102 | 
            +
                        }
         | 
| 103 | 
            +
                      end
         | 
| 104 | 
            +
                    }
         | 
| 105 | 
            +
                  }
         | 
| 106 | 
            +
                }.open
         | 
| 107 | 
            +
              end
         | 
| 108 | 
            +
            end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
            HelloLabel.new.launch
         | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
| Binary file | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: glimmer-dsl-tk
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.17
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - AndyMaleh
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2021-10- | 
| 11 | 
            +
            date: 2021-10-11 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: glimmer
         | 
| @@ -210,14 +210,25 @@ files: | |
| 210 210 | 
             
            - lib/glimmer/tk/root_proxy.rb
         | 
| 211 211 | 
             
            - lib/glimmer/tk/treeview_proxy.rb
         | 
| 212 212 | 
             
            - lib/glimmer/tk/widget_proxy.rb
         | 
| 213 | 
            +
            - samples/hello/hello_button.rb
         | 
| 213 214 | 
             
            - samples/hello/hello_combobox.rb
         | 
| 214 215 | 
             
            - samples/hello/hello_computed.rb
         | 
| 215 216 | 
             
            - samples/hello/hello_computed/contact.rb
         | 
| 217 | 
            +
            - samples/hello/hello_label.rb
         | 
| 216 218 | 
             
            - samples/hello/hello_list_multi_selection.rb
         | 
| 217 219 | 
             
            - samples/hello/hello_list_single_selection.rb
         | 
| 218 220 | 
             
            - samples/hello/hello_message_box.rb
         | 
| 219 221 | 
             
            - samples/hello/hello_tab.rb
         | 
| 220 222 | 
             
            - samples/hello/hello_world.rb
         | 
| 223 | 
            +
            - samples/hello/images/denmark.png
         | 
| 224 | 
            +
            - samples/hello/images/finland.png
         | 
| 225 | 
            +
            - samples/hello/images/france.png
         | 
| 226 | 
            +
            - samples/hello/images/germany.png
         | 
| 227 | 
            +
            - samples/hello/images/italy.png
         | 
| 228 | 
            +
            - samples/hello/images/mexico.png
         | 
| 229 | 
            +
            - samples/hello/images/netherlands.png
         | 
| 230 | 
            +
            - samples/hello/images/norway.png
         | 
| 231 | 
            +
            - samples/hello/images/usa.png
         | 
| 221 232 | 
             
            homepage: http://github.com/AndyObtiva/glimmer-dsl-tk
         | 
| 222 233 | 
             
            licenses:
         | 
| 223 234 | 
             
            - MIT
         |