Revision: 799 http://trac.macosforge.org/projects/ruby/changeset/799 Author: eloy.de.enige@gmail.com Date: 2009-01-20 12:09:12 -0800 (Tue, 20 Jan 2009) Log Message: ----------- Apply patch provided in ticket #209; Fix more namespace issues Modified Paths: -------------- MacRuby/trunk/lib/hotcocoa/behaviors.rb MacRuby/trunk/lib/hotcocoa/mapper.rb MacRuby/trunk/lib/hotcocoa/mappings/control.rb MacRuby/trunk/lib/hotcocoa/mappings/layout_view.rb MacRuby/trunk/lib/hotcocoa/mappings/toolbar_item.rb MacRuby/trunk/lib/hotcocoa/mappings.rb MacRuby/trunk/lib/hotcocoa/standard_rake_tasks.rb MacRuby/trunk/lib/hotcocoa.rb Added Paths: ----------- MacRuby/trunk/lib/hotcocoa/object_ext.rb Modified: MacRuby/trunk/lib/hotcocoa/behaviors.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/behaviors.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/behaviors.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -1,7 +1,7 @@ module HotCocoa module Behaviors def Behaviors.included(klass) - Mapper.map_class(klass) + Mappings::Mapper.map_class(klass) end end end \ No newline at end of file Modified: MacRuby/trunk/lib/hotcocoa/mapper.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/mapper.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/mapper.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -1,199 +1,200 @@ -module HotCocoa::Mappings - - class Mapper - - attr_reader :control_class, :builder_method, :control_module - - attr_accessor :map_bindings - - def self.map_class(klass) - new(klass).include_in_class - end - - def self.map_instances_of(klass, builder_method, &block) - new(klass).map_method(builder_method, &block) - end - - def self.bindings_modules - @bindings_module ||= {} - end - - def self.delegate_modules - @delegate_modules ||= {} - end - - def initialize(klass) - @control_class = klass - end - - def include_in_class - @extension_method = :include - customize(@control_class) - end - - def map_method(builder_method, &block) - @extension_method = :extend - @builder_method = builder_method - mod = (class << self; self; end) - mod.extend MappingMethods - mod.module_eval &block - @control_module = mod - inst = self - HotCocoa.send(:define_method, builder_method) do |*args, &control_block| - map = (args.length == 1 ? args[0] : args[1]) || {} - guid = args.length == 1 ? nil : args[0] - map = inst.remap_constants(map) - inst.map_bindings = map.delete(:map_bindings) - default_empty_rect_used = (map[:frame].__id__ == DefaultEmptyRect.__id__) - control = inst.respond_to?(:init_with_options) ? inst.init_with_options(inst.control_class.alloc, map) : inst.alloc_with_options(map) - Views[guid] = control if guid - inst.customize(control) - map.each do |key, value| - if control.respond_to?(key) && value == true - if control.respond_to?("set#{key.to_s.capitalize}") - eval "control.set#{key.to_s.capitalize}(true)" +module HotCocoa + module Mappings + class Mapper + + attr_reader :control_class, :builder_method, :control_module + + attr_accessor :map_bindings + + def self.map_class(klass) + new(klass).include_in_class + end + + def self.map_instances_of(klass, builder_method, &block) + new(klass).map_method(builder_method, &block) + end + + def self.bindings_modules + @bindings_module ||= {} + end + + def self.delegate_modules + @delegate_modules ||= {} + end + + def initialize(klass) + @control_class = klass + end + + def include_in_class + @extension_method = :include + customize(@control_class) + end + + def map_method(builder_method, &block) + @extension_method = :extend + @builder_method = builder_method + mod = (class << self; self; end) + mod.extend MappingMethods + mod.module_eval &block + @control_module = mod + inst = self + HotCocoa.send(:define_method, builder_method) do |*args, &control_block| + map = (args.length == 1 ? args[0] : args[1]) || {} + guid = args.length == 1 ? nil : args[0] + map = inst.remap_constants(map) + inst.map_bindings = map.delete(:map_bindings) + default_empty_rect_used = (map[:frame].__id__ == DefaultEmptyRect.__id__) + control = inst.respond_to?(:init_with_options) ? inst.init_with_options(inst.control_class.alloc, map) : inst.alloc_with_options(map) + Views[guid] = control if guid + inst.customize(control) + map.each do |key, value| + if control.respond_to?(key) && value == true + if control.respond_to?("set#{key.to_s.capitalize}") + eval "control.set#{key.to_s.capitalize}(true)" + else + control.send("#{key}") + end else - control.send("#{key}") + eval "control.#{key}= value" end - else - eval "control.#{key}= value" end + if default_empty_rect_used + control.sizeToFit if control.respondsToSelector(:sizeToFit) == true + end + if control_block + if inst.respond_to?(:handle_block) + inst.handle_block(control, &control_block) + else + control_block.call(control) + end + end + control end - if default_empty_rect_used - control.sizeToFit if control.respondsToSelector(:sizeToFit) == true + self + end + + def inherited_constants + constants = {} + each_control_ancestor do |ancestor| + constants = constants.merge(ancestor.control_module.constants_map) end - if control_block - if inst.respond_to?(:handle_block) - inst.handle_block(control, &control_block) - else - control_block.call(control) + constants + end + + def inherited_delegate_methods + delegate_methods = {} + each_control_ancestor do |ancestor| + delegate_methods = delegate_methods.merge(ancestor.control_module.delegate_map) + end + delegate_methods + end + + def inherited_custom_methods + methods = [] + each_control_ancestor do |ancestor| + methods << ancestor.control_module.custom_methods if ancestor.control_module.custom_methods + end + methods + end + + def each_control_ancestor + control_class.ancestors.reverse.each do |ancestor| + Mappings.mappings.values.each do |mapper| + yield mapper if mapper.control_class == ancestor end end - control end - self - end - - def inherited_constants - constants = {} - each_control_ancestor do |ancestor| - constants = constants.merge(ancestor.control_module.constants_map) + + def customize(control) + inherited_custom_methods.each do |custom_methods| + control.send(@extension_method, custom_methods) + end + decorate_with_delegate_methods(control) + decorate_with_bindings_methods(control) end - constants - end - - def inherited_delegate_methods - delegate_methods = {} - each_control_ancestor do |ancestor| - delegate_methods = delegate_methods.merge(ancestor.control_module.delegate_map) + + def decorate_with_delegate_methods(control) + control.send(@extension_method, delegate_module_for_control_class) end - delegate_methods - end - - def inherited_custom_methods - methods = [] - each_control_ancestor do |ancestor| - methods << ancestor.control_module.custom_methods if ancestor.control_module.custom_methods - end - methods - end - - def each_control_ancestor - control_class.ancestors.reverse.each do |ancestor| - Mappings.mappings.values.each do |mapper| - yield mapper if mapper.control_class == ancestor + + def delegate_module_for_control_class + 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_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 + Mapper.delegate_modules[control_class] = delegate_module end + Mapper.delegate_modules[control_class] end - end - - def customize(control) - inherited_custom_methods.each do |custom_methods| - control.send(@extension_method, custom_methods) + + def decorate_with_bindings_methods(control) + return if control_class == NSApplication + control.send(@extension_method, bindings_module_for_control(control)) if @map_bindings end - decorate_with_delegate_methods(control) - decorate_with_bindings_methods(control) - end - - def decorate_with_delegate_methods(control) - control.send(@extension_method, delegate_module_for_control_class) - end - - def delegate_module_for_control_class - 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] + + def bindings_module_for_control(control) + return Mapper.bindings_modules[control_class] if Mapper.bindings_modules.has_key?(control_class) + instance = if control == control_class + control_class.alloc.init + else + control end - inherited_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}) + bindings_module = Module.new + instance.exposedBindings.each do |exposed_binding| + bindings_module.module_eval %{ + def #{underscore(exposed_binding)}=(value) + if value.kind_of?(Hash) + options = value.delete(:options) + bind "#{exposed_binding}", toObject:value.keys.first, withKeyPath:value.values.first, options:options + else + set#{exposed_binding.capitalize}(value) + end end } end - Mapper.delegate_modules[control_class] = delegate_module + Mapper.bindings_modules[control_class] = bindings_module + bindings_module end - Mapper.delegate_modules[control_class] - end - - def decorate_with_bindings_methods(control) - return if control_class == NSApplication - control.send(@extension_method, bindings_module_for_control(control)) if @map_bindings - end - - def bindings_module_for_control(control) - return Mapper.bindings_modules[control_class] if Mapper.bindings_modules.has_key?(control_class) - instance = if control == control_class - control_class.alloc.init - else - control - end - bindings_module = Module.new - instance.exposedBindings.each do |exposed_binding| - bindings_module.module_eval %{ - def #{underscore(exposed_binding)}=(value) - if value.kind_of?(Hash) - options = value.delete(:options) - bind "#{exposed_binding}", toObject:value.keys.first, withKeyPath:value.values.first, options:options - else - set#{exposed_binding.capitalize}(value) - end + + def remap_constants(tags) + constants = inherited_constants + if control_module.defaults + control_module.defaults.each do |key, value| + tags[key] = value unless tags.has_key?(key) end - } - end - Mapper.bindings_modules[control_class] = bindings_module - bindings_module - end - - def remap_constants(tags) - constants = inherited_constants - if control_module.defaults - control_module.defaults.each do |key, value| - tags[key] = value unless tags.has_key?(key) end - end - result = {} - tags.each do |tag, value| - if constants[tag] - result[tag] = value.kind_of?(Array) ? value.inject(0) {|a, i| a|constants[tag][i]} : constants[tag][value] - else - result[tag] = value + result = {} + tags.each do |tag, value| + if constants[tag] + result[tag] = value.kind_of?(Array) ? value.inject(0) {|a, i| a|constants[tag][i]} : constants[tag][value] + else + result[tag] = value + end end + result end - result + + def underscore(camel_cased_word) + camel_cased_word.to_s.gsub(/::/, '/'). + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + tr("-", "_"). + downcase + end + end - - def underscore(camel_cased_word) - camel_cased_word.to_s.gsub(/::/, '/'). - gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). - gsub(/([a-z\d])([A-Z])/,'\1_\2'). - tr("-", "_"). - downcase - end - end -end +end \ No newline at end of file Modified: MacRuby/trunk/lib/hotcocoa/mappings/control.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/mappings/control.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/mappings/control.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -10,7 +10,7 @@ custom_methods do - include TargetActionConvenience + include HotCocoa::Mappings::TargetActionConvenience def text=(text) setStringValue(text) Modified: MacRuby/trunk/lib/hotcocoa/mappings/layout_view.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/mappings/layout_view.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/mappings/layout_view.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -1,4 +1,4 @@ -Mappings.map :layout_view => :LayoutView do +HotCocoa::Mappings.map :layout_view => :"HotCocoa::LayoutView" do defaults :frame => DefaultEmptyRect, :layout => {} Modified: MacRuby/trunk/lib/hotcocoa/mappings/toolbar_item.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/mappings/toolbar_item.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/mappings/toolbar_item.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -21,7 +21,7 @@ custom_methods do - include TargetActionConvenience + include HotCocoa::Mappings::TargetActionConvenience def priority=(value) setVisibilityPriority(value) Modified: MacRuby/trunk/lib/hotcocoa/mappings.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/mappings.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/mappings.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -30,15 +30,16 @@ framework = options.delete(:framework) mapped_name = options.keys.first mapped_value = options.values.first + const = Object.full_const_get(mapped_value) if mapped_value.kind_of?(Class) m = Mapper.map_instances_of(mapped_value, mapped_name, &block) mappings[m.builder_method] = m - elsif framework.nil? || Object.const_defined?(mapped_value) - m = Mapper.map_instances_of(Object.const_get(mapped_value), mapped_name, &block) + elsif framework.nil? || const + m = Mapper.map_instances_of(const, mapped_name, &block) mappings[m.builder_method] = m else on_framework(framework) do - m = Mapper.map_instances_of(Object.const_get(mapped_value), mapped_name, &block) + m = Mapper.map_instances_of(const, mapped_name, &block) mappings[m.builder_method] = m end end Added: MacRuby/trunk/lib/hotcocoa/object_ext.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/object_ext.rb (rev 0) +++ MacRuby/trunk/lib/hotcocoa/object_ext.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -0,0 +1,21 @@ + +# This is ripped from sam/extlib and changed a little bit. +class Object + + # @param name<String> The name of the constant to get, e.g. "Merb::Router". + # + # @return <Object> The constant corresponding to the name. + def full_const_get(name) + list = name.split("::") + list.shift if list.first.strip.empty? + obj = self + list.each do |x| + # This is required because const_get tries to look for constants in the + # ancestor chain, but we only want constants that are HERE + obj = obj.const_defined?(x) ? obj.const_get(x) : nil + return false unless obj + end + obj + end + +end \ No newline at end of file Modified: MacRuby/trunk/lib/hotcocoa/standard_rake_tasks.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa/standard_rake_tasks.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa/standard_rake_tasks.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -1,11 +1,11 @@ -AppConfig = ApplicationBuilder::Configuration.new("config/build.yml") +AppConfig = HotCocoa::ApplicationBuilder::Configuration.new("config/build.yml") task :deploy => [:clean] do - ApplicationBuilder.build(AppConfig, :deploy => true) + HotCocoa::ApplicationBuilder.build(AppConfig, :deploy => true) end task :build do - ApplicationBuilder.build(AppConfig) + HotCocoa::ApplicationBuilder.build(AppConfig) end task :run => [:build] do Modified: MacRuby/trunk/lib/hotcocoa.rb =================================================================== --- MacRuby/trunk/lib/hotcocoa.rb 2009-01-20 14:49:31 UTC (rev 798) +++ MacRuby/trunk/lib/hotcocoa.rb 2009-01-20 20:09:12 UTC (rev 799) @@ -6,6 +6,8 @@ end +require 'hotcocoa/object_ext' +require 'hotcocoa/kernel_ext' require 'hotcocoa/mappings' require 'hotcocoa/behaviors' require 'hotcocoa/mapping_methods' @@ -15,7 +17,6 @@ require 'hotcocoa/notification_listener' require 'hotcocoa/data_sources/table_data_source' require 'hotcocoa/data_sources/combo_box_data_source' -require 'hotcocoa/kernel_ext' require 'hotcocoa/plist' require 'hotcocoa/kvo_accessors' require 'hotcocoa/attributed_string'