[macruby-changes] [1574] MacRuby/trunk/lib/hotcocoa

source_changes at macosforge.org source_changes at macosforge.org
Mon May 18 03:32:52 PDT 2009


Revision: 1574
          http://trac.macosforge.org/projects/ruby/changeset/1574
Author:   rich at infoether.com
Date:     2009-05-18 03:32:51 -0700 (Mon, 18 May 2009)
Log Message:
-----------
added mvc stuff, changed load to require for mappings, updated to include more delegates, added new delegating_to method

Modified Paths:
--------------
    MacRuby/trunk/lib/hotcocoa/delegate_builder.rb
    MacRuby/trunk/lib/hotcocoa/kvo_accessors.rb
    MacRuby/trunk/lib/hotcocoa/layout_view.rb
    MacRuby/trunk/lib/hotcocoa/mapper.rb
    MacRuby/trunk/lib/hotcocoa/mappings/alert.rb
    MacRuby/trunk/lib/hotcocoa/mappings/application.rb
    MacRuby/trunk/lib/hotcocoa/mappings/button.rb
    MacRuby/trunk/lib/hotcocoa/mappings/combo_box.rb
    MacRuby/trunk/lib/hotcocoa/mappings/web_view.rb
    MacRuby/trunk/lib/hotcocoa/mappings.rb

Added Paths:
-----------
    MacRuby/trunk/lib/hotcocoa/mvc.rb

Modified: MacRuby/trunk/lib/hotcocoa/delegate_builder.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/delegate_builder.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/delegate_builder.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -19,6 +19,12 @@
       set_delegate if required_methods.empty?
     end
     
+    def delegate_to(object, *method_names)
+      method_names.each do |method_name|
+        control.send(method_name, &object.method(method_name)) if object.respond_to?(method_name)
+      end
+    end
+    
     private 
     
       def increment_method_count

Modified: MacRuby/trunk/lib/hotcocoa/kvo_accessors.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/kvo_accessors.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/kvo_accessors.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -1,48 +1,48 @@
 class Object
 
-    def self.kvo_array(key, &b)
-        key = key.to_s
-        capitalized_key = key[0].capitalize + key[1..-1]
-        signatures = { :size      => { selector: :"countOf#{capitalized_key}",                  type_signature: "i@:",   flip: false },
-                       :[]        => { selector: :"objectIn#{capitalized_key}AtIndex:",         type_signature: "@@:i",  flip: false },
-                       :insert    => { selector: :"insertObject:in#{capitalized_key}AtIndex:",  type_signature: "v@:@i", flip: true  },
-                       :delete_at => { selector: :"removeObjectFrom#{capitalized_key}AtIndex:", type_signature: "v@:i",  flip: false }
-        }
-        define_methods_with_signatures(signatures, &b)
-    end
+  def self.kvo_array(key, &b)
+    key = key.to_s
+    capitalized_key = key[0].capitalize + key[1..-1]
+    signatures = { :size      => { selector: :"countOf#{capitalized_key}",                  type_signature: "i@:",   flip: false },
+                   :[]        => { selector: :"objectIn#{capitalized_key}AtIndex:",         type_signature: "@@:i",  flip: false },
+                   :insert    => { selector: :"insertObject:in#{capitalized_key}AtIndex:",  type_signature: "v@:@i", flip: true  },
+                   :delete_at => { selector: :"removeObjectFrom#{capitalized_key}AtIndex:", type_signature: "v@:i",  flip: false }
+    }
+    define_methods_with_signatures(signatures, &b)
+  end
 
-    def self.kvo_set(key, &b)
-        key = key.to_s
-        capitalized_key = key[0].capitalize + key[1..-1]
-        signatures = { :add       => { selector: :"add#{capitalized_key}Object:",    type_signature: "v@:@", flip: false },
-                       :delete    => { selector: :"remove#{capitalized_key}Object:", type_signature: "v@:@", flip: false},
-                       :merge     => { selector: :"add#{capitalized_key}:",          type_signature: "v@:@", flip: false },
-                       :subtract  => { selector: :"remove#{capitalized_key}:",       type_signature: "v@:@", flip: false },
-                       :set       => { selector: :"#{key}",                          type_signature: "@@:",  flip: false }
-        }
-        define_methods_with_signatures(signatures, &b)
-    end
+  def self.kvo_set(key, &b)
+    key = key.to_s
+    capitalized_key = key[0].capitalize + key[1..-1]
+    signatures = { :add       => { selector: :"add#{capitalized_key}Object:",    type_signature: "v@:@", flip: false },
+                   :delete    => { selector: :"remove#{capitalized_key}Object:", type_signature: "v@:@", flip: false},
+                   :merge     => { selector: :"add#{capitalized_key}:",          type_signature: "v@:@", flip: false },
+                   :subtract  => { selector: :"remove#{capitalized_key}:",       type_signature: "v@:@", flip: false },
+                   :set       => { selector: :"#{key}",                          type_signature: "@@:",  flip: false }
+    }
+    define_methods_with_signatures(signatures, &b)
+  end
 
-    private
-    def self.define_methods_with_signatures(signatures, &b)
-        c = Module.new
-        c.module_eval &b
-        c.instance_methods.each do |m|
-            signature = signatures[m]
-            if signature
-		method = c.instance_method(m)
-		if signature[:flip]
-		    method = Proc.new { |a, b| method.bind(self).call(b, a)}
-		end
-		c.send(:define_method, signature[:selector], method)
-		c.send(:remove_method, m)
-		c.send(:method_signature, signature[:selector], signature[:type_signature])
-            elsif not Module.instance_methods.include?(m)
-                raise ArgumentError, "Method `#{m}' isn't a KVO accessor"
-            end
-        end
-
-        include c
+  private
+  
+  def self.define_methods_with_signatures(signatures, &b)
+    c = Module.new
+    c.module_eval &b
+    c.instance_methods.each do |m|
+      signature = signatures[m]
+      if signature
+      	method = c.instance_method(m)
+      	if signature[:flip]
+      	  method = Proc.new { |a, b| method.bind(self).call(b, a)}
+      	end
+      	c.send(:define_method, signature[:selector], method)
+      	c.send(:remove_method, m)
+      	c.send(:method_signature, signature[:selector], signature[:type_signature])
+      elsif not Module.instance_methods.include?(m)
+          raise ArgumentError, "Method `#{m}' isn't a KVO accessor"
+      end
     end
+    include c
+  end
 
 end

Modified: MacRuby/trunk/lib/hotcocoa/layout_view.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/layout_view.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/layout_view.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -291,7 +291,7 @@
     raise ArgumentError, "#{subview} is not a subview of #{self} and cannot be removed." unless subview.superview == self
     options[:needs_display] == false ? subview.removeFromSuperviewWithoutNeedingDisplay : subview.removeFromSuperview
   end
-    
+  
   def addSubview(view)
     super
     if view.respond_to?(:layout)

Modified: MacRuby/trunk/lib/hotcocoa/mapper.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mapper.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mapper.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -126,16 +126,25 @@
         unless Mapper.delegate_modules.has_key?(control_class)
           delegate_module = Module.new
           required_methods = []
-          inherited_delegate_methods.each do |delegate_method, mapping|
-            required_methods << delegate_method if mapping[:required]
-          end
-          inherited_delegate_methods.each do |delegate_method, mapping|
-            parameters = mapping[:parameters] ? ", "+mapping[:parameters].map {|param| %{"#{param}"} }.join(",") : ""
+          delegate_methods = inherited_delegate_methods
+          if delegate_methods.size > 0
+            delegate_methods.each do |delegate_method, mapping|
+              required_methods << delegate_method if mapping[:required]
+            end
+            delegate_methods.each do |delegate_method, mapping|
+              parameters = mapping[:parameters] ? ", "+mapping[:parameters].map {|param| %{"#{param}"} }.join(",") : ""
+              delegate_module.module_eval %{
+                def #{mapping[:to]}(&block)
+                  raise "Must pass in a block to use this delegate method" unless block_given?
+                  @_delegate_builder ||= HotCocoa::DelegateBuilder.new(self, #{required_methods.inspect})
+                  @_delegate_builder.add_delegated_method(block, "#{delegate_method}" #{parameters})
+                end
+              }
+            end
             delegate_module.module_eval %{
-              def #{mapping[:to]}(&block)
-                raise "Must pass in a block to use this delegate method" unless block_given?
+              def delegate_to(object)
                 @_delegate_builder ||= HotCocoa::DelegateBuilder.new(self, #{required_methods.inspect})
-                @_delegate_builder.add_delegated_method(block, "#{delegate_method}" #{parameters})
+                @_delegate_builder.delegate_to(object, #{delegate_methods.values.map {|method| ":#{method[:to]}"}.join(', ')})
               end
             }
           end

Modified: MacRuby/trunk/lib/hotcocoa/mappings/alert.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mappings/alert.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mappings/alert.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -20,4 +20,6 @@
     
   end
   
+  delegating "alertShowHelp:", :to => :show_help?
+  
 end

Modified: MacRuby/trunk/lib/hotcocoa/mappings/application.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mappings/application.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mappings/application.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -61,7 +61,7 @@
     def on_quit(menu)
       terminate(menu)
     end
-    
+
     private
     
       def find_menu(menu, path)
@@ -76,5 +76,36 @@
       end
     
   end
+
+  delegating "application:delegateHandlesKey:",                       :to => :delegate_handles_key?,            :parameters => [:delegateHandlesKey]
+  delegating "application:openFile:",                                 :to => :open_file,                        :parameters => [:openFile]
+  delegating "application:openFiles:",                                :to => :open_files,                       :parameters => [:openFiles]
+  delegating "application:openFileWithoutUI:",                        :to => :open_file_without_ui,             :parameters => [:openFileWithoutUI]
+  delegating "application:openTempFile:",                             :to => :open_temp_file,                   :parameters => [:openTempFile]
+  delegating "application:printFile:",                                :to => :print_file
+  delegating "application:printFiles:withSettings:showPrintPanels:",  :to => :print_files
+  delegating "application:willPresentError:",                         :to => :will_present_error
+  delegating "applicationDidBecomeActive:",                           :to => :did_become_active
+  delegating "applicationDidChangeScreenParameters:",                 :to => :did_change_screen_parameters
+  delegating "applicationDidFinishLaunching:",                        :to => :did_finish_launching
+  delegating "applicationDidHide:",                                   :to => :did_hide
+  delegating "applicationDidResignActive:",                           :to => :resign_active
+  delegating "applicationDidUnhide:",                                 :to => :did_unhide
+  delegating "applicationDidUpdate:",                                 :to => :did_update
+  delegating "applicationDockMenu:",                                  :to => :dock_menu
+  delegating "applicationOpenUntitledFile:",                          :to => :open_untitled_file
+  delegating "applicationShouldHandleReopen:hasVisibleWindows:",      :to => :should_handle_reopen?,            :parameters => [:hasVisibleWindows]
+  delegating "applicationShouldOpenUntitledFile:",                    :to => :should_open_untitled_file?
+  delegating "applicationShouldTerminate:",                           :to => :should_terminate?
+  delegating "applicationShouldTerminateAfterLastWindowClosed:",      :to => :should_terminate_after_last_window_closed?
+  delegating "applicationWillBecomeActive:",                          :to => :will_become_active
+  delegating "applicationWillFinishLaunching:",                       :to => :will_finish_launching
+  delegating "applicationWillHide:",                                  :to => :will_hide
+  delegating "applicationWillResignActive:",                          :to => :will_resign_active
+  delegating "applicationWillTerminate:",                             :to => :will_terminate
+  delegating "applicationWillUnhide:",                                :to => :will_unhide
+  delegating "applicationWillUpdate:",                                :to => :will_update
   
+  
+  
 end
\ No newline at end of file

Modified: MacRuby/trunk/lib/hotcocoa/mappings/button.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mappings/button.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mappings/button.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -30,8 +30,7 @@
      :momentary_change    => NSMomentaryChangeButton,
      :on_off              => NSOnOffButton,
      :momentary_push_in   => NSMomentaryPushInButton,
-     :momentary_push      => NSMomentaryPushButton,
-     :momentary_light     => NSMomentaryLight
+     :momentary_push      => NSMomentaryPushButton
   }
 
   constant :state, {

Modified: MacRuby/trunk/lib/hotcocoa/mappings/combo_box.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mappings/combo_box.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mappings/combo_box.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -16,4 +16,9 @@
     
   end
   
+  delegating "comboBoxSelectionDidChange:",   :to => :selection_did_change
+  delegating "comboBoxSelectionIsChanging:",  :to => :selection_is_changing
+  delegating "comboBoxWillDismiss:",          :to => :will_dismiss
+  delegating "comboBoxWillPopUp:",            :to => :will_pop_up
+  
 end

Modified: MacRuby/trunk/lib/hotcocoa/mappings/web_view.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mappings/web_view.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mappings/web_view.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -5,7 +5,7 @@
   def init_with_options(web_view, options)
     web_view.initWithFrame(options.delete(:frame))
   end
-
+  
   custom_methods do
     
     def url=(url)

Modified: MacRuby/trunk/lib/hotcocoa/mappings.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mappings.rb	2009-05-16 14:10:20 UTC (rev 1573)
+++ MacRuby/trunk/lib/hotcocoa/mappings.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -3,7 +3,7 @@
     
     def self.reload
       Dir.glob(File.join(File.dirname(__FILE__), "mappings", "*.rb")).each do |mapping|
-        load mapping
+        require mapping
       end
     end
     

Added: MacRuby/trunk/lib/hotcocoa/mvc.rb
===================================================================
--- MacRuby/trunk/lib/hotcocoa/mvc.rb	                        (rev 0)
+++ MacRuby/trunk/lib/hotcocoa/mvc.rb	2009-05-18 10:32:51 UTC (rev 1574)
@@ -0,0 +1,175 @@
+require 'hotcocoa'
+
+class HotCocoaApplication
+  attr_accessor :shared_application, :application_controller, :controllers
+  
+  include HotCocoa
+  
+  def self.instance=(instance)
+    @instance = instance
+  end
+  
+  def self.instance
+    @instance
+  end
+  
+  def initialize(application_file)
+    HotCocoaApplication.instance = self
+    @controllers = {}
+    load_controllers_and_views(directory_of(application_file))
+    @shared_application = application(ApplicationView.options[:application])
+    @shared_application.load_application_menu
+    @application_controller = controller(:application_controller)
+    shared_application.delegate_to(application_controller)
+  end
+  
+  def start
+    @shared_application.run
+  end
+  
+  def controller(controller_name)
+    controller_name_string = controller_name.to_s
+    controller_class = Object.const_get(controller_name_string !~ /_/ && controller_name_string =~ /[A-Z]+.*/ ? controller_name_string : controller_name_string.split('_').map{|e| e.capitalize}.join)
+    @controllers[controller_name] || create_controller_instance(controller_name, controller_class)
+  end
+  
+  private
+  
+    def create_controller_instance(controller_name, controller_class)
+      controller_instance = controller_class.new(self)
+      @controllers[controller_name] = controller_instance
+      controller_instance.application_window
+      controller_instance
+    end
+    
+    def directory_of(application_file)
+      File.dirname(File.expand_path(application_file))
+    end
+    
+    def load_controllers_and_views(directory)
+      Dir.glob(File.join(directory, 'controllers', '**', '*.rb')).each do |controller_file|
+        load(controller_file)
+      end
+      Dir.glob(File.join(directory, 'views', '**', '*.rb')).each do |view_file|
+        load(view_file)
+      end
+    end
+  
+end
+
+class HotCocoaController
+  
+  def self.view_instances
+    @view_instances ||= {}
+  end
+  
+  attr_reader :application
+  
+  def initialize(application)
+    @application = application
+  end
+  
+  def application_window
+    @application.application_controller.application_window
+  end
+
+end
+
+class HotCocoaApplicationController < HotCocoaController
+  
+  def initialize(application)
+    super(application)
+  end
+  
+  def application_window
+    @application_window ||= ApplicationWindow.new(self).application_window
+  end
+
+end
+
+class HotCocoaWindow
+  
+  attr_reader :application_controller, :application_window
+  
+  def initialize(application_controller)
+    @application_controller = application_controller
+    render
+  end
+  
+  def render
+    @application_window = HotCocoa.window(ApplicationView.options[:window])
+    @application_window.delegate_to(application_controller)
+    @application_window.view << application_controller.application_view
+  end
+  
+end
+
+class HotCocoaView < HotCocoa::LayoutView
+  
+  DefaultLayoutOptions = {:expand => [:width, :height]}
+  
+  module ClassMethods
+    def controller(name=nil)
+      if name
+        @name = name
+      else
+        @name || :application_controller
+      end
+    end
+    def options(options=nil)
+      if options
+        @options = options
+      else
+        @options
+      end
+    end
+  end
+  
+  def self.inherited(klass)
+    klass.extend(ClassMethods)
+    klass.send(:include, HotCocoa::Behaviors)
+    class_name = klass.name.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').tr("-", "_").downcase
+    HotCocoaController.class_eval %{
+      def #{class_name}
+        unless HotCocoaController.view_instances[:#{class_name}]
+          HotCocoaController.view_instances[:#{class_name}] = #{klass.name}.alloc.initWithFrame([0,0,0,0])
+          HotCocoaController.view_instances[:#{class_name}].setup_view
+        end
+        HotCocoaController.view_instances[:#{class_name}]
+      end
+    }, __FILE__, __LINE__
+  end
+  
+  attr_reader :controller
+
+  def setup_view
+    unless @controller
+      @controller = class_controller
+      self.layout = layout_options
+      render
+    end
+  end
+  
+  private
+  
+    def class_controller
+      HotCocoaApplication.instance.controller(self.class.controller)
+    end
+  
+    def layout_options
+      options = if self.class.options && self.class.options[:layout]
+        self.class.options[:layout]
+      else
+        DefaultLayoutOptions
+      end
+    end
+    
+end
+
+class ApplicationWindow < HotCocoaWindow
+  
+end
+
+class Application < HotCocoaApplication
+  
+end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090518/cf752867/attachment-0001.html>


More information about the macruby-changes mailing list