glimmer-dsl-tk 0.0.3 → 0.0.7
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 +30 -0
- data/LICENSE.txt +1 -1
- data/README.md +282 -28
- data/VERSION +1 -1
- data/bin/girb +30 -0
- data/bin/girb_runner.rb +26 -0
- data/lib/glimmer-dsl-tk.rb +4 -4
- data/lib/glimmer/data_binding/tk/list_selection_binding.rb +75 -0
- data/lib/glimmer/data_binding/tk/widget_binding.rb +22 -1
- data/lib/glimmer/dsl/tk/attribute_expression.rb +4 -4
- data/lib/glimmer/dsl/tk/bind_expression.rb +21 -0
- data/lib/glimmer/dsl/tk/block_attribute_expression.rb +4 -4
- data/lib/glimmer/dsl/tk/data_binding_expression.rb +24 -2
- data/lib/glimmer/dsl/tk/dsl.rb +5 -4
- data/lib/glimmer/dsl/tk/list_selection_data_binding_expression.rb +60 -0
- data/lib/glimmer/dsl/tk/root_expression.rb +4 -4
- data/lib/glimmer/dsl/tk/widget_expression.rb +7 -4
- data/lib/glimmer/tk/button_proxy.rb +5 -5
- data/lib/glimmer/tk/entry_proxy.rb +38 -0
- data/lib/glimmer/tk/frame_proxy.rb +5 -5
- data/lib/glimmer/tk/label_proxy.rb +40 -0
- data/lib/glimmer/tk/list_proxy.rb +60 -0
- data/lib/glimmer/tk/notebook_proxy.rb +5 -5
- data/lib/glimmer/tk/root_proxy.rb +4 -4
- data/lib/glimmer/tk/widget_proxy.rb +118 -56
- data/samples/hello/hello_combo.rb +26 -5
- data/samples/hello/hello_computed.rb +96 -0
- data/samples/hello/hello_computed/contact.rb +21 -0
- data/samples/hello/hello_list_multi_selection.rb +69 -0
- data/samples/hello/hello_list_single_selection.rb +60 -0
- data/samples/hello/hello_tab.rb +22 -1
- data/samples/hello/hello_world.rb +4 -4
- metadata +18 -6
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            # Copyright (c) 2020 Andy Maleh
         | 
| 2 | 
            -
            # | 
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 3 | 
             
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            # a copy of this software and associated documentation files (the
         | 
| 5 5 | 
             
            # "Software"), to deal in the Software without restriction, including
         | 
| @@ -7,10 +7,10 @@ | |
| 7 7 | 
             
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 8 | 
             
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 9 | 
             
            # the following conditions:
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # The above copyright notice and this permission notice shall be
         | 
| 12 12 | 
             
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            -
            # | 
| 13 | 
            +
            #
         | 
| 14 14 | 
             
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 15 | 
             
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 16 | 
             
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| @@ -22,7 +22,7 @@ | |
| 22 22 | 
             
            require 'glimmer/tk/widget_proxy'
         | 
| 23 23 |  | 
| 24 24 | 
             
            module Glimmer
         | 
| 25 | 
            -
              module Tk | 
| 25 | 
            +
              module Tk
         | 
| 26 26 | 
             
                # Proxy for Tk::Tile::Button
         | 
| 27 27 | 
             
                #
         | 
| 28 28 | 
             
                # Follows the Proxy Design Pattern
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            # a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            # "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            # the following conditions:
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            require 'glimmer/tk/widget_proxy'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            module Glimmer
         | 
| 25 | 
            +
              module Tk
         | 
| 26 | 
            +
                # Proxy for Tk::Tile::TEntry
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                # Follows the Proxy Design Pattern
         | 
| 29 | 
            +
                class EntryProxy < WidgetProxy
         | 
| 30 | 
            +
                  def validatecommand_block=(proc)
         | 
| 31 | 
            +
                    tk.validatecommand(proc)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                  def invalidcommand_block=(proc)
         | 
| 34 | 
            +
                    tk.invalidcommand(proc)
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            # Copyright (c) 2020 Andy Maleh
         | 
| 2 | 
            -
            # | 
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 3 | 
             
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            # a copy of this software and associated documentation files (the
         | 
| 5 5 | 
             
            # "Software"), to deal in the Software without restriction, including
         | 
| @@ -7,10 +7,10 @@ | |
| 7 7 | 
             
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 8 | 
             
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 9 | 
             
            # the following conditions:
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # The above copyright notice and this permission notice shall be
         | 
| 12 12 | 
             
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            -
            # | 
| 13 | 
            +
            #
         | 
| 14 14 | 
             
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 15 | 
             
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 16 | 
             
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| @@ -22,7 +22,7 @@ | |
| 22 22 | 
             
            require 'glimmer/tk/widget_proxy'
         | 
| 23 23 |  | 
| 24 24 | 
             
            module Glimmer
         | 
| 25 | 
            -
              module Tk | 
| 25 | 
            +
              module Tk
         | 
| 26 26 | 
             
                # Proxy for Tk::Tile::Frame
         | 
| 27 27 | 
             
                #
         | 
| 28 28 | 
             
                # Follows the Proxy Design Pattern
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            # a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            # "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            # the following conditions:
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            require 'glimmer/tk/widget_proxy'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            module Glimmer
         | 
| 25 | 
            +
              module Tk
         | 
| 26 | 
            +
                # Proxy for Tk::Tile::TLabel
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                # Follows the Proxy Design Pattern
         | 
| 29 | 
            +
                class LabelProxy < WidgetProxy
         | 
| 30 | 
            +
                  # TODO specify attribute setters
         | 
| 31 | 
            +
            #       def tk_widget_has_attribute_setter?(attribute)
         | 
| 32 | 
            +
            #         if ['anchor', 'justify'].include?(attribute.to_s)
         | 
| 33 | 
            +
            #           true
         | 
| 34 | 
            +
            #         else
         | 
| 35 | 
            +
            #           super
         | 
| 36 | 
            +
            #         end
         | 
| 37 | 
            +
            #       end
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 | 
            +
            # a copy of this software and associated documentation files (the
         | 
| 5 | 
            +
            # "Software"), to deal in the Software without restriction, including
         | 
| 6 | 
            +
            # without limitation the rights to use, copy, modify, merge, publish,
         | 
| 7 | 
            +
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 | 
            +
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 | 
            +
            # the following conditions:
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # The above copyright notice and this permission notice shall be
         | 
| 12 | 
            +
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            +
            #
         | 
| 14 | 
            +
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 | 
            +
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 | 
            +
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| 17 | 
            +
            # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         | 
| 18 | 
            +
            # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         | 
| 19 | 
            +
            # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         | 
| 20 | 
            +
            # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            require 'glimmer/tk/widget_proxy'
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            module Glimmer
         | 
| 25 | 
            +
              module Tk
         | 
| 26 | 
            +
                # Custom list widget implementation
         | 
| 27 | 
            +
                class ListProxy < WidgetProxy
         | 
| 28 | 
            +
                  def initialize(underscored_widget_name, parent_proxy, args)
         | 
| 29 | 
            +
                    super('treeview', parent_proxy, args)
         | 
| 30 | 
            +
                    @tk.show = 'tree'
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                  
         | 
| 33 | 
            +
                  def widget_custom_attribute_mapping
         | 
| 34 | 
            +
                    @widget_custom_attribute_mapping ||= {
         | 
| 35 | 
            +
                      ::Tk::Tile::Treeview => {
         | 
| 36 | 
            +
                        'items' => {
         | 
| 37 | 
            +
                          getter: {name: 'items', invoker: lambda { |widget, args| tk.children('').map(&:text) }},
         | 
| 38 | 
            +
                          setter: {name: 'items=', invoker: lambda { |widget, args|
         | 
| 39 | 
            +
                            @tk.delete @tk.children('')
         | 
| 40 | 
            +
                            args.first.each do |child|
         | 
| 41 | 
            +
                              @tk.insert('', 'end', :text => child)
         | 
| 42 | 
            +
                            end
         | 
| 43 | 
            +
                          }},
         | 
| 44 | 
            +
                        },
         | 
| 45 | 
            +
                        'selection' => {
         | 
| 46 | 
            +
                          getter: {name: 'selection', invoker: lambda { |widget, args| @tk.selection.map(&:text) }},
         | 
| 47 | 
            +
                          setter: {name: 'selection=', invoker: lambda { |widget, args|
         | 
| 48 | 
            +
                            selection_args = args.first.is_a?(Array) ? args.first : [args.first]
         | 
| 49 | 
            +
                            selection_items = selection_args.map do |arg|
         | 
| 50 | 
            +
                              @tk.children('').detect {|item| item.text == arg}
         | 
| 51 | 
            +
                            end
         | 
| 52 | 
            +
                            @tk.selection_set(*selection_items)
         | 
| 53 | 
            +
                          }},
         | 
| 54 | 
            +
                        },
         | 
| 55 | 
            +
                      },
         | 
| 56 | 
            +
                    }
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            # Copyright (c) 2020 Andy Maleh
         | 
| 2 | 
            -
            # | 
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 3 | 
             
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            # a copy of this software and associated documentation files (the
         | 
| 5 5 | 
             
            # "Software"), to deal in the Software without restriction, including
         | 
| @@ -7,10 +7,10 @@ | |
| 7 7 | 
             
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 8 | 
             
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 9 | 
             
            # the following conditions:
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # The above copyright notice and this permission notice shall be
         | 
| 12 12 | 
             
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            -
            # | 
| 13 | 
            +
            #
         | 
| 14 14 | 
             
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 15 | 
             
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 16 | 
             
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| @@ -22,7 +22,7 @@ | |
| 22 22 | 
             
            require 'glimmer/tk/widget_proxy'
         | 
| 23 23 |  | 
| 24 24 | 
             
            module Glimmer
         | 
| 25 | 
            -
              module Tk | 
| 25 | 
            +
              module Tk
         | 
| 26 26 | 
             
                # Proxy for Tk::Tile::Notebook
         | 
| 27 27 | 
             
                #
         | 
| 28 28 | 
             
                # Follows the Proxy Design Pattern
         | 
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            # Copyright (c) 2020 Andy Maleh
         | 
| 2 | 
            -
            # | 
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 3 | 
             
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            # a copy of this software and associated documentation files (the
         | 
| 5 5 | 
             
            # "Software"), to deal in the Software without restriction, including
         | 
| @@ -7,10 +7,10 @@ | |
| 7 7 | 
             
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 8 | 
             
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 9 | 
             
            # the following conditions:
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # The above copyright notice and this permission notice shall be
         | 
| 12 12 | 
             
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            -
            # | 
| 13 | 
            +
            #
         | 
| 14 14 | 
             
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 15 | 
             
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 16 | 
             
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            # Copyright (c) 2020 Andy Maleh
         | 
| 2 | 
            -
            # | 
| 1 | 
            +
            # Copyright (c) 2020-2021 Andy Maleh
         | 
| 2 | 
            +
            #
         | 
| 3 3 | 
             
            # Permission is hereby granted, free of charge, to any person obtaining
         | 
| 4 4 | 
             
            # a copy of this software and associated documentation files (the
         | 
| 5 5 | 
             
            # "Software"), to deal in the Software without restriction, including
         | 
| @@ -7,10 +7,10 @@ | |
| 7 7 | 
             
            # distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 8 8 | 
             
            # permit persons to whom the Software is furnished to do so, subject to
         | 
| 9 9 | 
             
            # the following conditions:
         | 
| 10 | 
            -
            # | 
| 10 | 
            +
            #
         | 
| 11 11 | 
             
            # The above copyright notice and this permission notice shall be
         | 
| 12 12 | 
             
            # included in all copies or substantial portions of the Software.
         | 
| 13 | 
            -
            # | 
| 13 | 
            +
            #
         | 
| 14 14 | 
             
            # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         | 
| 15 15 | 
             
            # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 16 16 | 
             
            # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         | 
| @@ -29,7 +29,13 @@ module Glimmer | |
| 29 29 |  | 
| 30 30 | 
             
                  DEFAULT_INITIALIZERS = {
         | 
| 31 31 | 
             
                    'combobox' => lambda do |tk|
         | 
| 32 | 
            -
                      tk.textvariable = ::TkVariable.new | 
| 32 | 
            +
                      tk.textvariable = ::TkVariable.new
         | 
| 33 | 
            +
                    end,
         | 
| 34 | 
            +
                    'label' => lambda do |tk|
         | 
| 35 | 
            +
                      tk.textvariable = ::TkVariable.new
         | 
| 36 | 
            +
                    end,
         | 
| 37 | 
            +
                    'entry' => lambda do |tk|
         | 
| 38 | 
            +
                      tk.textvariable = ::TkVariable.new
         | 
| 33 39 | 
             
                    end,
         | 
| 34 40 | 
             
                  }
         | 
| 35 41 |  | 
| @@ -44,9 +50,30 @@ module Glimmer | |
| 44 50 | 
             
                        Glimmer::Tk.const_get(class_name)
         | 
| 45 51 | 
             
                      rescue
         | 
| 46 52 | 
             
                        Glimmer::Tk::WidgetProxy
         | 
| 47 | 
            -
                      end | 
| 48 | 
            -
                    end | 
| 49 | 
            -
             | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
                    
         | 
| 56 | 
            +
                    # This supports widgets in and out of basic Tk
         | 
| 57 | 
            +
                    def tk_widget_class_for(underscored_widget_name)
         | 
| 58 | 
            +
                      tk_widget_class_basename = underscored_widget_name.camelcase(:upper)
         | 
| 59 | 
            +
                      potential_tk_widget_class_names = [
         | 
| 60 | 
            +
                        "::Tk::Tile::#{tk_widget_class_basename}",
         | 
| 61 | 
            +
                        "::Tk::#{tk_widget_class_basename}",
         | 
| 62 | 
            +
                        "::Tk#{tk_widget_class_basename}",
         | 
| 63 | 
            +
                        "::Glimmer::Tk::#{tk_widget_class_basename}Proxy",
         | 
| 64 | 
            +
                      ]
         | 
| 65 | 
            +
                      tk_widget_class = nil
         | 
| 66 | 
            +
                      potential_tk_widget_class_names.each do |tk_widget_name|
         | 
| 67 | 
            +
                        begin
         | 
| 68 | 
            +
                          tk_widget_class = eval(tk_widget_name)
         | 
| 69 | 
            +
                          break
         | 
| 70 | 
            +
                        rescue RuntimeError, SyntaxError, NameError => e
         | 
| 71 | 
            +
                          Glimmer::Config.logger.debug e.full_message
         | 
| 72 | 
            +
                        end
         | 
| 73 | 
            +
                      end
         | 
| 74 | 
            +
                      tk_widget_class
         | 
| 75 | 
            +
                    end
         | 
| 76 | 
            +
                  end
         | 
| 50 77 |  | 
| 51 78 | 
             
                  # Initializes a new Tk Widget
         | 
| 52 79 | 
             
                  #
         | 
| @@ -56,14 +83,9 @@ module Glimmer | |
| 56 83 | 
             
                    @args = args
         | 
| 57 84 | 
             
                    tk_widget_class = self.class.tk_widget_class_for(underscored_widget_name)
         | 
| 58 85 | 
             
                    @tk = tk_widget_class.new(@parent_proxy.tk, *args)
         | 
| 59 | 
            -
                     | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
                    rescue => e
         | 
| 63 | 
            -
                      # catching error just in case a widget doesn't support it
         | 
| 64 | 
            -
                      Glimmer::Config.logger.debug e.full_message
         | 
| 65 | 
            -
                    end
         | 
| 66 | 
            -
                    DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@tk)        
         | 
| 86 | 
            +
                    # a common widget initializer
         | 
| 87 | 
            +
                    @tk.grid
         | 
| 88 | 
            +
                    DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@tk)
         | 
| 67 89 | 
             
                    @parent_proxy.post_initialize_child(self)
         | 
| 68 90 | 
             
                  end
         | 
| 69 91 |  | 
| @@ -81,57 +103,63 @@ module Glimmer | |
| 81 103 | 
             
                    !!tk_widget_class_for(underscored_widget_name)
         | 
| 82 104 | 
             
                  end
         | 
| 83 105 |  | 
| 84 | 
            -
                   | 
| 85 | 
            -
             | 
| 86 | 
            -
                     | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 89 | 
            -
             | 
| 90 | 
            -
                     | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 93 | 
            -
                     | 
| 94 | 
            -
                    nil      
         | 
| 106 | 
            +
                  def tk_widget_has_attribute_setter?(attribute)
         | 
| 107 | 
            +
                    result = nil
         | 
| 108 | 
            +
                    begin
         | 
| 109 | 
            +
                      # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
         | 
| 110 | 
            +
                      @tk.send(attribute_setter(attribute), @tk.send(attribute))
         | 
| 111 | 
            +
                      result = true
         | 
| 112 | 
            +
                    rescue => e
         | 
| 113 | 
            +
                      result = false
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
                    result
         | 
| 95 116 | 
             
                  end
         | 
| 96 117 |  | 
| 97 | 
            -
                  def  | 
| 118 | 
            +
                  def tk_widget_has_attribute_getter_setter?(attribute)
         | 
| 98 119 | 
             
                    result = nil
         | 
| 99 | 
            -
                    begin | 
| 100 | 
            -
                      # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now | 
| 101 | 
            -
                      @tk.send( | 
| 120 | 
            +
                    begin
         | 
| 121 | 
            +
                      # TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
         | 
| 122 | 
            +
                      @tk.send(attribute, @tk.send(attribute))
         | 
| 102 123 | 
             
                      result = true
         | 
| 103 124 | 
             
                    rescue => e
         | 
| 104 125 | 
             
                      result = false
         | 
| 105 126 | 
             
                    end
         | 
| 106 | 
            -
                    result | 
| 127 | 
            +
                    result
         | 
| 107 128 | 
             
                  end
         | 
| 108 129 |  | 
| 109 | 
            -
                  def has_attribute?( | 
| 110 | 
            -
                     | 
| 130 | 
            +
                  def has_attribute?(attribute, *args)
         | 
| 131 | 
            +
                    (widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]) ||
         | 
| 132 | 
            +
                      tk_widget_has_attribute_setter?(attribute) ||
         | 
| 133 | 
            +
                      tk_widget_has_attribute_getter_setter?(attribute) ||
         | 
| 134 | 
            +
                      respond_to?(attribute_setter(attribute), args)
         | 
| 111 135 | 
             
                  end
         | 
| 112 136 |  | 
| 113 | 
            -
                  def set_attribute( | 
| 114 | 
            -
                    widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][ | 
| 137 | 
            +
                  def set_attribute(attribute, *args)
         | 
| 138 | 
            +
                    widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
         | 
| 115 139 | 
             
                    if widget_custom_attribute
         | 
| 116 140 | 
             
                      widget_custom_attribute[:setter][:invoker].call(@tk, args)
         | 
| 117 | 
            -
                    elsif  | 
| 118 | 
            -
                      @tk.send(attribute_setter( | 
| 141 | 
            +
                    elsif tk_widget_has_attribute_setter?(attribute)
         | 
| 142 | 
            +
                      @tk.send(attribute_setter(attribute), *args) unless @tk.send(attribute) == args.first
         | 
| 143 | 
            +
                    elsif tk_widget_has_attribute_getter_setter?(attribute)
         | 
| 144 | 
            +
                      @tk.send(attribute, *args) unless @tk.send(attribute) == args.first
         | 
| 119 145 | 
             
                    else
         | 
| 120 | 
            -
                      send(attribute_setter( | 
| 146 | 
            +
                      send(attribute_setter(attribute), args)
         | 
| 121 147 | 
             
                    end
         | 
| 122 148 | 
             
                  end
         | 
| 123 149 |  | 
| 124 | 
            -
                  def get_attribute( | 
| 125 | 
            -
                    widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][ | 
| 150 | 
            +
                  def get_attribute(attribute)
         | 
| 151 | 
            +
                    widget_custom_attribute = widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][attribute.to_s]
         | 
| 126 152 | 
             
                    if widget_custom_attribute
         | 
| 127 153 | 
             
                      widget_custom_attribute[:getter][:invoker].call(@tk, args)
         | 
| 154 | 
            +
                    elsif tk_widget_has_attribute_getter_setter?(attribute)
         | 
| 155 | 
            +
                      @tk.send(attribute)
         | 
| 128 156 | 
             
                    else
         | 
| 129 | 
            -
                       | 
| 157 | 
            +
                      send(attribute)
         | 
| 130 158 | 
             
                    end
         | 
| 131 | 
            -
                  end | 
| 159 | 
            +
                  end
         | 
| 132 160 |  | 
| 133 | 
            -
                  def attribute_setter( | 
| 134 | 
            -
                    "#{ | 
| 161 | 
            +
                  def attribute_setter(attribute)
         | 
| 162 | 
            +
                    "#{attribute}="
         | 
| 135 163 | 
             
                  end
         | 
| 136 164 |  | 
| 137 165 | 
             
                  def widget_custom_attribute_mapping
         | 
| @@ -142,13 +170,25 @@ module Glimmer | |
| 142 170 | 
             
                          setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
         | 
| 143 171 | 
             
                        },
         | 
| 144 172 | 
             
                      },
         | 
| 173 | 
            +
                      ::Tk::Tile::TLabel => {
         | 
| 174 | 
            +
                        'text' => {
         | 
| 175 | 
            +
                          getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
         | 
| 176 | 
            +
                          setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first }},
         | 
| 177 | 
            +
                        },
         | 
| 178 | 
            +
                      },
         | 
| 179 | 
            +
                      ::Tk::Tile::TEntry => {
         | 
| 180 | 
            +
                        'text' => {
         | 
| 181 | 
            +
                          getter: {name: 'text', invoker: lambda { |widget, args| @tk.textvariable&.value }},
         | 
| 182 | 
            +
                          setter: {name: 'text=', invoker: lambda { |widget, args| @tk.textvariable&.value = args.first unless @text_variable_edit }},
         | 
| 183 | 
            +
                        },
         | 
| 184 | 
            +
                      },
         | 
| 145 185 | 
             
                    }
         | 
| 146 186 | 
             
                  end
         | 
| 147 187 |  | 
| 148 | 
            -
                  def  | 
| 149 | 
            -
                    @ | 
| 188 | 
            +
                  def widget_attribute_listener_installers
         | 
| 189 | 
            +
                    @tk_widget_attribute_listener_installers ||= {
         | 
| 150 190 | 
             
                      ::Tk::Tile::TCombobox => {
         | 
| 151 | 
            -
                         | 
| 191 | 
            +
                        'text' => lambda do |observer|
         | 
| 152 192 | 
             
                          if observer.is_a?(Glimmer::DataBinding::ModelBinding)
         | 
| 153 193 | 
             
                            model = observer.model
         | 
| 154 194 | 
             
                            options_model_property = observer.property_name + '_options'
         | 
| @@ -158,29 +198,51 @@ module Glimmer | |
| 158 198 | 
             
                            observer.call(@tk.textvariable.value)
         | 
| 159 199 | 
             
                          }
         | 
| 160 200 | 
             
                        end,
         | 
| 161 | 
            -
                      }
         | 
| 201 | 
            +
                      },
         | 
| 202 | 
            +
                      ::Tk::Tile::TEntry => {
         | 
| 203 | 
            +
                        'text' => lambda do |observer|
         | 
| 204 | 
            +
                          tk.validate = 'key'
         | 
| 205 | 
            +
                          tk.validatecommand { |new_tk_variable|
         | 
| 206 | 
            +
                            @text_variable_edit = new_tk_variable.value != @tk.textvariable.value
         | 
| 207 | 
            +
                            if @text_variable_edit
         | 
| 208 | 
            +
                              observer.call(new_tk_variable.value)
         | 
| 209 | 
            +
                              @text_variable_edit = nil
         | 
| 210 | 
            +
                              true
         | 
| 211 | 
            +
                            else
         | 
| 212 | 
            +
                              false
         | 
| 213 | 
            +
                            end
         | 
| 214 | 
            +
                          }
         | 
| 215 | 
            +
                        end,
         | 
| 216 | 
            +
                      },
         | 
| 162 217 | 
             
                    }
         | 
| 163 218 | 
             
                  end
         | 
| 164 219 |  | 
| 165 | 
            -
                  def add_observer(observer,  | 
| 166 | 
            -
                     | 
| 167 | 
            -
                    widget_listener_installers =  | 
| 220 | 
            +
                  def add_observer(observer, attribute)
         | 
| 221 | 
            +
                    attribute_listener_installers = @tk.class.ancestors.map {|ancestor| widget_attribute_listener_installers[ancestor]}.compact
         | 
| 222 | 
            +
                    widget_listener_installers = attribute_listener_installers.map{|installer| installer[attribute.to_s]}.compact if !attribute_listener_installers.empty?
         | 
| 168 223 | 
             
                    widget_listener_installers.to_a.first&.call(observer)
         | 
| 169 | 
            -
                  end | 
| 224 | 
            +
                  end
         | 
| 170 225 |  | 
| 171 226 | 
             
                  def content(&block)
         | 
| 172 227 | 
             
                    Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::WidgetExpression.new, &block)
         | 
| 173 228 | 
             
                  end
         | 
| 174 229 |  | 
| 175 230 | 
             
                  def method_missing(method, *args, &block)
         | 
| 176 | 
            -
                     | 
| 231 | 
            +
                    method = method.to_s
         | 
| 232 | 
            +
                    if args.empty? && block.nil? && widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method]
         | 
| 233 | 
            +
                      get_attribute(method)
         | 
| 234 | 
            +
                    elsif widget_custom_attribute_mapping[tk.class] && widget_custom_attribute_mapping[tk.class][method.sub(/=$/, '')] && method.end_with?('=') && block.nil?
         | 
| 235 | 
            +
                      set_attribute(method.sub(/=$/, ''), *args)
         | 
| 236 | 
            +
                    else
         | 
| 237 | 
            +
                      tk.send(method, *args, &block)
         | 
| 238 | 
            +
                    end
         | 
| 177 239 | 
             
                  rescue => e
         | 
| 178 240 | 
             
                    Glimmer::Config.logger.debug {"Neither WidgetProxy nor #{tk.class.name} can handle the method ##{method}"}
         | 
| 179 | 
            -
                    super
         | 
| 241 | 
            +
                    super(method.to_sym, *args, &block)
         | 
| 180 242 | 
             
                  end
         | 
| 181 243 |  | 
| 182 244 | 
             
                  def respond_to?(method, *args, &block)
         | 
| 183 | 
            -
                    super || | 
| 245 | 
            +
                    super ||
         | 
| 184 246 | 
             
                      tk.respond_to?(method, *args, &block)
         | 
| 185 247 | 
             
                  end
         | 
| 186 248 | 
             
                end
         |