glimmer-dsl-opal 0.7.0 → 0.7.1
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 +8 -0
 - data/README.md +16 -14
 - data/VERSION +1 -1
 - data/lib/glimmer-dsl-opal.rb +58 -0
 - data/lib/glimmer-dsl-opal/ext/date.rb +1 -1
 - data/lib/glimmer-dsl-opal/samples/hello/hello_table.rb +3 -3
 - data/lib/glimmer-dsl-swt.rb +20 -35
 - data/lib/glimmer/data_binding/table_items_binding.rb +4 -2
 - data/lib/glimmer/dsl/opal/widget_expression.rb +6 -2
 - data/lib/glimmer/swt/composite_proxy.rb +5 -1
 - data/lib/glimmer/swt/control_editor.rb +53 -0
 - data/lib/glimmer/swt/layout_proxy.rb +1 -1
 - data/lib/glimmer/swt/table_column_proxy.rb +9 -0
 - data/lib/glimmer/swt/table_editor.rb +65 -0
 - data/lib/glimmer/swt/table_item_proxy.rb +28 -0
 - data/lib/glimmer/swt/table_proxy.rb +357 -11
 - data/lib/glimmer/swt/widget_proxy.rb +73 -9
 - metadata +4 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b4e81c8aae870295468f5c0e573da962daa58837efda4742c9855313ae29f42a
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 40df246c27977d3fa862a452cdfb2dd99ad0b506374408c69e25666b3fc7fa50
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c46c3bdfcc129557ac54640d2d905cb7495f010ff1b81422c5b55529a01ecb67c698b4724029b62b9cbc6bcb46727763185ba1b4469c0355259d16acd1f228f1
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 803c487121b4092f024fabca666e359fcdfeca87482b95a391e6b857b19dca28f46a845fc46e6c189e73254c1aa3a1f53d8cbe51c113f425be5019544a353913
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Change Log
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## 0.7.1
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            - Combo table editor (enabled in Hello, Table! sample)
         
     | 
| 
      
 6 
     | 
    
         
            +
            - Fix issue with table cell selection for editing not working
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Remove widget from parent upon dispose
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Remove listeners upon widget dispose
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       3 
10 
     | 
    
         
             
            ## 0.7.0
         
     | 
| 
       4 
11 
     | 
    
         | 
| 
       5 
12 
     | 
    
         
             
            - Hello, Table! Sample
         
     | 
| 
         @@ -127,3 +134,4 @@ 
     | 
|
| 
       127 
134 
     | 
    
         | 
| 
       128 
135 
     | 
    
         
             
            - Initial support for webifying Glimmer SWT apps
         
     | 
| 
       129 
136 
     | 
    
         
             
            - Support for Shell and Label widgets (text property only).
         
     | 
| 
      
 137 
     | 
    
         
            +
            - Hello, World! sample support
         
     | 
    
        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 Opal 0.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 Opal 0.7.1 (Pure Ruby Web GUI)
         
     | 
| 
       2 
2 
     | 
    
         
             
            [](http://badge.fury.io/rb/glimmer-dsl-opal)
         
     | 
| 
       3 
3 
     | 
    
         
             
            [](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
         @@ -8,11 +8,11 @@ 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            Use in one of two ways:
         
     | 
| 
       10 
10 
     | 
    
         
             
            - **Direct:** build the GUI of web apps with the same friendly desktop GUI Ruby syntax as [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt), thus requiring a lot less code than web technologies that is in pure Ruby and avoiding opaque web concepts like 'render' and 'reactive'. No HTML/JS/CSS skills are even required. Web designers may be involved with CSS styling only if needed.
         
     | 
| 
       11 
     | 
    
         
            -
            - **Adapter:**  
     | 
| 
      
 11 
     | 
    
         
            +
            - **Adapter:** auto-webify [Glimmer](https://github.com/AndyObtiva/glimmer) desktop apps (i.e. apps built with [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt)) via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) without changing a line of code. Just insert them as a single require statement in a Rails app, and BOOM! They're running on the web! Apps may then optionally be custom-styled for the web by web designers with standard CSS if needed.
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            Glimmer DSL for Opal successfully reuses the entire [Glimmer](https://github.com/AndyObtiva/glimmer) core DSL engine in [Opal Ruby](https://opalrb.com/) inside a web browser, and as such inherits the full range of powerful Glimmer desktop [data-binding](https://github.com/AndyObtiva/glimmer#data-binding) capabilities for the web.
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            NOTE: Alpha Version 0.7. 
     | 
| 
      
 15 
     | 
    
         
            +
            NOTE: Alpha Version 0.7.1 only supports bare-minimum capabilities for the following [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) [samples](https://github.com/AndyObtiva/glimmer#samples):
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
17 
     | 
    
         
             
            Hello:
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
         @@ -49,16 +49,6 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems: 
     | 
|
| 
       49 
49 
     | 
    
         
             
            - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
         
     | 
| 
       50 
50 
     | 
    
         
             
            - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
            ## Background
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
            The original idea behind Glimmer DSL for Opal was that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The GUI DSL is very simple in Glimmer DSL for SWT. Once the app is built. You simply embed it in a Rails app as a one line require statement after adding the Glimmer DSL for Opal gem, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser).
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            Part of the idea is that web browsers just render GUI widgets similar to those of a desktop app (after all a web browser is a desktop app), so whether you run your GUI on the desktop or on the web should just be a low-level concern, hopefully automated completely with Glimmer DSL for Opal.
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
            Last but not least, you would likely want some special branding on the web, so you can push that off to a web designer who would be more than happy to do the web graphic design and customize the look and feel with pure CSS (no need for programming with Ruby or JavaScript). This enables a clean separation of concerns and distribution of tasks among developers and designers, let alone saving effort on the web GUI by reusing the desktop GUI as a base right off the bat.
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            Alternatively, web developers may directly use [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) to build the GUI of web apps since it is as simple as desktop development, thus requiring a lot less code that is in pure Ruby only (as demonstrated in examples below) and avoiding opaque web concepts like 'render' and 'reactive' due to treating GUI as persistent just like desktop apps do. No HTML/JS/CSS skills are even required. Still, web designers may be involved with CSS only if needed, thanks to the clean semantic markup [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) produces.
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
52 
     | 
    
         
             
            ## Supported Glimmer DSL Keywords
         
     | 
| 
       63 
53 
     | 
    
         | 
| 
       64 
54 
     | 
    
         
             
            The following keywords from [glimmer-dsl-swt](https://github.com/AndyObtiva/glimmer-dsl-swt) have partial support in Opal:
         
     | 
| 
         @@ -99,6 +89,16 @@ Event loop: 
     | 
|
| 
       99 
89 
     | 
    
         
             
            - `display`
         
     | 
| 
       100 
90 
     | 
    
         
             
            - `async_exec`
         
     | 
| 
       101 
91 
     | 
    
         | 
| 
      
 92 
     | 
    
         
            +
            ## Background
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            The original idea behind Glimmer DSL for Opal was that you start by having a [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) desktop app that communicates with a Rails API for any web/cloud concerns. The pure Ruby [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer-dsl-swt) is very simple, so it is more productive to build GUI in it since it does not go through a server/client request/response cycle and can be iterated on locally with a much shorter feedback cycle. Once the GUI and the rest of the app is built. You simply embed it in a Rails app as a one line require statement after adding the Glimmer DSL for Opal gem, and BOOM, it just works on the web inside a web browser with the same server/client communication you had in the desktop app (I am working on adding minimal support for net/http in Opal so that desktop apps that use it continue to work in a web browser. Until then, just use [Opal-jQuery](https://github.com/opal/opal-jquery) http support). That way, you get two apps for one: desktop and web.
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            Part of the idea is that web browsers just render GUI widgets similar to those of a desktop app (after all a web browser is a desktop app), so whether you run your GUI on the desktop or on the web should just be a low-level concern, hopefully automated completely with Glimmer DSL for Opal.
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            Last but not least, you would likely want some special branding on the web, so you can push that off to a web designer who would be more than happy to do the web graphic design and customize the look and feel with pure CSS (no need for programming with Ruby or JavaScript). This enables a clean separation of concerns and distribution of tasks among developers and designers, let alone saving effort on the web GUI by reusing the desktop GUI as a base right off the bat.
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            Alternatively, web developers may directly use [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) to build the GUI of web apps since it is as simple as desktop development, thus requiring a lot less code that is in pure Ruby only (as demonstrated in examples below) and avoiding opaque web concepts like 'render' and 'reactive' due to treating GUI as persistent just like desktop apps do. No HTML/JS/CSS skills are even required. Still, web designers may be involved with CSS only if needed, thanks to the clean semantic markup [Glimmer DSL for Opal](https://rubygems.org/gems/glimmer-dsl-opal) automatically produces.
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
       102 
102 
     | 
    
         
             
            ## Pre-requisites
         
     | 
| 
       103 
103 
     | 
    
         | 
| 
       104 
104 
     | 
    
         
             
            - Rails 5: [https://github.com/rails/rails/tree/5-2-stable](https://github.com/rails/rails/tree/5-2-stable)
         
     | 
| 
         @@ -133,7 +133,7 @@ Add the following to `Gemfile`: 
     | 
|
| 
       133 
133 
     | 
    
         
             
            gem 'opal-rails', '~> 1.1.2'
         
     | 
| 
       134 
134 
     | 
    
         
             
            gem 'opal-async', '~> 1.2.0'
         
     | 
| 
       135 
135 
     | 
    
         
             
            gem 'opal-jquery', '~> 0.4.4'
         
     | 
| 
       136 
     | 
    
         
            -
            gem 'glimmer-dsl-opal', '~> 0.7. 
     | 
| 
      
 136 
     | 
    
         
            +
            gem 'glimmer-dsl-opal', '~> 0.7.1'
         
     | 
| 
       137 
137 
     | 
    
         
             
            gem 'glimmer-dsl-xml', '~> 1.1.0', require: false
         
     | 
| 
       138 
138 
     | 
    
         
             
            gem 'glimmer-dsl-css', '~> 1.1.0', require: false
         
     | 
| 
       139 
139 
     | 
    
         | 
| 
         @@ -170,6 +170,8 @@ Edit `app/views/layouts/application.html.erb` and add the following below other 
     | 
|
| 
       170 
170 
     | 
    
         
             
            <%= stylesheet_link_tag    'glimmer/glimmer', media: 'all', 'data-turbolinks-track': 'reload' %>
         
     | 
| 
       171 
171 
     | 
    
         
             
            ```
         
     | 
| 
       172 
172 
     | 
    
         | 
| 
      
 173 
     | 
    
         
            +
            Clear the file `app/views/welcomes/index.html.erb` from any content.
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
       173 
175 
     | 
    
         
             
            Open a `Document.ready?` block and add inside it Glimmer GUI DSL code or a require statement for one of the samples below.
         
     | 
| 
       174 
176 
     | 
    
         | 
| 
       175 
177 
     | 
    
         
             
            ```ruby
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            0.7. 
     | 
| 
      
 1 
     | 
    
         
            +
            0.7.1
         
     | 
    
        data/lib/glimmer-dsl-opal.rb
    CHANGED
    
    | 
         @@ -1,3 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2020 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 
     | 
    
         
            +
             
     | 
| 
       1 
22 
     | 
    
         
             
            require 'opal'
         
     | 
| 
       2 
23 
     | 
    
         | 
| 
       3 
24 
     | 
    
         
             
            GLIMMER_DSL_OPAL_ROOT = File.expand_path('../..', __FILE__)
         
     | 
| 
         @@ -45,6 +66,7 @@ if RUBY_ENGINE == 'opal' 
     | 
|
| 
       45 
66 
     | 
    
         
             
              require 'glimmer-dsl-xml'
         
     | 
| 
       46 
67 
     | 
    
         
             
              require 'glimmer-dsl-css'
         
     | 
| 
       47 
68 
     | 
    
         
             
              Element.alias_native :replace_with, :replaceWith
         
     | 
| 
      
 69 
     | 
    
         
            +
              Element.alias_native :select
         
     | 
| 
       48 
70 
     | 
    
         | 
| 
       49 
71 
     | 
    
         
             
            #   Glimmer::Config.loop_max_count = 20
         
     | 
| 
       50 
72 
     | 
    
         | 
| 
         @@ -54,6 +76,42 @@ if RUBY_ENGINE == 'opal' 
     | 
|
| 
       54 
76 
     | 
    
         
             
                result ||= method == '<<'
         
     | 
| 
       55 
77 
     | 
    
         
             
                result ||= method == 'handle'
         
     | 
| 
       56 
78 
     | 
    
         
             
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
              
         
     | 
| 
      
 80 
     | 
    
         
            +
              class OS
         
     | 
| 
      
 81 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def windows?
         
     | 
| 
      
 83 
     | 
    
         
            +
                    # No Op in Opal
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  
         
     | 
| 
      
 86 
     | 
    
         
            +
                  def mac?
         
     | 
| 
      
 87 
     | 
    
         
            +
                    # No Op in Opal
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                  
         
     | 
| 
      
 90 
     | 
    
         
            +
                  def linux?
         
     | 
| 
      
 91 
     | 
    
         
            +
                    # No Op in Opal
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
              
         
     | 
| 
      
 96 
     | 
    
         
            +
              class File
         
     | 
| 
      
 97 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 98 
     | 
    
         
            +
                  def read(*args, &block)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    # TODO implement via asset downloads in the future
         
     | 
| 
      
 100 
     | 
    
         
            +
                    # No Op in Opal
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
              end
         
     | 
| 
      
 104 
     | 
    
         
            +
              
         
     | 
| 
      
 105 
     | 
    
         
            +
              class Display
         
     | 
| 
      
 106 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 107 
     | 
    
         
            +
                  def setAppName(app_name)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    # No Op in Opal
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
                  def setAppVersion(version)
         
     | 
| 
      
 111 
     | 
    
         
            +
                    # No Op in Opal
         
     | 
| 
      
 112 
     | 
    
         
            +
                  end
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
       57 
115 
     | 
    
         
             
            else
         
     | 
| 
       58 
116 
     | 
    
         
             
              require_relative 'glimmer/engine'
         
     | 
| 
       59 
117 
     | 
    
         
             
            end
         
     | 
| 
         @@ -45,7 +45,7 @@ class Time 
     | 
|
| 
       45 
45 
     | 
    
         
             
                alias new_original new
         
     | 
| 
       46 
46 
     | 
    
         
             
                def new(*args)
         
     | 
| 
       47 
47 
     | 
    
         
             
                  if args.size >= 7
         
     | 
| 
       48 
     | 
    
         
            -
                     
     | 
| 
      
 48 
     | 
    
         
            +
                    Glimmer::Config.logger.debug "Dropped timezone #{args[6]} from Time.new(#{args.map(&:to_s)}) constructor arguments since Opal does not support it!"
         
     | 
| 
       49 
49 
     | 
    
         
             
                    args = args[0...6]
         
     | 
| 
       50 
50 
     | 
    
         
             
                  end
         
     | 
| 
       51 
51 
     | 
    
         
             
                  new_original(*args)
         
     | 
| 
         @@ -218,17 +218,17 @@ class HelloTable 
     | 
|
| 
       218 
218 
     | 
    
         
             
                    table_column {
         
     | 
| 
       219 
219 
     | 
    
         
             
                      text 'Ballpark'
         
     | 
| 
       220 
220 
     | 
    
         
             
                      width 180
         
     | 
| 
       221 
     | 
    
         
            -
             
     | 
| 
      
 221 
     | 
    
         
            +
                      editor :none
         
     | 
| 
       222 
222 
     | 
    
         
             
                    }
         
     | 
| 
       223 
223 
     | 
    
         
             
                    table_column {
         
     | 
| 
       224 
224 
     | 
    
         
             
                      text 'Home Team'
         
     | 
| 
       225 
225 
     | 
    
         
             
                      width 150
         
     | 
| 
       226 
     | 
    
         
            -
             
     | 
| 
      
 226 
     | 
    
         
            +
                      editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
         
     | 
| 
       227 
227 
     | 
    
         
             
                    }
         
     | 
| 
       228 
228 
     | 
    
         
             
                    table_column {
         
     | 
| 
       229 
229 
     | 
    
         
             
                      text 'Away Team'
         
     | 
| 
       230 
230 
     | 
    
         
             
                      width 150
         
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
      
 231 
     | 
    
         
            +
                      editor :combo, :read_only # read_only is simply an SWT style passed to combo widget
         
     | 
| 
       232 
232 
     | 
    
         
             
                    }
         
     | 
| 
       233 
233 
     | 
    
         
             
                    table_column {
         
     | 
| 
       234 
234 
     | 
    
         
             
                      text 'Promotion'
         
     | 
    
        data/lib/glimmer-dsl-swt.rb
    CHANGED
    
    | 
         @@ -1,37 +1,22 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
                  # No Op in Opal
         
     | 
| 
       22 
     | 
    
         
            -
                end
         
     | 
| 
       23 
     | 
    
         
            -
              end
         
     | 
| 
       24 
     | 
    
         
            -
            end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            class Display
         
     | 
| 
       27 
     | 
    
         
            -
              class << self
         
     | 
| 
       28 
     | 
    
         
            -
                def setAppName(app_name)
         
     | 
| 
       29 
     | 
    
         
            -
                  # No Op in Opal
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
                def setAppVersion(version)
         
     | 
| 
       32 
     | 
    
         
            -
                  # No Op in Opal
         
     | 
| 
       33 
     | 
    
         
            -
                end
         
     | 
| 
       34 
     | 
    
         
            -
              end
         
     | 
| 
       35 
     | 
    
         
            -
            end
         
     | 
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2020 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.
         
     | 
| 
       36 
21 
     | 
    
         | 
| 
       37 
22 
     | 
    
         
             
            require 'glimmer-dsl-opal'
         
     | 
| 
         @@ -35,7 +35,7 @@ module Glimmer 
     | 
|
| 
       35 
35 
     | 
    
         
             
                    model_cells = new_model_collection.to_a.map {|m| @table.cells_for(m)}
         
     | 
| 
       36 
36 
     | 
    
         
             
                    return if table_cells == model_cells
         
     | 
| 
       37 
37 
     | 
    
         
             
                    if new_model_collection and new_model_collection.is_a?(Array)
         
     | 
| 
       38 
     | 
    
         
            -
            #           @table_items_observer_registration&.unobserve
         
     | 
| 
      
 38 
     | 
    
         
            +
            #           @table_items_observer_registration&.unobserve # TODO re-enable
         
     | 
| 
       39 
39 
     | 
    
         
             
                      @table_items_observer_registration = observe(new_model_collection, @column_properties)
         
     | 
| 
       40 
40 
     | 
    
         
             
                      add_dependent(@table_observer_registration => @table_items_observer_registration)
         
     | 
| 
       41 
41 
     | 
    
         
             
                      @model_collection = new_model_collection
         
     | 
| 
         @@ -45,8 +45,10 @@ module Glimmer 
     | 
|
| 
       45 
45 
     | 
    
         
             
                  end
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
47 
     | 
    
         
             
                  def populate_table(model_collection, parent, column_properties)
         
     | 
| 
       48 
     | 
    
         
            -
                     
     | 
| 
      
 48 
     | 
    
         
            +
                    @skip_populate_table = model_collection&.sort_by(&:hash).map {|m| @table.column_properties.map {|p| m.send(p)}} == @last_populated_model_collection_properties
         
     | 
| 
      
 49 
     | 
    
         
            +
                    return if @skip_populate_table
         
     | 
| 
       49 
50 
     | 
    
         
             
                    @last_populated_model_collection = model_collection
         
     | 
| 
      
 51 
     | 
    
         
            +
                    @last_populated_model_collection_properties = model_collection&.sort_by(&:hash).map {|m| @table.column_properties.map {|p| m.send(p)}}
         
     | 
| 
       50 
52 
     | 
    
         
             
                    # TODO improve performance
         
     | 
| 
       51 
53 
     | 
    
         
             
                    selected_table_item_models = parent.selection.map(&:get_data)
         
     | 
| 
       52 
54 
     | 
    
         
             
                    old_items = parent.items
         
     | 
| 
         @@ -20,8 +20,12 @@ module Glimmer 
     | 
|
| 
       20 
20 
     | 
    
         
             
                    end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                    def add_content(parent, &block)
         
     | 
| 
       23 
     | 
    
         
            -
                       
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
                      if parent.rendered?
         
     | 
| 
      
 24 
     | 
    
         
            +
                        super(parent, &block)
         
     | 
| 
      
 25 
     | 
    
         
            +
                        parent.post_add_content
         
     | 
| 
      
 26 
     | 
    
         
            +
                      else
         
     | 
| 
      
 27 
     | 
    
         
            +
                        parent.add_content_on_render(&block)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      end
         
     | 
| 
       25 
29 
     | 
    
         
             
                    end
         
     | 
| 
       26 
30 
     | 
    
         
             
                  end
         
     | 
| 
       27 
31 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2020 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 
     | 
    
         
            +
            module Glimmer
         
     | 
| 
      
 23 
     | 
    
         
            +
              module SWT
         
     | 
| 
      
 24 
     | 
    
         
            +
                # Emulates SWT's native org.eclipse.swt.custom.ControlEditor
         
     | 
| 
      
 25 
     | 
    
         
            +
                class ControlEditor
         
     | 
| 
      
 26 
     | 
    
         
            +
                  ATTRIBUTES = [:grabHorizontal, :grabVertical, :horizontalAlignment, :verticalAlignment, :minimumWidth, :minimumHeight]
         
     | 
| 
      
 27 
     | 
    
         
            +
                  attr_accessor *ATTRIBUTES
         
     | 
| 
      
 28 
     | 
    
         
            +
                  ATTRIBUTES.each do |attribute|
         
     | 
| 
      
 29 
     | 
    
         
            +
                    alias_method attribute.underscore, attribute
         
     | 
| 
      
 30 
     | 
    
         
            +
                    alias_method "#{attribute.underscore}=", "#{attribute}="
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  
         
     | 
| 
      
 33 
     | 
    
         
            +
                  # TODO consider supporting a java_attr_accessor to get around having to generate all the aliases manually
         
     | 
| 
      
 34 
     | 
    
         
            +
                  attr_accessor :editor
         
     | 
| 
      
 35 
     | 
    
         
            +
                  alias getEditor editor
         
     | 
| 
      
 36 
     | 
    
         
            +
                  alias get_editor editor
         
     | 
| 
      
 37 
     | 
    
         
            +
                  alias setEditor editor=
         
     | 
| 
      
 38 
     | 
    
         
            +
                  alias set_editor editor=
         
     | 
| 
      
 39 
     | 
    
         
            +
                  
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # TODO implement `#layout` method if needed
         
     | 
| 
      
 41 
     | 
    
         
            +
                  
         
     | 
| 
      
 42 
     | 
    
         
            +
                  attr_reader :composite
         
     | 
| 
      
 43 
     | 
    
         
            +
                  
         
     | 
| 
      
 44 
     | 
    
         
            +
                  def initialize(composite)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    @composite = composite
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                  
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # TODO implement showing editor for composite or canvas
         
     | 
| 
      
 49 
     | 
    
         
            +
            #       def editor=(widget)
         
     | 
| 
      
 50 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -18,7 +18,7 @@ module Glimmer 
     | 
|
| 
       18 
18 
     | 
    
         
             
                      a_layout_class = Glimmer::SWT.const_get(class_name_main.to_sym) rescue Glimmer::SWT.const_get(class_name_alternative.to_sym)
         
     | 
| 
       19 
19 
     | 
    
         
             
                      a_layout_class if a_layout_class.ancestors.include?(Glimmer::SWT::LayoutProxy)
         
     | 
| 
       20 
20 
     | 
    
         
             
                    rescue => e
         
     | 
| 
       21 
     | 
    
         
            -
                       
     | 
| 
      
 21 
     | 
    
         
            +
                      Glimmer::Config.logger.debug "Layout #{keyword} was not found!"
         
     | 
| 
       22 
22 
     | 
    
         
             
                      nil
         
     | 
| 
       23 
23 
     | 
    
         
             
                    end
         
     | 
| 
       24 
24 
     | 
    
         | 
| 
         @@ -74,6 +74,15 @@ module Glimmer 
     | 
|
| 
       74 
74 
     | 
    
         
             
                    dom_element.find('.sort-direction')
         
     | 
| 
       75 
75 
     | 
    
         
             
                  end
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
      
 77 
     | 
    
         
            +
                  # Sets editor (e.g. combo)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  def editor=(args)
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @editor = args
         
     | 
| 
      
 80 
     | 
    
         
            +
                  end
         
     | 
| 
      
 81 
     | 
    
         
            +
                  
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def editable?
         
     | 
| 
      
 83 
     | 
    
         
            +
                    !@editor&.include?(:none)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  
         
     | 
| 
       77 
86 
     | 
    
         
             
                  def observation_request_to_event_mapping
         
     | 
| 
       78 
87 
     | 
    
         
             
                    {
         
     | 
| 
       79 
88 
     | 
    
         
             
                      'on_widget_selected' => {
         
     | 
| 
         @@ -0,0 +1,65 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2020 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/swt/control_editor'
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            module Glimmer
         
     | 
| 
      
 25 
     | 
    
         
            +
              module SWT
         
     | 
| 
      
 26 
     | 
    
         
            +
                # Emulates SWT's native org.eclipse.swt.custom.TableEditor
         
     | 
| 
      
 27 
     | 
    
         
            +
                class TableEditor < ControlEditor
         
     | 
| 
      
 28 
     | 
    
         
            +
                  alias table composite
         
     | 
| 
      
 29 
     | 
    
         
            +
                  
         
     | 
| 
      
 30 
     | 
    
         
            +
                  def editor=(editor_widget, table_item, table_column_index)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    # TODO consider making editor not gain an ID or gain a separate set of IDs to avoid clashing with standard widget predictability of ID
         
     | 
| 
      
 32 
     | 
    
         
            +
                    @table_item = table_item
         
     | 
| 
      
 33 
     | 
    
         
            +
                    @table_column_index = table_column_index
         
     | 
| 
      
 34 
     | 
    
         
            +
                    @editor_widget = editor_widget
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @old_value = table_item.cell_dom_element(table_column_index).html
         
     | 
| 
      
 36 
     | 
    
         
            +
                    table_item.cell_dom_element(table_column_index).html('')
         
     | 
| 
      
 37 
     | 
    
         
            +
                    editor_widget.render(table_item.cell_dom_element(table_column_index))
         
     | 
| 
      
 38 
     | 
    
         
            +
                    # TODO tweak the width perfectly so it doesn't expand the table cell
         
     | 
| 
      
 39 
     | 
    
         
            +
            #         editor_widget.dom_element.css('width', 'calc(100% - 20px)')
         
     | 
| 
      
 40 
     | 
    
         
            +
                    editor_widget.dom_element.css('width', '90%') # just a good enough approximation
         
     | 
| 
      
 41 
     | 
    
         
            +
                    editor_widget.dom_element.css('height', "#{minimumHeight}px")
         
     | 
| 
      
 42 
     | 
    
         
            +
                    editor_widget.dom_element.add_class('table-editor')
         
     | 
| 
      
 43 
     | 
    
         
            +
                    # TODO consider relying on autofocus instead
         
     | 
| 
      
 44 
     | 
    
         
            +
                    editor_widget.dom_element.focus
         
     | 
| 
      
 45 
     | 
    
         
            +
                    # TODO consider doing the following line only for :text editor
         
     | 
| 
      
 46 
     | 
    
         
            +
                    editor_widget.dom_element.select
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  alias set_editor editor=
         
     | 
| 
      
 49 
     | 
    
         
            +
                  alias setEditor editor=
         
     | 
| 
      
 50 
     | 
    
         
            +
                  
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def cancel!
         
     | 
| 
      
 52 
     | 
    
         
            +
                    done!
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                  
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def save!
         
     | 
| 
      
 56 
     | 
    
         
            +
                    done!
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  
         
     | 
| 
      
 59 
     | 
    
         
            +
                  def done!
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @table_item.cell_dom_element(@table_column_index).html(@old_value) unless @old_value.nil?
         
     | 
| 
      
 61 
     | 
    
         
            +
                    @old_value = nil
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,9 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2020 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 
     | 
    
         
            +
             
     | 
| 
       1 
22 
     | 
    
         
             
            require 'glimmer/swt/widget_proxy'
         
     | 
| 
       2 
23 
     | 
    
         | 
| 
       3 
24 
     | 
    
         
             
            module Glimmer
         
     | 
| 
       4 
25 
     | 
    
         
             
              module SWT
         
     | 
| 
       5 
26 
     | 
    
         
             
                class TableItemProxy < WidgetProxy
         
     | 
| 
       6 
27 
     | 
    
         
             
                  STYLE = <<~CSS
         
     | 
| 
      
 28 
     | 
    
         
            +
                    tr.table-item td {
         
     | 
| 
      
 29 
     | 
    
         
            +
                      padding-bottom: 0;
         
     | 
| 
      
 30 
     | 
    
         
            +
                    }
         
     | 
| 
       7 
31 
     | 
    
         
             
                    tr.table-item:nth-child(even):not(.selected) {
         
     | 
| 
       8 
32 
     | 
    
         
             
                      background: rgb(243, 244, 246);
         
     | 
| 
       9 
33 
     | 
    
         
             
                    }
         
     | 
| 
         @@ -60,6 +84,10 @@ module Glimmer 
     | 
|
| 
       60 
84 
     | 
    
         
             
                    'tr'
         
     | 
| 
       61 
85 
     | 
    
         
             
                  end
         
     | 
| 
       62 
86 
     | 
    
         | 
| 
      
 87 
     | 
    
         
            +
                  def cell_dom_element(column_index)
         
     | 
| 
      
 88 
     | 
    
         
            +
                    dom_element.find("td:nth-child(#{column_index + 1})")
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end
         
     | 
| 
      
 90 
     | 
    
         
            +
                  
         
     | 
| 
       63 
91 
     | 
    
         
             
                  def redraw
         
     | 
| 
       64 
92 
     | 
    
         
             
                    super() #TODO re-enable and remove below lines
         
     | 
| 
       65 
93 
     | 
    
         | 
| 
         @@ -1,20 +1,242 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Copyright (c) 2020 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 
     | 
    
         
            +
             
     | 
| 
       1 
22 
     | 
    
         
             
            require 'glimmer/swt/widget_proxy'
         
     | 
| 
       2 
23 
     | 
    
         
             
            require 'glimmer/swt/table_column_proxy'
         
     | 
| 
      
 24 
     | 
    
         
            +
            require 'glimmer/swt/table_item_proxy'
         
     | 
| 
      
 25 
     | 
    
         
            +
            require 'glimmer/swt/table_editor'
         
     | 
| 
       3 
26 
     | 
    
         | 
| 
       4 
27 
     | 
    
         
             
            module Glimmer
         
     | 
| 
       5 
28 
     | 
    
         
             
              module SWT
         
     | 
| 
       6 
     | 
    
         
            -
                class TableProxy <  
     | 
| 
      
 29 
     | 
    
         
            +
                class TableProxy < CompositeProxy
         
     | 
| 
       7 
30 
     | 
    
         
             
                  attr_reader :columns, :selection,
         
     | 
| 
       8 
     | 
    
         
            -
                              :sort_type, :sort_column, :sort_property, :sort_block, :sort_by_block, :additional_sort_properties
         
     | 
| 
      
 31 
     | 
    
         
            +
                              :sort_type, :sort_column, :sort_property, :sort_block, :sort_by_block, :additional_sort_properties,
         
     | 
| 
      
 32 
     | 
    
         
            +
                              :editor, :table_editor
         
     | 
| 
       9 
33 
     | 
    
         
             
                  attr_accessor :column_properties, :item_count, :data
         
     | 
| 
       10 
34 
     | 
    
         
             
                  alias items children
         
     | 
| 
       11 
35 
     | 
    
         
             
                  alias model_binding data
         
     | 
| 
       12 
36 
     | 
    
         | 
| 
      
 37 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 38 
     | 
    
         
            +
                    include Glimmer
         
     | 
| 
      
 39 
     | 
    
         
            +
                    
         
     | 
| 
      
 40 
     | 
    
         
            +
                    def editors
         
     | 
| 
      
 41 
     | 
    
         
            +
                      @editors ||= {
         
     | 
| 
      
 42 
     | 
    
         
            +
                        # ensure editor can work with string keys not just symbols (leave one string in for testing)
         
     | 
| 
      
 43 
     | 
    
         
            +
                        text: {
         
     | 
| 
      
 44 
     | 
    
         
            +
                          widget_value_property: :text,
         
     | 
| 
      
 45 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 46 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 10
         
     | 
| 
      
 47 
     | 
    
         
            +
                            table_editor_widget_proxy = text(*args) {
         
     | 
| 
      
 48 
     | 
    
         
            +
                              text model.send(property)
         
     | 
| 
      
 49 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 50 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 51 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 52 
     | 
    
         
            +
                              }
         
     | 
| 
      
 53 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 54 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 55 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 56 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 57 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 58 
     | 
    
         
            +
                                end
         
     | 
| 
      
 59 
     | 
    
         
            +
                              }
         
     | 
| 
      
 60 
     | 
    
         
            +
                            }
         
     | 
| 
      
 61 
     | 
    
         
            +
            #                 table_editor_widget_proxy.swt_widget.selectAll # TODO select all
         
     | 
| 
      
 62 
     | 
    
         
            +
                            table_editor_widget_proxy
         
     | 
| 
      
 63 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 64 
     | 
    
         
            +
                        },
         
     | 
| 
      
 65 
     | 
    
         
            +
                        combo: {
         
     | 
| 
      
 66 
     | 
    
         
            +
                          widget_value_property: :text,
         
     | 
| 
      
 67 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 68 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 69 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 18
         
     | 
| 
      
 70 
     | 
    
         
            +
                            table_editor_widget_proxy = combo(*args) {
         
     | 
| 
      
 71 
     | 
    
         
            +
                              items model.send("#{property}_options")
         
     | 
| 
      
 72 
     | 
    
         
            +
                              text model.send(property)
         
     | 
| 
      
 73 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 74 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 75 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 76 
     | 
    
         
            +
                              }
         
     | 
| 
      
 77 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 78 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 79 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 80 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 81 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 82 
     | 
    
         
            +
                                end
         
     | 
| 
      
 83 
     | 
    
         
            +
                              }
         
     | 
| 
      
 84 
     | 
    
         
            +
                              on_widget_selected {
         
     | 
| 
      
 85 
     | 
    
         
            +
                                if !OS.windows? || !first_time || first_time && model.send(property) != table_editor_widget_proxy.text
         
     | 
| 
      
 86 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 87 
     | 
    
         
            +
                                end
         
     | 
| 
      
 88 
     | 
    
         
            +
                              }
         
     | 
| 
      
 89 
     | 
    
         
            +
                            }
         
     | 
| 
      
 90 
     | 
    
         
            +
                            table_editor_widget_proxy
         
     | 
| 
      
 91 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 92 
     | 
    
         
            +
                        },
         
     | 
| 
      
 93 
     | 
    
         
            +
                        checkbox: {
         
     | 
| 
      
 94 
     | 
    
         
            +
                          widget_value_property: :selection,
         
     | 
| 
      
 95 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 96 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 97 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 25
         
     | 
| 
      
 98 
     | 
    
         
            +
                            checkbox(*args) {
         
     | 
| 
      
 99 
     | 
    
         
            +
                              selection model.send(property)
         
     | 
| 
      
 100 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 101 
     | 
    
         
            +
                              on_widget_selected {
         
     | 
| 
      
 102 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 103 
     | 
    
         
            +
                              }
         
     | 
| 
      
 104 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 105 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 106 
     | 
    
         
            +
                              }
         
     | 
| 
      
 107 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 108 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 109 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 110 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 111 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 112 
     | 
    
         
            +
                                end
         
     | 
| 
      
 113 
     | 
    
         
            +
                              }
         
     | 
| 
      
 114 
     | 
    
         
            +
                            }
         
     | 
| 
      
 115 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 116 
     | 
    
         
            +
                        },
         
     | 
| 
      
 117 
     | 
    
         
            +
                        date: {
         
     | 
| 
      
 118 
     | 
    
         
            +
                          widget_value_property: :date_time,
         
     | 
| 
      
 119 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 120 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 121 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 25
         
     | 
| 
      
 122 
     | 
    
         
            +
                            date(*args) {
         
     | 
| 
      
 123 
     | 
    
         
            +
                              date_time model.send(property)
         
     | 
| 
      
 124 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 125 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 126 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 127 
     | 
    
         
            +
                              }
         
     | 
| 
      
 128 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 129 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 130 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 131 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 132 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 133 
     | 
    
         
            +
                                end
         
     | 
| 
      
 134 
     | 
    
         
            +
                              }
         
     | 
| 
      
 135 
     | 
    
         
            +
                            }
         
     | 
| 
      
 136 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 137 
     | 
    
         
            +
                        },
         
     | 
| 
      
 138 
     | 
    
         
            +
                        date_drop_down: {
         
     | 
| 
      
 139 
     | 
    
         
            +
                          widget_value_property: :date_time,
         
     | 
| 
      
 140 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 141 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 142 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 25
         
     | 
| 
      
 143 
     | 
    
         
            +
                            date_drop_down(*args) {
         
     | 
| 
      
 144 
     | 
    
         
            +
                              date_time model.send(property)
         
     | 
| 
      
 145 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 146 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 147 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 148 
     | 
    
         
            +
                              }
         
     | 
| 
      
 149 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 150 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 151 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 152 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 153 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 154 
     | 
    
         
            +
                                end
         
     | 
| 
      
 155 
     | 
    
         
            +
                              }
         
     | 
| 
      
 156 
     | 
    
         
            +
                            }
         
     | 
| 
      
 157 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 158 
     | 
    
         
            +
                        },
         
     | 
| 
      
 159 
     | 
    
         
            +
                        time: {
         
     | 
| 
      
 160 
     | 
    
         
            +
                          widget_value_property: :date_time,
         
     | 
| 
      
 161 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 162 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 163 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 25
         
     | 
| 
      
 164 
     | 
    
         
            +
                            time(*args) {
         
     | 
| 
      
 165 
     | 
    
         
            +
                              date_time model.send(property)
         
     | 
| 
      
 166 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 167 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 168 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 169 
     | 
    
         
            +
                              }
         
     | 
| 
      
 170 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 171 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 172 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 173 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 174 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 175 
     | 
    
         
            +
                                end
         
     | 
| 
      
 176 
     | 
    
         
            +
                              }
         
     | 
| 
      
 177 
     | 
    
         
            +
                            }
         
     | 
| 
      
 178 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 179 
     | 
    
         
            +
                        },
         
     | 
| 
      
 180 
     | 
    
         
            +
                        radio: {
         
     | 
| 
      
 181 
     | 
    
         
            +
                          widget_value_property: :selection,
         
     | 
| 
      
 182 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 183 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 184 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 25
         
     | 
| 
      
 185 
     | 
    
         
            +
                            radio(*args) {
         
     | 
| 
      
 186 
     | 
    
         
            +
                              selection model.send(property)
         
     | 
| 
      
 187 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 188 
     | 
    
         
            +
                              on_widget_selected {
         
     | 
| 
      
 189 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 190 
     | 
    
         
            +
                              }
         
     | 
| 
      
 191 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 192 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 193 
     | 
    
         
            +
                              }
         
     | 
| 
      
 194 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 195 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 196 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 197 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 198 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 199 
     | 
    
         
            +
                                end
         
     | 
| 
      
 200 
     | 
    
         
            +
                              }
         
     | 
| 
      
 201 
     | 
    
         
            +
                            }
         
     | 
| 
      
 202 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 203 
     | 
    
         
            +
                        },
         
     | 
| 
      
 204 
     | 
    
         
            +
                        spinner: {
         
     | 
| 
      
 205 
     | 
    
         
            +
                          widget_value_property: :selection,
         
     | 
| 
      
 206 
     | 
    
         
            +
                          editor_gui: lambda do |args, model, property, table_proxy|
         
     | 
| 
      
 207 
     | 
    
         
            +
                            first_time = true
         
     | 
| 
      
 208 
     | 
    
         
            +
                            table_proxy.table_editor.minimumHeight = 25
         
     | 
| 
      
 209 
     | 
    
         
            +
                            table_editor_widget_proxy = spinner(*args) {
         
     | 
| 
      
 210 
     | 
    
         
            +
                              selection model.send(property)
         
     | 
| 
      
 211 
     | 
    
         
            +
                              focus true
         
     | 
| 
      
 212 
     | 
    
         
            +
                              on_focus_lost {
         
     | 
| 
      
 213 
     | 
    
         
            +
                                table_proxy.finish_edit!
         
     | 
| 
      
 214 
     | 
    
         
            +
                              }
         
     | 
| 
      
 215 
     | 
    
         
            +
                              on_key_pressed { |key_event|
         
     | 
| 
      
 216 
     | 
    
         
            +
                                if key_event.keyCode == swt(:cr)
         
     | 
| 
      
 217 
     | 
    
         
            +
                                  table_proxy.finish_edit!
         
     | 
| 
      
 218 
     | 
    
         
            +
                                elsif key_event.keyCode == swt(:esc)
         
     | 
| 
      
 219 
     | 
    
         
            +
                                  table_proxy.cancel_edit!
         
     | 
| 
      
 220 
     | 
    
         
            +
                                end
         
     | 
| 
      
 221 
     | 
    
         
            +
                              }
         
     | 
| 
      
 222 
     | 
    
         
            +
                            }
         
     | 
| 
      
 223 
     | 
    
         
            +
                            table_editor_widget_proxy
         
     | 
| 
      
 224 
     | 
    
         
            +
                          end,
         
     | 
| 
      
 225 
     | 
    
         
            +
                        },
         
     | 
| 
      
 226 
     | 
    
         
            +
                      }
         
     | 
| 
      
 227 
     | 
    
         
            +
                    end
         
     | 
| 
      
 228 
     | 
    
         
            +
                  end
         
     | 
| 
      
 229 
     | 
    
         
            +
                  
         
     | 
| 
       13 
230 
     | 
    
         
             
                  def initialize(parent, args, block)
         
     | 
| 
       14 
231 
     | 
    
         
             
                    super(parent, args, block)
         
     | 
| 
       15 
232 
     | 
    
         
             
                    @columns = []
         
     | 
| 
       16 
233 
     | 
    
         
             
                    @children = []
         
     | 
| 
      
 234 
     | 
    
         
            +
                    @editors = []
         
     | 
| 
       17 
235 
     | 
    
         
             
                    @selection = []
         
     | 
| 
      
 236 
     | 
    
         
            +
                    @table_editor = TableEditor.new(self)
         
     | 
| 
      
 237 
     | 
    
         
            +
                    @table_editor.horizontalAlignment = SWTProxy[:left]
         
     | 
| 
      
 238 
     | 
    
         
            +
                    @table_editor.grabHorizontal = true
         
     | 
| 
      
 239 
     | 
    
         
            +
                    @table_editor.minimumHeight = 20
         
     | 
| 
       18 
240 
     | 
    
         
             
                    if editable?
         
     | 
| 
       19 
241 
     | 
    
         
             
                      on_mouse_up { |event|
         
     | 
| 
       20 
242 
     | 
    
         
             
                        edit_table_item(event.table_item, event.column_index)
         
     | 
| 
         @@ -26,10 +248,24 @@ module Glimmer 
     | 
|
| 
       26 
248 
     | 
    
         
             
                  def post_initialize_child(child)
         
     | 
| 
       27 
249 
     | 
    
         
             
                    if child.is_a?(TableColumnProxy)
         
     | 
| 
       28 
250 
     | 
    
         
             
                      @columns << child
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 251 
     | 
    
         
            +
                      child.render
         
     | 
| 
      
 252 
     | 
    
         
            +
                    elsif child.is_a?(TableItemProxy)
         
     | 
| 
       30 
253 
     | 
    
         
             
                      @children << child
         
     | 
| 
      
 254 
     | 
    
         
            +
                      child.render
         
     | 
| 
      
 255 
     | 
    
         
            +
                    else
         
     | 
| 
      
 256 
     | 
    
         
            +
                      @editors << child
         
     | 
| 
      
 257 
     | 
    
         
            +
                    end
         
     | 
| 
      
 258 
     | 
    
         
            +
                  end
         
     | 
| 
      
 259 
     | 
    
         
            +
                  
         
     | 
| 
      
 260 
     | 
    
         
            +
                  # Executes for the parent of a child that just got disposed
         
     | 
| 
      
 261 
     | 
    
         
            +
                  def post_dispose_child(child)
         
     | 
| 
      
 262 
     | 
    
         
            +
                    if child.is_a?(TableColumnProxy)
         
     | 
| 
      
 263 
     | 
    
         
            +
                      @columns&.delete(child)
         
     | 
| 
      
 264 
     | 
    
         
            +
                    elsif child.is_a?(TableItemProxy)
         
     | 
| 
      
 265 
     | 
    
         
            +
                      @children&.delete(child)
         
     | 
| 
      
 266 
     | 
    
         
            +
                    else
         
     | 
| 
      
 267 
     | 
    
         
            +
                      @editors&.delete(child)
         
     | 
| 
       31 
268 
     | 
    
         
             
                    end
         
     | 
| 
       32 
     | 
    
         
            -
                    child.redraw
         
     | 
| 
       33 
269 
     | 
    
         
             
                  end
         
     | 
| 
       34 
270 
     | 
    
         | 
| 
       35 
271 
     | 
    
         
             
                  def post_add_content
         
     | 
| 
         @@ -38,6 +274,10 @@ module Glimmer 
     | 
|
| 
       38 
274 
     | 
    
         
             
                    @initially_sorted = true
         
     | 
| 
       39 
275 
     | 
    
         
             
                  end
         
     | 
| 
       40 
276 
     | 
    
         | 
| 
      
 277 
     | 
    
         
            +
                  def default_layout
         
     | 
| 
      
 278 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 279 
     | 
    
         
            +
                  end
         
     | 
| 
      
 280 
     | 
    
         
            +
                  
         
     | 
| 
       41 
281 
     | 
    
         
             
                  def get_data(key=nil)
         
     | 
| 
       42 
282 
     | 
    
         
             
                    data
         
     | 
| 
       43 
283 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -97,10 +337,6 @@ module Glimmer 
     | 
|
| 
       97 
337 
     | 
    
         
             
                    self.selection = new_selection
         
     | 
| 
       98 
338 
     | 
    
         
             
                  end
         
     | 
| 
       99 
339 
     | 
    
         | 
| 
       100 
     | 
    
         
            -
                  def search(&condition)
         
     | 
| 
       101 
     | 
    
         
            -
                    items.select {|item| condition.nil? || condition.call(item)}
         
     | 
| 
       102 
     | 
    
         
            -
                  end
         
     | 
| 
       103 
     | 
    
         
            -
                  
         
     | 
| 
       104 
340 
     | 
    
         
             
                  def sort_block=(comparator)
         
     | 
| 
       105 
341 
     | 
    
         
             
                    @sort_block = comparator
         
     | 
| 
       106 
342 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -223,9 +459,118 @@ module Glimmer 
     | 
|
| 
       223 
459 
     | 
    
         
             
                    @additional_sort_properties = args unless args.empty?
         
     | 
| 
       224 
460 
     | 
    
         
             
                  end
         
     | 
| 
       225 
461 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
                  def  
     | 
| 
       227 
     | 
    
         
            -
                     
     | 
| 
      
 462 
     | 
    
         
            +
                  def editor=(args)
         
     | 
| 
      
 463 
     | 
    
         
            +
                    @editor = args
         
     | 
| 
      
 464 
     | 
    
         
            +
                  end
         
     | 
| 
      
 465 
     | 
    
         
            +
                  
         
     | 
| 
      
 466 
     | 
    
         
            +
                  # Indicates if table is in edit mode, thus displaying a text widget for a table item cell
         
     | 
| 
      
 467 
     | 
    
         
            +
                  def edit_mode?
         
     | 
| 
      
 468 
     | 
    
         
            +
                    !!@edit_mode
         
     | 
| 
      
 469 
     | 
    
         
            +
                  end
         
     | 
| 
      
 470 
     | 
    
         
            +
                  
         
     | 
| 
      
 471 
     | 
    
         
            +
                  def cancel_edit!
         
     | 
| 
      
 472 
     | 
    
         
            +
                    @cancel_edit&.call if @edit_mode
         
     | 
| 
      
 473 
     | 
    
         
            +
                  end
         
     | 
| 
      
 474 
     | 
    
         
            +
             
     | 
| 
      
 475 
     | 
    
         
            +
                  def finish_edit!
         
     | 
| 
      
 476 
     | 
    
         
            +
                    @finish_edit&.call if @edit_mode
         
     | 
| 
      
 477 
     | 
    
         
            +
                  end
         
     | 
| 
      
 478 
     | 
    
         
            +
             
     | 
| 
      
 479 
     | 
    
         
            +
                  # Indicates if table is editing a table item because the user hit ENTER or focused out after making a change in edit mode to a table item cell.
         
     | 
| 
      
 480 
     | 
    
         
            +
                  # It is set to false once change is saved to model
         
     | 
| 
      
 481 
     | 
    
         
            +
                  def edit_in_progress?
         
     | 
| 
      
 482 
     | 
    
         
            +
                    !!@edit_in_progress
         
     | 
| 
      
 483 
     | 
    
         
            +
                  end
         
     | 
| 
      
 484 
     | 
    
         
            +
                  
         
     | 
| 
      
 485 
     | 
    
         
            +
                  def edit_selected_table_item(column_index, before_write: nil, after_write: nil, after_cancel: nil)
         
     | 
| 
      
 486 
     | 
    
         
            +
                    edit_table_item(selection.first, column_index, before_write: before_write, after_write: after_write, after_cancel: after_cancel)
         
     | 
| 
      
 487 
     | 
    
         
            +
                  end
         
     | 
| 
      
 488 
     | 
    
         
            +
             
     | 
| 
      
 489 
     | 
    
         
            +
                    # TODO migrate the following to the next method
         
     | 
| 
      
 490 
     | 
    
         
            +
            #       def edit_table_item(table_item, column_index)
         
     | 
| 
      
 491 
     | 
    
         
            +
            #         table_item&.edit(column_index) unless column_index.nil?
         
     | 
| 
      
 492 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 493 
     | 
    
         
            +
                  
         
     | 
| 
      
 494 
     | 
    
         
            +
                  def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)
         
     | 
| 
      
 495 
     | 
    
         
            +
                    return if table_item.nil? || (@edit_mode && @edit_table_item == table_item && @edit_column_index == column_index)
         
     | 
| 
      
 496 
     | 
    
         
            +
                    @edit_column_index = column_index
         
     | 
| 
      
 497 
     | 
    
         
            +
                    @edit_table_item = table_item
         
     | 
| 
      
 498 
     | 
    
         
            +
                    column_index = column_index.to_i
         
     | 
| 
      
 499 
     | 
    
         
            +
                    model = table_item.data
         
     | 
| 
      
 500 
     | 
    
         
            +
                    property = column_properties[column_index]
         
     | 
| 
      
 501 
     | 
    
         
            +
                    cancel_edit!
         
     | 
| 
      
 502 
     | 
    
         
            +
                    return unless columns[column_index].editable?
         
     | 
| 
      
 503 
     | 
    
         
            +
                    action_taken = false
         
     | 
| 
      
 504 
     | 
    
         
            +
                    @edit_mode = true
         
     | 
| 
      
 505 
     | 
    
         
            +
                    
         
     | 
| 
      
 506 
     | 
    
         
            +
                    editor_config = columns[column_index].editor || editor
         
     | 
| 
      
 507 
     | 
    
         
            +
                    editor_config = [editor_config].flatten.compact
         
     | 
| 
      
 508 
     | 
    
         
            +
                    editor_widget_options = editor_config.last.is_a?(Hash) ? editor_config.last : {}
         
     | 
| 
      
 509 
     | 
    
         
            +
                    editor_widget_arg_last_index = editor_config.last.is_a?(Hash) ? -2 : -1
         
     | 
| 
      
 510 
     | 
    
         
            +
                    editor_widget = (editor_config[0] || :text).to_sym
         
     | 
| 
      
 511 
     | 
    
         
            +
                    editor_widget_args = editor_config[1..editor_widget_arg_last_index]
         
     | 
| 
      
 512 
     | 
    
         
            +
                    model_editing_property = editor_widget_options[:property] || property
         
     | 
| 
      
 513 
     | 
    
         
            +
                    widget_value_property = TableProxy::editors.symbolize_keys[editor_widget][:widget_value_property]
         
     | 
| 
      
 514 
     | 
    
         
            +
                    
         
     | 
| 
      
 515 
     | 
    
         
            +
                    @cancel_edit = lambda do |event=nil|
         
     | 
| 
      
 516 
     | 
    
         
            +
                      @cancel_in_progress = true
         
     | 
| 
      
 517 
     | 
    
         
            +
                      @table_editor.cancel!
         
     | 
| 
      
 518 
     | 
    
         
            +
                      @table_editor_widget_proxy&.dispose
         
     | 
| 
      
 519 
     | 
    
         
            +
                      @table_editor_widget_proxy = nil
         
     | 
| 
      
 520 
     | 
    
         
            +
                      after_cancel&.call
         
     | 
| 
      
 521 
     | 
    
         
            +
                      @edit_in_progress = false
         
     | 
| 
      
 522 
     | 
    
         
            +
                      @cancel_in_progress = false
         
     | 
| 
      
 523 
     | 
    
         
            +
                      @cancel_edit = nil
         
     | 
| 
      
 524 
     | 
    
         
            +
                      @edit_table_item = @edit_column_index = nil if (@edit_mode && @edit_table_item == table_item && @edit_column_index == column_index)
         
     | 
| 
      
 525 
     | 
    
         
            +
                      @edit_mode = false
         
     | 
| 
      
 526 
     | 
    
         
            +
                    end
         
     | 
| 
      
 527 
     | 
    
         
            +
                    
         
     | 
| 
      
 528 
     | 
    
         
            +
                    @finish_edit = lambda do |event=nil|
         
     | 
| 
      
 529 
     | 
    
         
            +
                      new_value = @table_editor_widget_proxy&.send(widget_value_property)
         
     | 
| 
      
 530 
     | 
    
         
            +
                      if table_item.disposed?
         
     | 
| 
      
 531 
     | 
    
         
            +
                        @cancel_edit.call
         
     | 
| 
      
 532 
     | 
    
         
            +
                      elsif !new_value.nil? && !action_taken && !@edit_in_progress && !@cancel_in_progress
         
     | 
| 
      
 533 
     | 
    
         
            +
                        action_taken = true
         
     | 
| 
      
 534 
     | 
    
         
            +
                        @edit_in_progress = true
         
     | 
| 
      
 535 
     | 
    
         
            +
                        if new_value == model.send(model_editing_property)
         
     | 
| 
      
 536 
     | 
    
         
            +
                          @cancel_edit.call
         
     | 
| 
      
 537 
     | 
    
         
            +
                        else
         
     | 
| 
      
 538 
     | 
    
         
            +
                          before_write&.call
         
     | 
| 
      
 539 
     | 
    
         
            +
                          @table_editor.save!(widget_value_property: widget_value_property)
         
     | 
| 
      
 540 
     | 
    
         
            +
                          model.send("#{model_editing_property}=", new_value) # makes table update itself, so must search for selected table item again
         
     | 
| 
      
 541 
     | 
    
         
            +
                          # Table refresh happens here because of model update triggering observers, so must retrieve table item again
         
     | 
| 
      
 542 
     | 
    
         
            +
                          edited_table_item = search { |ti| ti.data == model }.first
         
     | 
| 
      
 543 
     | 
    
         
            +
                          show_item(edited_table_item)
         
     | 
| 
      
 544 
     | 
    
         
            +
                          @table_editor_widget_proxy&.dispose
         
     | 
| 
      
 545 
     | 
    
         
            +
                          @table_editor_widget_proxy = nil
         
     | 
| 
      
 546 
     | 
    
         
            +
                          after_write&.call(edited_table_item)
         
     | 
| 
      
 547 
     | 
    
         
            +
                          @edit_in_progress = false
         
     | 
| 
      
 548 
     | 
    
         
            +
                          @edit_table_item = @edit_column_index = nil
         
     | 
| 
      
 549 
     | 
    
         
            +
                        end
         
     | 
| 
      
 550 
     | 
    
         
            +
                      end
         
     | 
| 
      
 551 
     | 
    
         
            +
                    end
         
     | 
| 
      
 552 
     | 
    
         
            +
             
     | 
| 
      
 553 
     | 
    
         
            +
                    content {
         
     | 
| 
      
 554 
     | 
    
         
            +
                      @table_editor_widget_proxy = TableProxy::editors.symbolize_keys[editor_widget][:editor_gui].call(editor_widget_args, model, model_editing_property, self)
         
     | 
| 
      
 555 
     | 
    
         
            +
                    }
         
     | 
| 
      
 556 
     | 
    
         
            +
                    @table_editor.set_editor(@table_editor_widget_proxy, table_item, column_index)
         
     | 
| 
      
 557 
     | 
    
         
            +
                  rescue => e
         
     | 
| 
      
 558 
     | 
    
         
            +
                    Glimmer::Config.logger.error {e.full_message}
         
     | 
| 
      
 559 
     | 
    
         
            +
                    raise e
         
     | 
| 
      
 560 
     | 
    
         
            +
                  end
         
     | 
| 
      
 561 
     | 
    
         
            +
                  
         
     | 
| 
      
 562 
     | 
    
         
            +
                  def show_item(table_item)
         
     | 
| 
      
 563 
     | 
    
         
            +
                    table_item.dom_element.focus
         
     | 
| 
      
 564 
     | 
    
         
            +
                  end
         
     | 
| 
      
 565 
     | 
    
         
            +
                  
         
     | 
| 
      
 566 
     | 
    
         
            +
                  def add_listener(underscored_listener_name, &block)
         
     | 
| 
      
 567 
     | 
    
         
            +
                    enhanced_block = lambda do |event|
         
     | 
| 
      
 568 
     | 
    
         
            +
                      event.extend(TableListenerEvent)
         
     | 
| 
      
 569 
     | 
    
         
            +
                      block.call(event)
         
     | 
| 
      
 570 
     | 
    
         
            +
                    end
         
     | 
| 
      
 571 
     | 
    
         
            +
                    super(underscored_listener_name, &enhanced_block)
         
     | 
| 
       228 
572 
     | 
    
         
             
                  end
         
     | 
| 
      
 573 
     | 
    
         
            +
                          
         
     | 
| 
       229 
574 
     | 
    
         | 
| 
       230 
575 
     | 
    
         
             
                  def header_visible=(value)
         
     | 
| 
       231 
576 
     | 
    
         
             
                    @header_visible = value
         
     | 
| 
         @@ -337,7 +682,8 @@ module Glimmer 
     | 
|
| 
       337 
682 
     | 
    
         
             
                    table_id = id
         
     | 
| 
       338 
683 
     | 
    
         
             
                    table_id_style = css
         
     | 
| 
       339 
684 
     | 
    
         
             
                    table_id_css_classes = css_classes
         
     | 
| 
       340 
     | 
    
         
            -
                    table_id_css_classes << 'table'
         
     | 
| 
      
 685 
     | 
    
         
            +
                    table_id_css_classes << 'table' unless table_id_css_classes.include?('table')
         
     | 
| 
      
 686 
     | 
    
         
            +
                    table_id_css_classes << 'editable' if editable? && !table_id_css_classes.include?('editable')
         
     | 
| 
       341 
687 
     | 
    
         
             
                    table_id_css_classes_string = table_id_css_classes.to_a.join(' ')
         
     | 
| 
       342 
688 
     | 
    
         
             
                    @dom ||= html {
         
     | 
| 
       343 
689 
     | 
    
         
             
                      table(id: table_id, style: table_id_style, class: table_id_css_classes_string) {
         
     | 
| 
         @@ -29,7 +29,10 @@ module Glimmer 
     | 
|
| 
       29 
29 
     | 
    
         
             
                  include Glimmer
         
     | 
| 
       30 
30 
     | 
    
         
             
                  include PropertyOwner
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
                  attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus
         
     | 
| 
      
 32 
     | 
    
         
            +
                  attr_reader :parent, :args, :path, :children, :enabled, :foreground, :background, :font, :focus, :disposed?, :rendered
         
     | 
| 
      
 33 
     | 
    
         
            +
                  alias isDisposed disposed?
         
     | 
| 
      
 34 
     | 
    
         
            +
                  alias is_disposed disposed?
         
     | 
| 
      
 35 
     | 
    
         
            +
                  alias rendered? rendered
         
     | 
| 
       33 
36 
     | 
    
         | 
| 
       34 
37 
     | 
    
         
             
                  class << self
         
     | 
| 
       35 
38 
     | 
    
         
             
                    # Factory Method that translates a Glimmer DSL keyword into a WidgetProxy object
         
     | 
| 
         @@ -103,6 +106,7 @@ module Glimmer 
     | 
|
| 
       103 
106 
     | 
    
         
             
                    @block = block
         
     | 
| 
       104 
107 
     | 
    
         
             
                    @children = Set.new # TODO consider moving to composite
         
     | 
| 
       105 
108 
     | 
    
         
             
                    @enabled = true
         
     | 
| 
      
 109 
     | 
    
         
            +
                    @data = {}
         
     | 
| 
       106 
110 
     | 
    
         
             
                    DEFAULT_INITIALIZERS[self.class.underscored_widget_name(self)]&.call(self)
         
     | 
| 
       107 
111 
     | 
    
         
             
                    @parent.post_initialize_child(self) # TODO rename to post_initialize_child to be closer to glimmer-dsl-swt terminology
         
     | 
| 
       108 
112 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -113,17 +117,52 @@ module Glimmer 
     | 
|
| 
       113 
117 
     | 
    
         
             
                    child.render
         
     | 
| 
       114 
118 
     | 
    
         
             
                  end
         
     | 
| 
       115 
119 
     | 
    
         | 
| 
      
 120 
     | 
    
         
            +
                  # Executes for the parent of a child that just got disposed
         
     | 
| 
      
 121 
     | 
    
         
            +
                  def post_dispose_child(child)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    @children&.delete(child)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  
         
     | 
| 
       116 
125 
     | 
    
         
             
                  # Executes at the closing of a parent widget curly braces after all children/properties have been added/set
         
     | 
| 
       117 
126 
     | 
    
         
             
                  def post_add_content
         
     | 
| 
       118 
127 
     | 
    
         
             
                    # No Op by default
         
     | 
| 
       119 
128 
     | 
    
         
             
                  end
         
     | 
| 
       120 
129 
     | 
    
         | 
| 
      
 130 
     | 
    
         
            +
                  def set_data(key=nil, value)
         
     | 
| 
      
 131 
     | 
    
         
            +
                    @data[key] = value
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
                  alias setData set_data
         
     | 
| 
      
 134 
     | 
    
         
            +
                  alias data= set_data
         
     | 
| 
      
 135 
     | 
    
         
            +
                  
         
     | 
| 
      
 136 
     | 
    
         
            +
                  def get_data(key=nil)
         
     | 
| 
      
 137 
     | 
    
         
            +
                    @data[key]
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
      
 139 
     | 
    
         
            +
                  alias getData get_data
         
     | 
| 
      
 140 
     | 
    
         
            +
                  alias data get_data
         
     | 
| 
      
 141 
     | 
    
         
            +
                  
         
     | 
| 
       121 
142 
     | 
    
         
             
                  def css_classes
         
     | 
| 
       122 
143 
     | 
    
         
             
                    dom_element.attr('class').to_s.split
         
     | 
| 
       123 
144 
     | 
    
         
             
                  end
         
     | 
| 
       124 
145 
     | 
    
         | 
| 
       125 
146 
     | 
    
         
             
                  def dispose
         
     | 
| 
      
 147 
     | 
    
         
            +
                    remove_all_listeners
         
     | 
| 
       126 
148 
     | 
    
         
             
                    Document.find(path).remove
         
     | 
| 
      
 149 
     | 
    
         
            +
                    parent&.post_dispose_child(self)
         
     | 
| 
      
 150 
     | 
    
         
            +
                    # TODO fire on_widget_disposed listener
         
     | 
| 
      
 151 
     | 
    
         
            +
                    @disposed = true
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
                  
         
     | 
| 
      
 154 
     | 
    
         
            +
                  def remove_all_listeners
         
     | 
| 
      
 155 
     | 
    
         
            +
                    observation_request_to_event_mapping.keys.each do |keyword|
         
     | 
| 
      
 156 
     | 
    
         
            +
                      [observation_request_to_event_mapping[keyword]].flatten.each do |mapping|
         
     | 
| 
      
 157 
     | 
    
         
            +
                        @observation_requests[keyword].to_a.each do |event_listener|
         
     | 
| 
      
 158 
     | 
    
         
            +
                          event = mapping[:event]
         
     | 
| 
      
 159 
     | 
    
         
            +
                          event_handler = mapping[:event_handler]
         
     | 
| 
      
 160 
     | 
    
         
            +
                          event_element_css_selector = mapping[:event_element_css_selector]
         
     | 
| 
      
 161 
     | 
    
         
            +
                          the_listener_dom_element = event_element_css_selector ? Element[event_element_css_selector] : listener_dom_element
         
     | 
| 
      
 162 
     | 
    
         
            +
                          the_listener_dom_element.off(event)
         
     | 
| 
      
 163 
     | 
    
         
            +
                        end
         
     | 
| 
      
 164 
     | 
    
         
            +
                      end
         
     | 
| 
      
 165 
     | 
    
         
            +
                    end
         
     | 
| 
       127 
166 
     | 
    
         
             
                  end
         
     | 
| 
       128 
167 
     | 
    
         | 
| 
       129 
168 
     | 
    
         
             
                  def path
         
     | 
| 
         @@ -172,12 +211,17 @@ module Glimmer 
     | 
|
| 
       172 
211 
     | 
    
         
             
                    @parent.path
         
     | 
| 
       173 
212 
     | 
    
         
             
                  end
         
     | 
| 
       174 
213 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
                  def  
     | 
| 
      
 214 
     | 
    
         
            +
                  def parent_dom_element
         
     | 
| 
      
 215 
     | 
    
         
            +
                    Document.find(parent_path)
         
     | 
| 
      
 216 
     | 
    
         
            +
                  end
         
     | 
| 
      
 217 
     | 
    
         
            +
                  
         
     | 
| 
      
 218 
     | 
    
         
            +
                  def render(custom_parent_dom_element = nil)
         
     | 
| 
      
 219 
     | 
    
         
            +
                    the_parent_dom_element = custom_parent_dom_element || parent_dom_element
         
     | 
| 
       176 
220 
     | 
    
         
             
                    old_element = dom_element
         
     | 
| 
       177 
221 
     | 
    
         
             
                    brand_new = @dom.nil? || old_element.empty?
         
     | 
| 
       178 
     | 
    
         
            -
                    build_dom
         
     | 
| 
      
 222 
     | 
    
         
            +
                    build_dom(!custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
         
     | 
| 
       179 
223 
     | 
    
         
             
                    if brand_new
         
     | 
| 
       180 
     | 
    
         
            -
                       
     | 
| 
      
 224 
     | 
    
         
            +
                      the_parent_dom_element.append(@dom)
         
     | 
| 
       181 
225 
     | 
    
         
             
                    else
         
     | 
| 
       182 
226 
     | 
    
         
             
                      old_element.replace_with(@dom)
         
     | 
| 
       183 
227 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -190,13 +234,29 @@ module Glimmer 
     | 
|
| 
       190 
234 
     | 
    
         
             
                    children.each do |child|
         
     | 
| 
       191 
235 
     | 
    
         
             
                      child.render
         
     | 
| 
       192 
236 
     | 
    
         
             
                    end
         
     | 
| 
      
 237 
     | 
    
         
            +
                    @rendered = true
         
     | 
| 
      
 238 
     | 
    
         
            +
                    content_on_render_blocks.each { |content_block| content(&content_block) }
         
     | 
| 
       193 
239 
     | 
    
         
             
                  end
         
     | 
| 
       194 
240 
     | 
    
         
             
                  alias redraw render
         
     | 
| 
       195 
241 
     | 
    
         | 
| 
       196 
     | 
    
         
            -
                  def  
     | 
| 
      
 242 
     | 
    
         
            +
                  def content_on_render_blocks
         
     | 
| 
      
 243 
     | 
    
         
            +
                    @content_on_render_blocks ||= []
         
     | 
| 
      
 244 
     | 
    
         
            +
                  end
         
     | 
| 
      
 245 
     | 
    
         
            +
                  
         
     | 
| 
      
 246 
     | 
    
         
            +
                  def add_content_on_render(&content_block)
         
     | 
| 
      
 247 
     | 
    
         
            +
                    if rendered?
         
     | 
| 
      
 248 
     | 
    
         
            +
                      content_block.call
         
     | 
| 
      
 249 
     | 
    
         
            +
                    else
         
     | 
| 
      
 250 
     | 
    
         
            +
                      content_on_render_blocks << content_block
         
     | 
| 
      
 251 
     | 
    
         
            +
                    end
         
     | 
| 
      
 252 
     | 
    
         
            +
                  end
         
     | 
| 
      
 253 
     | 
    
         
            +
                  
         
     | 
| 
      
 254 
     | 
    
         
            +
                  def build_dom(layout=true)
         
     | 
| 
      
 255 
     | 
    
         
            +
                    # TODO consider passing parent element instead and having table item include a table cell widget only for opal
         
     | 
| 
       197 
256 
     | 
    
         
             
                    @dom = nil
         
     | 
| 
       198 
257 
     | 
    
         
             
                    @dom = dom
         
     | 
| 
       199 
258 
     | 
    
         
             
                    @dom = @parent.layout.dom(@dom) if @parent.respond_to?(:layout) && @parent.layout
         
     | 
| 
      
 259 
     | 
    
         
            +
                    @dom
         
     | 
| 
       200 
260 
     | 
    
         
             
                  end
         
     | 
| 
       201 
261 
     | 
    
         | 
| 
       202 
262 
     | 
    
         
             
                  def content(&block)
         
     | 
| 
         @@ -271,10 +331,6 @@ module Glimmer 
     | 
|
| 
       271 
331 
     | 
    
         
             
                    element
         
     | 
| 
       272 
332 
     | 
    
         
             
                  end
         
     | 
| 
       273 
333 
     | 
    
         | 
| 
       274 
     | 
    
         
            -
                  def parent_dom_element
         
     | 
| 
       275 
     | 
    
         
            -
                    Document.find(parent_path)
         
     | 
| 
       276 
     | 
    
         
            -
                  end
         
     | 
| 
       277 
     | 
    
         
            -
                  
         
     | 
| 
       278 
334 
     | 
    
         
             
                  def listener_path
         
     | 
| 
       279 
335 
     | 
    
         
             
                    path
         
     | 
| 
       280 
336 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -334,6 +390,14 @@ module Glimmer 
     | 
|
| 
       334 
390 
     | 
    
         
             
                    super(attribute_name, *args) # PropertyOwner
         
     | 
| 
       335 
391 
     | 
    
         
             
                  end
         
     | 
| 
       336 
392 
     | 
    
         | 
| 
      
 393 
     | 
    
         
            +
                  def method_missing(method, *args, &block)
         
     | 
| 
      
 394 
     | 
    
         
            +
                    if method.to_s.start_with?('on_')
         
     | 
| 
      
 395 
     | 
    
         
            +
                      handle_observation_request(method, &block)
         
     | 
| 
      
 396 
     | 
    
         
            +
                    else
         
     | 
| 
      
 397 
     | 
    
         
            +
                      super(method, *args, &block)
         
     | 
| 
      
 398 
     | 
    
         
            +
                    end
         
     | 
| 
      
 399 
     | 
    
         
            +
                  end
         
     | 
| 
      
 400 
     | 
    
         
            +
                  
         
     | 
| 
       337 
401 
     | 
    
         
             
                  def apply_property_type_converters(attribute_name, args)
         
     | 
| 
       338 
402 
     | 
    
         
             
                    if args.count == 1
         
     | 
| 
       339 
403 
     | 
    
         
             
                      value = args.first
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: glimmer-dsl-opal
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.7. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.7.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - AndyMaleh
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2020-12- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-12-06 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: glimmer
         
     | 
| 
         @@ -311,6 +311,7 @@ files: 
     | 
|
| 
       311 
311 
     | 
    
         
             
            - lib/glimmer/swt/color_proxy.rb
         
     | 
| 
       312 
312 
     | 
    
         
             
            - lib/glimmer/swt/combo_proxy.rb
         
     | 
| 
       313 
313 
     | 
    
         
             
            - lib/glimmer/swt/composite_proxy.rb
         
     | 
| 
      
 314 
     | 
    
         
            +
            - lib/glimmer/swt/control_editor.rb
         
     | 
| 
       314 
315 
     | 
    
         
             
            - lib/glimmer/swt/custom/checkbox_group.rb
         
     | 
| 
       315 
316 
     | 
    
         
             
            - lib/glimmer/swt/custom/radio_group.rb
         
     | 
| 
       316 
317 
     | 
    
         
             
            - lib/glimmer/swt/date_time_proxy.rb
         
     | 
| 
         @@ -338,6 +339,7 @@ files: 
     | 
|
| 
       338 
339 
     | 
    
         
             
            - lib/glimmer/swt/tab_folder_proxy.rb
         
     | 
| 
       339 
340 
     | 
    
         
             
            - lib/glimmer/swt/tab_item_proxy.rb
         
     | 
| 
       340 
341 
     | 
    
         
             
            - lib/glimmer/swt/table_column_proxy.rb
         
     | 
| 
      
 342 
     | 
    
         
            +
            - lib/glimmer/swt/table_editor.rb
         
     | 
| 
       341 
343 
     | 
    
         
             
            - lib/glimmer/swt/table_item_proxy.rb
         
     | 
| 
       342 
344 
     | 
    
         
             
            - lib/glimmer/swt/table_proxy.rb
         
     | 
| 
       343 
345 
     | 
    
         
             
            - lib/glimmer/swt/text_proxy.rb
         
     |