I''ve got most of the form designer working ok now, so I''m going to start working on the MSBuild, project & item integration. However, I''ve got a couple of problems/questions. 1) IronRuby doesn''t like the delegate op assign so I can''t click on a button 2) I really need ''attr_accessor'' to define a ''field'' (it''s commented out below and I''ve worked round it, but it''s a pain to do). Does it exist yet? 3) the references use the full qualified reference name. I can live with this no problem, but it really should use the short form. Is this on the road map? Here''s the code for a simple form: require ''System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL'' require ''System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86'' require ''System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL'' require ''System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL'' class Form1123 < System::Windows::Forms::Form #attr_accessor :button1 def button1=(v) @button1 = v end def button1 @button1 end def InitializeComponent self.button1 = System::Windows::Forms::Button.new() self.SuspendLayout() # # button1 # self.button1.Location = System::Drawing::Point.new(220, 91) self.button1.Name = "button1" self.button1.Size = System::Drawing::Size.new(198, 42) self.button1.TabIndex = 0 self.button1.Text = "button1" self.button1.Click += System::EventHandler.new(self.button1_Click) # # Form1123 # self.ClientSize = System::Drawing::Size.new(600, 400) self.Controls.Add(self.button1) self.Name = "Form1123" self.ResumeLayout(false) end end Apart from the ''Click'' everything else works fine. Thanks, Dermot -- Posted via http://www.ruby-forum.com/.
Dermot Hogan:> I''ve got most of the form designer working ok now, so I''m going to > start > working on the MSBuild, project & item integration. However, I''ve got a > couple of problems/questions.Excellent!> 1) IronRuby doesn''t like the delegate op assign so I can''t click on a > buttonWe only support: self.button1.click do |sender, args| # code end today.> 2) I really need ''attr_accessor'' to define a ''field'' (it''s commented > out > below and I''ve worked round it, but it''s a pain to do). Does it exist > yet?We''re working on this - it should be almost doable today.> 3) the references use the full qualified reference name. I can live > with > this no problem, but it really should use the short form. Is this on > the > road map?What I''ve been doing is assembling these references into a .rb file that I require - eg require ''winforms''. Thanks & great job! -John
> >> 1) IronRuby doesn''t like the delegate op assign so I can''t click on a >> button > > We only support: > > self.button1.click do |sender, args| > # code > end > > today. >OK. The Form Designer requires that you add a delegate (at least I think it does. I haven''t found a simple way supporting the above syntax). Everything else C#, VB, IronPython, etc use the += syntax.>> 2) I really need ''attr_accessor'' to define a ''field'' (it''s commented >> out >> below and I''ve worked round it, but it''s a pain to do). Does it exist >> yet? > > We''re working on this - it should be almost doable today. >OK. That''s good.>> 3) the references use the full qualified reference name. I can live >> with >> this no problem, but it really should use the short form. Is this on >> the >> road map? > > What I''ve been doing is assembling these references into a .rb file that > I require - eg require ''winforms''. >I can actually get the fully qualified name from the VS Add References system, so it''s not a problem. It''s not urgent by any means - it just looks odd. Another minor problem is that I have to use syntax like this: System::Windows::Forms::Application.EnableVisualStyles() System::Windows::Forms::Application.SetCompatibleTextRenderingDefault(false); even with the require ''System::Windows::Forms'' Any way of shortening this? Also (a more general question) - will IR compile to a PE? I''m assuming that it runs similarly to MRuby right now (i.e as an interpreter), but I need to build certain assumptions into the things MSBuild knows about. If it''s going to compile, then I''ll make sure MSBuild knows about it. Don''t bend your development plans to accomodate me, btw. I can see that there''s plenty to work on before getting the finer points of the Form Designer. Still, I can see impressive progress! Dermot -- Posted via http://www.ruby-forum.com/.
I battled many of these issues in developing the VS package (including forms designer) for Ruby.NET. You can check out a complete version from http://rubydotnetcompiler.googlecode.com/svn/trunk/src/VisualStudioPackage/ There may be still be some bugs, but it basically works. Some of the code in our InitializeComponent is a little un Ruby like but it was done to achieve perfect round-trip-ability. Perhaps we could collaborate more closely on the VS integration challenges for Ruby? I''m certainly happy to have one-on-one conversations with anyone working on this part of the project. Cheers, Wayne. FYI, the code that we would generate in that scenario is as follows: require ''mscorlib.dll'' require ''System.dll'' require ''System.Drawing.dll'' require ''System.Windows.Forms.dll'' class Form1 < System::Windows::Forms::Form def initialize self.InitializeComponent end attr_accessor :button1 def InitializeComponent() @button1 = System::Windows::Forms::Button.new() self.SuspendLayout() # # button1 # @button1.set_Location(System::Drawing::Point.new(47, 54)) @button1.set_Name(''button1'') @button1.set_Size(System::Drawing::Size.new(75, 23)) @button1.set_TabIndex(0) @button1.set_Text(''button1'') @button1.set_UseVisualStyleBackColor(true) @button1.add_Click(System::EventHandler.new { |*args| self.button1_Click(*args)}) # # Form1 # self.set_ClientSize(System::Drawing::Size.new(292, 266)) self.get_Controls().Add(@button1) self.set_Name(''Form1'') self.ResumeLayout(false) end def button1_Click(sender,e) end end
1) I think we could support += for events - seems to be quite easy to plug into our infrastructure. This is a model how I think it could work: class Form def initialize @click = Event.new end def click puts "TRACE: Click" @click end def click=(x) puts "TRACE: Click=#{x.inspect}" if x.instance_of? MethodHolder then @click.add(x.method) else @click.set(x) end end end class MethodHolder attr :method def initialize(m) @method = m end end class Event def initialize @methods = [] end def +(m) puts "TRACE: +(#{m.inspect}" MethodHolder.new(m) end def call @methods.each { |m| m.call } end def add(m) @methods << m end def set(m) @methods = [m] end end def bar puts ''hello'' end def baz puts ''world'' end form = Form.new form.click += method(:bar) form.click += method(:baz) form.click.call So if you guys don''t have objections, I would add it to my TODO list. Tomas -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Dermot Hogan Sent: Wednesday, October 24, 2007 2:47 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Form Designer adding delegates> >> 1) IronRuby doesn''t like the delegate op assign so I can''t click on a >> button > > We only support: > > self.button1.click do |sender, args| > # code > end > > today. >OK. The Form Designer requires that you add a delegate (at least I think it does. I haven''t found a simple way supporting the above syntax). Everything else C#, VB, IronPython, etc use the += syntax.>> 2) I really need ''attr_accessor'' to define a ''field'' (it''s commented >> out >> below and I''ve worked round it, but it''s a pain to do). Does it exist >> yet? > > We''re working on this - it should be almost doable today. >OK. That''s good.>> 3) the references use the full qualified reference name. I can live >> with >> this no problem, but it really should use the short form. Is this on >> the >> road map? > > What I''ve been doing is assembling these references into a .rb file that > I require - eg require ''winforms''. >I can actually get the fully qualified name from the VS Add References system, so it''s not a problem. It''s not urgent by any means - it just looks odd. Another minor problem is that I have to use syntax like this: System::Windows::Forms::Application.EnableVisualStyles() System::Windows::Forms::Application.SetCompatibleTextRenderingDefault(false); even with the require ''System::Windows::Forms'' Any way of shortening this? Also (a more general question) - will IR compile to a PE? I''m assuming that it runs similarly to MRuby right now (i.e as an interpreter), but I need to build certain assumptions into the things MSBuild knows about. If it''s going to compile, then I''ll make sure MSBuild knows about it. Don''t bend your development plans to accomodate me, btw. I can see that there''s plenty to work on before getting the finer points of the Form Designer. Still, I can see impressive progress! Dermot -- Posted via http://www.ruby-forum.com/. _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core
Actually, Ruby already has an in-place addition operator for arrays: <<. So another way of hooking could be: form.click << method(:bar) We can alias/rename :add to :push and :remove to :delete for better consistency with Ruby Array class method names. Of course, we can provide all three ways and let the user choose whatever she likes. Tomas -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Tomas Matousek Sent: Wednesday, October 24, 2007 7:47 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Form Designer adding delegates 1) I think we could support += for events - seems to be quite easy to plug into our infrastructure. This is a model how I think it could work: class Form def initialize @click = Event.new end def click puts "TRACE: Click" @click end def click=(x) puts "TRACE: Click=#{x.inspect}" if x.instance_of? MethodHolder then @click.add(x.method) else @click.set(x) end end end class MethodHolder attr :method def initialize(m) @method = m end end class Event def initialize @methods = [] end def +(m) puts "TRACE: +(#{m.inspect}" MethodHolder.new(m) end def call @methods.each { |m| m.call } end def add(m) @methods << m end def set(m) @methods = [m] end end def bar puts ''hello'' end def baz puts ''world'' end form = Form.new form.click += method(:bar) form.click += method(:baz) form.click.call So if you guys don''t have objections, I would add it to my TODO list. Tomas -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Dermot Hogan Sent: Wednesday, October 24, 2007 2:47 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Form Designer adding delegates> >> 1) IronRuby doesn''t like the delegate op assign so I can''t click on a >> button > > We only support: > > self.button1.click do |sender, args| > # code > end > > today. >OK. The Form Designer requires that you add a delegate (at least I think it does. I haven''t found a simple way supporting the above syntax). Everything else C#, VB, IronPython, etc use the += syntax.>> 2) I really need ''attr_accessor'' to define a ''field'' (it''s commented >> out >> below and I''ve worked round it, but it''s a pain to do). Does it exist >> yet? > > We''re working on this - it should be almost doable today. >OK. That''s good.>> 3) the references use the full qualified reference name. I can live >> with >> this no problem, but it really should use the short form. Is this on >> the >> road map? > > What I''ve been doing is assembling these references into a .rb file that > I require - eg require ''winforms''. >I can actually get the fully qualified name from the VS Add References system, so it''s not a problem. It''s not urgent by any means - it just looks odd. Another minor problem is that I have to use syntax like this: System::Windows::Forms::Application.EnableVisualStyles() System::Windows::Forms::Application.SetCompatibleTextRenderingDefault(false); even with the require ''System::Windows::Forms'' Any way of shortening this? Also (a more general question) - will IR compile to a PE? I''m assuming that it runs similarly to MRuby right now (i.e as an interpreter), but I need to build certain assumptions into the things MSBuild knows about. If it''s going to compile, then I''ll make sure MSBuild knows about it. Don''t bend your development plans to accomodate me, btw. I can see that there''s plenty to work on before getting the finer points of the Form Designer. Still, I can see impressive progress! Dermot -- Posted via http://www.ruby-forum.com/. _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core
Tomas Matousek:> Actually, Ruby already has an in-place addition operator for arrays: > <<. > > So another way of hooking could be: > > form.click << method(:bar) > > We can alias/rename :add to :push and :remove to :delete for better > consistency with Ruby Array class method names. > > Of course, we can provide all three ways and let the user choose > whatever she likes.For consistency, we should also let the user remove delegates as well via -=. But other than that, it looks good and feels rather Rubyish. -John
Wayne Kelly:> require ''mscorlib.dll'' > require ''System.dll'' > require ''System.Drawing.dll'' > require ''System.Windows.Forms.dll''I''m a bit surprised at the use of assembly filenames vs. assembly names here - what''s the resolution order for these assemblies? Do they need to be on the path?> @button1.set_Location(System::Drawing::Point.new(47, 54))Is there a reason why you''re calling the property setter method explicitly rather than using the property name? Or is this not supported in the Ruby.Net method binder? Thanks, -John
> -----Original Message----- > From: ironruby-core-bounces at rubyforge.org > [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of > John Lam (DLR) > Sent: Thursday, 25 October 2007 1:57 PM > To: ironruby-core at rubyforge.org > Subject: Re: [Ironruby-core] Form Designer adding delegates > > Wayne Kelly: > > > require ''mscorlib.dll'' > > require ''System.dll'' > > require ''System.Drawing.dll'' > > require ''System.Windows.Forms.dll'' > > I''m a bit surprised at the use of assembly filenames vs. > assembly names hereDon''t all ruby requires expect a file name? We haven''t changed the lookup mechanism for loading - we just allowed .NET dlls to also be loaded.> Do they need to be on the path?They need to be on Ruby''s path, but we automatically add the Microsoft.NET framework directory to that Path.> > @button1.set_Location(System::Drawing::Point.new(47, 54)) > > Is there a reason why you''re calling the property setter > method explicitly rather than using the property name? Or is > this not supported in the Ruby.Net method binder?Our compiler would be happy with it as a property assignment, but we did it that way inside InitializeComponent in order to ensure round tripping. When parsing InitializeComponent and generating the codeDOM representation we need to distinguish between a field, a property and a method call. Statically typed languages are expected to use type information to distinguish. As we have no type information we use syntactic conventions to distinguish between them. Note - these syntactic conventions only apply within the InitializeComponent method which is typically auto-generated. Ruby programmers are free to use the more Rubyish syntax elsewhere in their code. Another issue is statically distinguishing between variables such as Foo and type references such as System::Drawing::Point - we use wrapper/helper methods to distinguish type references (except when invoking a new method where we implicitly assume that the constant is a type reference). Again, this is only necessary inside IntializeComponent. And now a question for your VS integration experts: when adding a new event handler - how do you arrange for the cursor to be automatically placed inside the body of the new method? Cheers, Wayne.
Tomas Matousek wrote:> Actually, Ruby already has an in-place addition operator for arrays: <<. > > So another way of hooking could be: > > form.click << method(:bar) > > We can alias/rename :add to :push and :remove to :delete for better > consistency with Ruby Array class method names. > > Of course, we can provide all three ways and let the user choose > whatever she likes. > > TomasThis looks reasonably promising in the short term. I''ll try implementing this in Ruby. All I need is some syntax that won''t be rejected by IronRuby and that hooks up a delegate type thing to the object. The FormDesigner doesn''t care if it''s ''+='' or ''<<'' Dermot -- Posted via http://www.ruby-forum.com/.
John Lam (DLR) wrote:> > For consistency, we should also let the user remove delegates as well > via -=. But other than that, it looks good and feels rather Rubyish.Thta''s actually quite important (though not for the FormDesigner). I do add and remove delegates, fo example, when loading assemblies. Not often, I admit, but I do use them. Dermot -- Posted via http://www.ruby-forum.com/.
Wayne Kelly wrote:>> > @button1.set_Location(System::Drawing::Point.new(47, 54)) >> >> Is there a reason why you''re calling the property setter >> method explicitly rather than using the property name? Or is >> this not supported in the Ruby.Net method binder? > > Our compiler would be happy with it as a property assignment, but we did > it that way inside InitializeComponent in order to ensure round > tripping. When parsing InitializeComponent and generating the codeDOM > representation we need to distinguish between a field, a property and a > method call. Statically typed languages are expected to use type > information to distinguish. As we have no type information we use > syntactic conventions to distinguish between them. Note - these > syntactic conventions only apply within the InitializeComponent method > which is typically auto-generated. Ruby programmers are free to use the > more Rubyish syntax elsewhere in their code. >You don''t need to do this, I think. You can work out from the context what is a field, a property and a call. I did have some initial trouble distinguishing between a Property (System.Windows.Form.BackColor.Red) and an enum (System.Windows.Form.BorderStyle.Sizable) - but it worked out ok.> Another issue is statically distinguishing between variables such as Foo > and type references such as System::Drawing::Point - we use > wrapper/helper methods to distinguish type references (except when > invoking a new method where we implicitly assume that the constant is a > type reference). Again, this is only necessary inside > IntializeComponent. >I didn''t have that problem. But what I did have a problem with was something like this (from a TreeNode control): treeNode3 = System::Windows::Forms::TreeNode.new(''Node0'', [treeNode1, treeNode2]) Here, the FormDesigner needs to know the type of the array - which Ruby of course doesn''t give you. That took a bit of time to get right.> > And now a question for your VS integration experts: when adding a new > event handler - how do you arrange for the cursor to be automatically > placed inside the body of the new method? >I''m sure there are several ways to do this, but this is what I did: 1) I have two files - the form code file and the designer file (as in C#). In the CodeDomProvider, I override the Parse method and *before* I parse the designer file to generate the CodeDom, I scan the form file looking for event handlers. I use regexps to do this - I don''t bother Ruby parsing the form file at all. I then build a list containing the names and positions of any event handlers. 2) I then Ruby parse (using Antlr) the designer file and generate the CodeDom from that. When a delegate is required I do something like this: CodeMemberMethod cmm = new CodeMemberMethod(); cmm.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "sender")); cmm.Parameters.Add(new CodeParameterDeclarationExpression(typeof(System.EventArgs), "e")); cmm.Name = eventHandlerName; // let the provider process adding the event handler int line = _provider.AddEventHandler(eventHandlerName); cmm.UserData.Add(typeof(Point), new Point(0, line + 1)); The AddEventHandler method does the business of finding any event handler in the form code, generating it if required (again in the form code - not the designer code) and returning its position. The last bit is the code that lets the FormDesigner know where the event handler is when you double click on the control in the form. Something similar happems when you drop a new control on the form. Splitting the form code from the designer makes life a whole lot simpler and the coding is then clear and unambiguous. And most importantly from my point of view, it''s easily maintainable. Dermot -- Posted via http://www.ruby-forum.com/.