From: Jonathan P. <jp...@dc...> - 2005-04-12 09:39:11
Attachments:
ObjcID.rb
|
Hi, After following the instructions on the FAQ [1], with a few fiddles, I have got Cocoa bindings on a Ruby object to work well. Please let me know what you think of these modifications - if they seem ok I'll try to update the Wiki FAQ page. The main thing I wanted to support was notification from Ruby to Cocoa upon changing a value in Ruby. I created the NSObject+RubyCocoaBindings.[mh] and ObjcID.rb files, adjusting the latter slightly. I've attached the modified ObjcID.rb file to this message. The result is a model object like this: class MyModel < OSX::NSObject kvc_accessor :name, :title end The kvc_accessor meta-method takes care of wrapping the setter (key=) with the Cocoa bindings notifications. If the setter is already defined, it will be wrapped by the kvc_accessor: class MyModel < OSX::NSObject def foo=(value) @foo = value @foo_parsed = ... # do some parsing of foo end kvc_accessor :foo # wraps foo= with notification, also defines foo reader method end Now, in other code, if you do 'model.foo = "Something"', any GUI objects bound will automatically update. Thanks Jonathan [1] http://rubycocoa.sourceforge.net/w.en/FAQ.html |
From: kimura w. <ki...@us...> - 2005-04-26 15:09:28
|
Hi, I'm sorry my reply is too late. Tue, 12 Apr 2005 10:38:50 +0100, Jonathan Paisley wrote: >Hi, > >After following the instructions on the FAQ [1], with a few fiddles, I >have got Cocoa bindings on a Ruby object to work well. Please let me >know what you think of these modifications - if they seem ok I'll try >to update the Wiki FAQ page. > >The main thing I wanted to support was notification from Ruby to Cocoa >upon changing a value in Ruby. > >The kvc_accessor meta-method takes care of wrapping the setter (key=) >with the Cocoa bindings notifications. If the setter is already >defined, it will be wrapped by the kvc_accessor: > > class MyModel < OSX::NSObject > def foo=(value) > @foo = value > @foo_parsed = ... # do some parsing of foo > end > > kvc_accessor :foo # wraps foo= with notification, also defines foo >reader method > end > >Now, in other code, if you do 'model.foo = "Something"', any GUI >objects bound will automatically update. > It's cool! If you allow, I will add kvc_accessor to RubyCocoa. btw, Module#method_added enables to hook method definition. Following code reverts a wrapper of a setter when the setter is overrided. module NSBehaviorAttachment def kvc_accessor(*keys) # define setter if needed # alias setter to internal setter # define wrapper # alias wrapper to setter end def kvc_internal_setter(key) # returns wrapped setter name end def kvc_setter_wrapper(key) # returns wrapper name end def method_added(sym) return unless sym.to_s =~ /([^=]+)=\z/ key = $1 setter = kvc_internal_setter(key) wrapper = kvc_setter_wrapper(key) return unless method_defined?(setter) && method_defined?(wrapper) # do not re-alias wrapper return if self.instance_method(wrapper) == self.instance_method(sym) # re-alias wrapper to setter alias_method sym, wrapper end end -- kimura wataru |
From: Jonathan P. <jp...@dc...> - 2005-04-28 07:57:50
Attachments:
addRubyMethod_withType.patch
ObjcID.rb
|
On 26 Apr 2005, at 16:08, kimura wataru wrote: > I'm sorry my reply is too late. No problem at all. > It's cool! If you allow, I will add kvc_accessor to RubyCocoa. Yes, please do. > btw, Module#method_added enables to hook method definition. Following > code reverts a wrapper of a setter when the setter is overrided. > [snip code] Ah! Looks good. I will try it out. I've attached a patch to this message that extends the base Ruby-Cocoa bridge class methods. addRubyMethod_withType allows creation of an actual ObjC method corresponding to a ruby method. This means that key-value coding will be able to find the actual method when it does a lookup. This could be used to define real accessor methods (therefore avoiding the valueForUndefinedKey hook), or for implementing array accessors (which have no such hook). For example: def kvc_array_accessor(*args) kvc_accessor(*args) args.each do |v| n = v.to_s n[0..0] = n[0..0].upcase self.addRubyMethod_withType("countOf#{n}".to_sym,"i4@8:12") self.addRubyMethod_withType("objectIn#{n}AtIndex_".to_sym,"@4@8:12i16") self.addRubyMethod_withType("insertObject_in#{n}AtIndex_".to_sym,"@4@8: 12@16i20") self.addRubyMethod_withType("removeObjectFrom#{n}AtIndex_".to_sym,"@4@8: 12i16") # ... I've attached an updated version of ObjcID that has the full implementation of this method. Thanks Jonathan |
From: kimura w. <ki...@us...> - 2005-06-07 14:53:22
|
Hi, This patch was merged to CVS HEAD. Thanks! Thu, 28 Apr 2005 08:57:07 +0100, Jonathan Paisley wrote: >I've attached a patch to this message that extends the base Ruby-Cocoa >bridge class methods. addRubyMethod_withType allows creation of an >actual ObjC method corresponding to a ruby method. This means that >key-value coding will be able to find the actual method when it does a >lookup. > >This could be used to define real accessor methods (therefore avoiding >the valueForUndefinedKey hook), or for implementing array accessors >(which have no such hook). For example: > > def kvc_array_accessor(*args) > kvc_accessor(*args) > args.each do |v| > n = v.to_s > n[0..0] = n[0..0].upcase > self.addRubyMethod_withType("countOf#{n}".to_sym,"i4@8:12") > -- kimura wataru |