glimmer 0.1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING.LGPL +504 -0
- data/README +27 -0
- data/samples/contactmanager/contact.rb +12 -0
- data/samples/contactmanager/contact_manager.rb +65 -0
- data/samples/contactmanager/contact_manager_presenter.rb +23 -0
- data/samples/contactmanager/contact_repository.rb +27 -0
- data/samples/hello_world.rb +26 -0
- data/samples/login.rb +97 -0
- data/samples/tictactoe/tic_tac_toe.rb +67 -0
- data/samples/tictactoe/tic_tac_toe_board.rb +149 -0
- data/src/command_handler.rb +11 -0
- data/src/command_handler_chain_factory.rb +23 -0
- data/src/command_handler_chain_link.rb +22 -0
- data/src/command_handlers.rb +26 -0
- data/src/command_handlers/bind_command_handler.rb +29 -0
- data/src/command_handlers/data_binding_command_handler.rb +64 -0
- data/src/command_handlers/models/model_observer.rb +25 -0
- data/src/command_handlers/models/observable_array.rb +46 -0
- data/src/command_handlers/models/observable_model.rb +35 -0
- data/src/command_handlers/models/r_runnable.rb +14 -0
- data/src/command_handlers/models/r_shell.rb +27 -0
- data/src/command_handlers/models/r_widget.rb +146 -0
- data/src/command_handlers/models/r_widget_listener.rb +12 -0
- data/src/command_handlers/models/r_widget_packages.rb +9 -0
- data/src/command_handlers/models/table_items_updater.rb +39 -0
- data/src/command_handlers/models/widget_observer.rb +23 -0
- data/src/command_handlers/shell_command_handler.rb +18 -0
- data/src/command_handlers/swt_constant_command_handler.rb +22 -0
- data/src/command_handlers/table_column_properties_data_binding_command_handler.rb +24 -0
- data/src/command_handlers/table_items_data_binding_command_handler.rb +30 -0
- data/src/command_handlers/widget_command_handler.rb +26 -0
- data/src/command_handlers/widget_listener_command_handler.rb +35 -0
- data/src/command_handlers/widget_method_command_handler.rb +22 -0
- data/src/glimmer.rb +45 -0
- data/src/parent.rb +8 -0
- data/src/shine.rb +24 -0
- data/src/swt.rb +10 -0
- data/src/xml.rb +10 -0
- data/src/xml_command_handlers.rb +18 -0
- data/src/xml_command_handlers/html_command_handler.rb +49 -0
- data/src/xml_command_handlers/models/depth_first_search_iterator.rb +20 -0
- data/src/xml_command_handlers/models/name_space_visitor.rb +21 -0
- data/src/xml_command_handlers/models/node.rb +83 -0
- data/src/xml_command_handlers/models/node_visitor.rb +12 -0
- data/src/xml_command_handlers/models/xml_visitor.rb +62 -0
- data/src/xml_command_handlers/xml_command_handler.rb +22 -0
- data/src/xml_command_handlers/xml_name_space_command_handler.rb +34 -0
- data/src/xml_command_handlers/xml_tag_command_handler.rb +26 -0
- data/src/xml_command_handlers/xml_text_command_handler.rb +22 -0
- data/test/glimmer_constant_test.rb +36 -0
- data/test/glimmer_data_binding_test.rb +236 -0
- data/test/glimmer_listeners_test.rb +61 -0
- data/test/glimmer_shine_data_binding_test.rb +88 -0
- data/test/glimmer_table_data_binding_test.rb +135 -0
- data/test/glimmer_test.rb +233 -0
- data/test/observable_model_test.rb +27 -0
- data/test/r_widget_test.rb +52 -0
- data/test/samples/contactmanager/contact_manager_presenter_test.rb +60 -0
- data/test/samples/tictactoe/tic_tac_toe_test.rb +265 -0
- data/test/xml/glimmer_xml_test.rb +163 -0
- metadata +126 -0
| @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module CommandHandler
         | 
| 5 | 
            +
              def can_handle?(parent, command_symbol, *args, &block)
         | 
| 6 | 
            +
                raise "must be implemented by a class"
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
              def do_handle(parent, command_symbol, *args, &block) 
         | 
| 9 | 
            +
                raise "must be implemented by a class"
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.dirname(__FILE__) + "/command_handler_chain_link"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class CommandHandlerChainFactory
         | 
| 7 | 
            +
              @@last_chain_link = nil
         | 
| 8 | 
            +
              @@chain = nil
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              def self.set_command_handlers(*command_handler_array)
         | 
| 11 | 
            +
                command_handler_array.each do |command_handler|
         | 
| 12 | 
            +
                  puts "Loading #{command_handler.class.to_s}..."
         | 
| 13 | 
            +
                  chain_link = CommandHandlerChainLink.new(command_handler)
         | 
| 14 | 
            +
                  @@last_chain_link.chain_to(chain_link) if @@last_chain_link
         | 
| 15 | 
            +
                  @@last_chain_link = chain_link
         | 
| 16 | 
            +
                  @@chain = chain_link unless @@chain
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
              
         | 
| 20 | 
            +
              def self.chain
         | 
| 21 | 
            +
                @@chain
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class CommandHandlerChainLink
         | 
| 5 | 
            +
              def initialize(command_handler)
         | 
| 6 | 
            +
                @command_handler = command_handler
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
              def chain_to(next_chain_link)
         | 
| 9 | 
            +
                @next_chain_link = next_chain_link
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              def handle(parent, command_symbol, *args, &block)
         | 
| 12 | 
            +
                if (@command_handler.can_handle?(parent, command_symbol, *args, &block))
         | 
| 13 | 
            +
                  puts "#{@command_handler.class.to_s} will handle command: #{command_symbol} with arguments #{args}"
         | 
| 14 | 
            +
                  return @command_handler.do_handle(parent, command_symbol, *args, &block)
         | 
| 15 | 
            +
                elsif @next_chain_link
         | 
| 16 | 
            +
                  return @next_chain_link.handle(parent, command_symbol, *args, &block)
         | 
| 17 | 
            +
                else
         | 
| 18 | 
            +
                  puts "Command: #{command_symbol} cannot be handled!"
         | 
| 19 | 
            +
                  return nil
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.dirname(__FILE__) + "/command_handler_chain_factory"
         | 
| 5 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/shell_command_handler"
         | 
| 6 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/widget_listener_command_handler"
         | 
| 7 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/bind_command_handler"
         | 
| 8 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/table_items_data_binding_command_handler"
         | 
| 9 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/table_column_properties_data_binding_command_handler"
         | 
| 10 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/data_binding_command_handler"
         | 
| 11 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/widget_method_command_handler"
         | 
| 12 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/widget_command_handler"
         | 
| 13 | 
            +
            require File.dirname(__FILE__) + "/command_handlers/swt_constant_command_handler"
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            # edit to add more command handlers and extend Glimmer
         | 
| 16 | 
            +
            CommandHandlerChainFactory.set_command_handlers(
         | 
| 17 | 
            +
              ShellCommandHandler.new,
         | 
| 18 | 
            +
              WidgetListenerCommandHandler.new,
         | 
| 19 | 
            +
              BindCommandHandler.new,
         | 
| 20 | 
            +
              TableItemsDataBindingCommandHandler.new,
         | 
| 21 | 
            +
              TableColumnPropertiesDataBindingCommandHandler.new,
         | 
| 22 | 
            +
              DataBindingCommandHandler.new,
         | 
| 23 | 
            +
              WidgetMethodCommandHandler.new,
         | 
| 24 | 
            +
              WidgetCommandHandler.new,
         | 
| 25 | 
            +
              SwtConstantCommandHandler.new #at the bottom to avoid stealing commands from other command handlers
         | 
| 26 | 
            +
            )
         | 
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.dirname(__FILE__) + "/../command_handler"
         | 
| 5 | 
            +
            require File.dirname(__FILE__) + "/models/r_widget"
         | 
| 6 | 
            +
            require File.dirname(__FILE__) + "/models/model_observer"
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            class BindCommandHandler
         | 
| 9 | 
            +
              include CommandHandler
         | 
| 10 | 
            +
              
         | 
| 11 | 
            +
              include_package 'org.eclipse.swt.widgets'
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def can_handle?(parent, command_symbol, *args, &block)
         | 
| 14 | 
            +
                parent.is_a?(RWidget) and
         | 
| 15 | 
            +
                command_symbol.to_s == "bind" and
         | 
| 16 | 
            +
                (((args.size == 2) and
         | 
| 17 | 
            +
                (args[1].is_a?(Symbol) or args[1].is_a?(String))) or
         | 
| 18 | 
            +
                ((args.size == 3) and
         | 
| 19 | 
            +
                (args[1].is_a?(Symbol) or args[1].is_a?(String)) and
         | 
| 20 | 
            +
                (args[2].is_a?(Symbol) or args[2].is_a?(String)))) and
         | 
| 21 | 
            +
                block == nil
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
              def do_handle(parent, command_symbol, *args, &block)
         | 
| 25 | 
            +
                property_type = args[2] if (args.size == 3)
         | 
| 26 | 
            +
                ModelObserver.new(args[0], args[1].to_s, property_type)
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
            end
         | 
| @@ -0,0 +1,64 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.dirname(__FILE__) + "/../command_handler"
         | 
| 5 | 
            +
            require File.dirname(__FILE__) + "/models/r_widget"
         | 
| 6 | 
            +
            require File.dirname(__FILE__) + "/models/observable_model"
         | 
| 7 | 
            +
            require File.dirname(__FILE__) + "/models/model_observer"
         | 
| 8 | 
            +
            require File.dirname(__FILE__) + "/models/widget_observer"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            class DataBindingCommandHandler 
         | 
| 11 | 
            +
              extend Glimmer
         | 
| 12 | 
            +
              include CommandHandler
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
              include_package 'org.eclipse.swt.widgets'
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              @@widget_data_binders = {
         | 
| 17 | 
            +
                Java::OrgEclipseSwtWidgets::Text => {
         | 
| 18 | 
            +
                  :text => Proc.new do |rwidget, model_observer|
         | 
| 19 | 
            +
                    add_contents(rwidget) {
         | 
| 20 | 
            +
                      on_modify_text { |modify_event|
         | 
| 21 | 
            +
                        model_observer.update(rwidget.widget.getText)
         | 
| 22 | 
            +
                      }
         | 
| 23 | 
            +
                    }
         | 
| 24 | 
            +
                    end,
         | 
| 25 | 
            +
                  },
         | 
| 26 | 
            +
                  Java::OrgEclipseSwtWidgets::Button => {
         | 
| 27 | 
            +
                    :selection => Proc.new do |rwidget, model_observer|
         | 
| 28 | 
            +
                      add_contents(rwidget) {
         | 
| 29 | 
            +
                        on_widget_selected { |selection_event|
         | 
| 30 | 
            +
                          model_observer.update(rwidget.widget.getSelection)
         | 
| 31 | 
            +
                        }
         | 
| 32 | 
            +
                      }
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  },
         | 
| 35 | 
            +
                  Java::OrgEclipseSwtWidgets::Spinner => {
         | 
| 36 | 
            +
                    :selection => Proc.new do |rwidget, model_observer|
         | 
| 37 | 
            +
                      add_contents(rwidget) {
         | 
| 38 | 
            +
                        on_widget_selected { |selection_event|
         | 
| 39 | 
            +
                          model_observer.update(rwidget.widget.getSelection)
         | 
| 40 | 
            +
                        }
         | 
| 41 | 
            +
                      }
         | 
| 42 | 
            +
                    end
         | 
| 43 | 
            +
                  }
         | 
| 44 | 
            +
                }    
         | 
| 45 | 
            +
                
         | 
| 46 | 
            +
                def can_handle?(parent, command_symbol, *args, &block)
         | 
| 47 | 
            +
                  parent.is_a?(RWidget) and
         | 
| 48 | 
            +
                   args.size == 1 and
         | 
| 49 | 
            +
                   args[0].is_a?(ModelObserver)
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
                
         | 
| 52 | 
            +
                def do_handle(parent, command_symbol, *args, &block)
         | 
| 53 | 
            +
                  model_observer = args[0]
         | 
| 54 | 
            +
                  widget_observer = WidgetObserver.new(parent, command_symbol.to_s)
         | 
| 55 | 
            +
                  widget_observer.update(model_observer.evaluate_property)
         | 
| 56 | 
            +
                  model = model_observer.model
         | 
| 57 | 
            +
                  model.extend ObservableModel unless model.is_a?(ObservableModel)
         | 
| 58 | 
            +
                  model.add_observer(model_observer.property_name, widget_observer)
         | 
| 59 | 
            +
                  widget_data_binder_map = @@widget_data_binders[parent.widget.class]
         | 
| 60 | 
            +
                  widget_data_binder = widget_data_binder_map[command_symbol.to_s.to_sym] if widget_data_binder_map
         | 
| 61 | 
            +
                  widget_data_binder.call(parent, model_observer) if widget_data_binder
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
                
         | 
| 64 | 
            +
              end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class ModelObserver
         | 
| 5 | 
            +
              attr_reader :model, :property_name, :property_type
         | 
| 6 | 
            +
              @@property_type_converters = {
         | 
| 7 | 
            +
                :undefined => Proc.new { |value| value }, 
         | 
| 8 | 
            +
                :fixnum => Proc.new { |string_value| string_value.to_i }
         | 
| 9 | 
            +
                #TODO check what other types are needed
         | 
| 10 | 
            +
              }
         | 
| 11 | 
            +
              def initialize(model, property_name, property_type)
         | 
| 12 | 
            +
                property_type = :undefined unless property_type
         | 
| 13 | 
            +
                @model = model
         | 
| 14 | 
            +
                @property_name = property_name
         | 
| 15 | 
            +
                @property_type = property_type
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              def update(value)
         | 
| 18 | 
            +
                converted_value = @@property_type_converters[@property_type].call(value)
         | 
| 19 | 
            +
                @model.send(@property_name + "=", converted_value) unless evaluate_property == converted_value
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              def evaluate_property
         | 
| 22 | 
            +
                @model.send(@property_name)
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
              
         | 
| @@ -0,0 +1,46 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module ObservableArray
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              def add_observer(element_properties, observer)
         | 
| 7 | 
            +
                property_observer_list << observer
         | 
| 8 | 
            +
                each do |element|
         | 
| 9 | 
            +
                  element_properties.each do |property|
         | 
| 10 | 
            +
                    element.extend(ObservableModel) unless element.is_a?(ObservableModel)
         | 
| 11 | 
            +
                    element.add_observer(property, observer)
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              def property_observer_list
         | 
| 17 | 
            +
                @property_observer_list = [] unless @property_observer_list
         | 
| 18 | 
            +
                @property_observer_list
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              def notify_observers
         | 
| 22 | 
            +
                property_observer_list.each {|observer| observer.update}
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
              
         | 
| 25 | 
            +
              def self.extend_object(array)
         | 
| 26 | 
            +
                array.instance_eval("alias original_add <<")
         | 
| 27 | 
            +
                array.instance_eval "def <<(value) \n self.original_add(value); notify_observers; \nend"
         | 
| 28 | 
            +
                
         | 
| 29 | 
            +
                notify_observers_on_invokation(array, "delete", 1)
         | 
| 30 | 
            +
                notify_observers_on_invokation(array, "delete_at", 1)
         | 
| 31 | 
            +
                notify_observers_on_invokation(array, "clear")
         | 
| 32 | 
            +
                
         | 
| 33 | 
            +
                super
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
              
         | 
| 36 | 
            +
              def self.notify_observers_on_invokation(model, method, argument_count=0)
         | 
| 37 | 
            +
                model.instance_eval "alias original_#{method} #{method}\n"
         | 
| 38 | 
            +
                arguments = ""
         | 
| 39 | 
            +
                for index in 1..argument_count
         | 
| 40 | 
            +
                  arguments += "argument" + index.to_s + ","
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
                arguments = arguments[0..-2]
         | 
| 43 | 
            +
                model.instance_eval "def #{method}(#{arguments}) \n self.original_#{method}(#{arguments}); notify_observers; \nend"
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            end
         | 
| @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module ObservableModel
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              def add_observer(property_name, observer)
         | 
| 7 | 
            +
                property_observer_list(property_name) << observer
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              def property_observer_hash
         | 
| 11 | 
            +
                @property_observers = Hash.new unless @property_observers
         | 
| 12 | 
            +
                @property_observers
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              def property_observer_list(property_name)
         | 
| 16 | 
            +
                property_observer_hash[property_name.to_sym] = [] unless property_observer_hash[property_name.to_sym]
         | 
| 17 | 
            +
                property_observer_hash[property_name.to_sym]
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
              
         | 
| 20 | 
            +
              def notify_observers(property_name)
         | 
| 21 | 
            +
                property_observer_list(property_name).each {|observer| observer.update(send(property_name))}
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
              def self.extend_object(model)
         | 
| 25 | 
            +
                super
         | 
| 26 | 
            +
                model.methods.each do |method|
         | 
| 27 | 
            +
                  setter_method_pattern = /^\w+=$/
         | 
| 28 | 
            +
                  if (method.match(setter_method_pattern))
         | 
| 29 | 
            +
                    getter_method = method[0, method.length - 1]
         | 
| 30 | 
            +
                    model.instance_eval "alias original_#{method} #{method}\n"
         | 
| 31 | 
            +
                    model.instance_eval "def #{method}(value) \n self.original_#{method}(value); notify_observers('#{getter_method}'); \nend"
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.dirname(__FILE__) + "/r_widget"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class RShell < RWidget
         | 
| 7 | 
            +
              include_package 'org.eclipse.swt.layout'
         | 
| 8 | 
            +
              include_package 'org.eclipse.swt.widgets'
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              attr_reader :display
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              def initialize(display = Display.new)
         | 
| 13 | 
            +
                @display = display
         | 
| 14 | 
            +
                @widget = Shell.new(@display)
         | 
| 15 | 
            +
                @widget.setLayout(FillLayout.new)
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              def open
         | 
| 19 | 
            +
                @widget.pack
         | 
| 20 | 
            +
                @widget.open
         | 
| 21 | 
            +
                until @widget.isDisposed
         | 
| 22 | 
            +
                  @display.sleep unless @display.readAndDispatch
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                @display.dispose
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,146 @@ | |
| 1 | 
            +
            # Copyright (C) 2007-2008 Annas Al Maleh
         | 
| 2 | 
            +
            # Licensed under the LGPL. See /COPYING.LGPL for more details.
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require File.dirname(__FILE__) + "/r_widget_listener"
         | 
| 5 | 
            +
            require File.dirname(__FILE__) + "/r_runnable"
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class RWidget
         | 
| 8 | 
            +
              require File.dirname(__FILE__) + "/r_widget_packages"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              include Parent
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              attr_reader :widget
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
              #TODO externalize
         | 
| 15 | 
            +
              @@default_styles = {
         | 
| 16 | 
            +
                "text" => SWT::BORDER,
         | 
| 17 | 
            +
                "table" => SWT::BORDER,
         | 
| 18 | 
            +
                "spinner" => SWT::BORDER,
         | 
| 19 | 
            +
                "button" => SWT::PUSH,
         | 
| 20 | 
            +
              }
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              #TODO externalize
         | 
| 23 | 
            +
              @@default_initializers = {
         | 
| 24 | 
            +
                "composite" => Proc.new {|composite| composite.setLayout(GridLayout.new) },
         | 
| 25 | 
            +
                "table" => Proc.new do |table| 
         | 
| 26 | 
            +
                  table.setHeaderVisible(true)
         | 
| 27 | 
            +
                  table.setLinesVisible(true)
         | 
| 28 | 
            +
                end,
         | 
| 29 | 
            +
                "table_column" => Proc.new { |table_column| table_column.setWidth(80) },
         | 
| 30 | 
            +
                "group" => Proc.new {|group| group.setLayout(GridLayout.new) },
         | 
| 31 | 
            +
              }
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              def initialize(underscored_widget_name, parent, style, &contents)
         | 
| 34 | 
            +
                style = default_style(underscored_widget_name) unless style
         | 
| 35 | 
            +
                @widget = eval underscored_widget_name.to_s.camelcase(true) + '.new(parent, style)'
         | 
| 36 | 
            +
                @@default_initializers[underscored_widget_name].call(@widget) if @@default_initializers[underscored_widget_name]
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              def default_style(underscored_widget_name)
         | 
| 40 | 
            +
                style = @@default_styles[underscored_widget_name] if @@default_styles[underscored_widget_name]
         | 
| 41 | 
            +
                style = SWT::NONE unless style
         | 
| 42 | 
            +
                style
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
              
         | 
| 45 | 
            +
              def respond_to?(method_symbol, *args)
         | 
| 46 | 
            +
                @widget.respond_to?("set" + method_symbol.to_s.camelcase(true), args)
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
              
         | 
| 49 | 
            +
              def method_missing(method_symbol, *args)
         | 
| 50 | 
            +
                statement_to_eval = "@widget.send('set' + method_symbol.to_s.camelcase(true)"
         | 
| 51 | 
            +
                statement_to_eval << expand_arguments(args)
         | 
| 52 | 
            +
                statement_to_eval << ")"
         | 
| 53 | 
            +
                eval statement_to_eval
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
              
         | 
| 56 | 
            +
              def expand_arguments(args)
         | 
| 57 | 
            +
                expanded_args = ""
         | 
| 58 | 
            +
                index = 0
         | 
| 59 | 
            +
                args.each do
         | 
| 60 | 
            +
                  expanded_args << ", args[#{index}]"
         | 
| 61 | 
            +
                  index += 1
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
                expanded_args
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
              
         | 
| 66 | 
            +
              def self.widget_exists?(underscored_widget_name)
         | 
| 67 | 
            +
                begin
         | 
| 68 | 
            +
                  eval underscored_widget_name.camelcase(true)
         | 
| 69 | 
            +
                  true
         | 
| 70 | 
            +
                rescue NameError        
         | 
| 71 | 
            +
                  false
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
              
         | 
| 75 | 
            +
              def widget_listener_exists?(underscored_listener_name)
         | 
| 76 | 
            +
                listener_method_name = underscored_listener_name.camelcase()
         | 
| 77 | 
            +
                @widget.getClass.getMethods.each do |widget_method| 
         | 
| 78 | 
            +
                  if widget_method.getName.match(/add.*Listener/)
         | 
| 79 | 
            +
                    widget_method.getParameterTypes.each do |listener_type|
         | 
| 80 | 
            +
                      listener_type.getMethods.each do |listener_method|
         | 
| 81 | 
            +
                        if (listener_method.getName.match(listener_method_name))
         | 
| 82 | 
            +
                          return true
         | 
| 83 | 
            +
                        end
         | 
| 84 | 
            +
                      end
         | 
| 85 | 
            +
                    end
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                end
         | 
| 88 | 
            +
                return false
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
              
         | 
| 91 | 
            +
              def can_add_listener?(underscored_listener_name)
         | 
| 92 | 
            +
                listener_method_name = underscored_listener_name.camelcase()
         | 
| 93 | 
            +
                @widget.getClass.getMethods.each do |widget_method| 
         | 
| 94 | 
            +
                  if widget_method.getName.match(/add.*Listener/)
         | 
| 95 | 
            +
                    widget_method.getParameterTypes.each do |listener_type|
         | 
| 96 | 
            +
                      listener_type.getMethods.each do |listener_method|
         | 
| 97 | 
            +
                        if (listener_method.getName.match(listener_method_name))
         | 
| 98 | 
            +
                          return true
         | 
| 99 | 
            +
                        end
         | 
| 100 | 
            +
                      end
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
                  end
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
                return false
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
              
         | 
| 107 | 
            +
              def add_listener(underscored_listener_name, &block) 
         | 
| 108 | 
            +
                listener_method_name = underscored_listener_name.camelcase()
         | 
| 109 | 
            +
                @widget.getClass.getMethods.each do |widget_method| 
         | 
| 110 | 
            +
                  if widget_method.getName.match(/add.*Listener/)
         | 
| 111 | 
            +
                    widget_method.getParameterTypes.each do |listener_type|
         | 
| 112 | 
            +
                      listener_type.getMethods.each do |listener_method|
         | 
| 113 | 
            +
                        if (listener_method.getName.match(listener_method_name))
         | 
| 114 | 
            +
                          listener_class = Class.new(Object)
         | 
| 115 | 
            +
                          listener_class.send :include, (eval listener_type.to_s)
         | 
| 116 | 
            +
                          listener = listener_class.new
         | 
| 117 | 
            +
                          listener_type.getMethods.each do |t_method|
         | 
| 118 | 
            +
                            eval "def listener.#{t_method.getName}(event) end"
         | 
| 119 | 
            +
                          end
         | 
| 120 | 
            +
                          def listener.block=(block)
         | 
| 121 | 
            +
                            @block = block
         | 
| 122 | 
            +
                          end
         | 
| 123 | 
            +
                          listener.block=block
         | 
| 124 | 
            +
                          eval "def listener.#{listener_method.getName}(event) @block.call(event) if @block end"
         | 
| 125 | 
            +
                          @widget.send(widget_method.getName, listener)
         | 
| 126 | 
            +
                          return RWidgetListener.new(listener)
         | 
| 127 | 
            +
                        end
         | 
| 128 | 
            +
                      end
         | 
| 129 | 
            +
                    end
         | 
| 130 | 
            +
                  end
         | 
| 131 | 
            +
                end
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
              
         | 
| 134 | 
            +
              def process_block(block)
         | 
| 135 | 
            +
                block.call(@widget)
         | 
| 136 | 
            +
              end
         | 
| 137 | 
            +
              
         | 
| 138 | 
            +
              def async_exec(&block)
         | 
| 139 | 
            +
                @widget.getDisplay.asyncExec(RRunnable.new(&block))
         | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
             | 
| 142 | 
            +
              def sync_exec(&block)
         | 
| 143 | 
            +
                @widget.getDisplay.syncExec(RRunnable.new(&block))
         | 
| 144 | 
            +
              end
         | 
| 145 | 
            +
              
         | 
| 146 | 
            +
            end
         |