= Porting wxWidgets wx.NET C# source file to cobra = The .NET wrapper library ([http://wxnet.sourceforge.net wx.NET]) for [http://www.wxwidgets.org wxWidgets] is an interesting case for cobra since it is one of the few .NET libraries that uses a lowercase namespace.[[br]] Consequently there are some complications with persuading cobra to work with it conveniently. see [wiki:C#Diffs Cobra differences fm C#] Heres a process for C# generally with some notes re wx.NET generated from converting wx.NET sample file ListView.cs to ListView.cobra 1 Take .cs file, rename to .cobra file 2. Change multiline comments from multiple // or /* */ bounded to be /# #/ bounded.[[br]] Change single line comments to use leading '#' Remove extraneous separator line comments between method calls // ------------------------------ 3. Remove trailing ';' from each line they occur on 4. Fixup blocking and indentation. Remove all '{' and '}' indicating start and end blocks from source.[[br]] Ensure remaining blocks are all correctly (equally) indented and that indentation uses either all spaces or all Tabs and that the indents are in multiples of either 4 spaces or 1 tab. 5. Fix 'using' statements ''''using'''' -> ''''use''''' Remove any lines for {{{ using System using System.Collections.Generic using System.IO using System.Text }}} as cobra includes these automagically Change any other lines from ''''using xxxx;'''' to ''''use xxxx'''' You also need to specify to use the C# wrapper library/namespace for wxWidgets (''''wx''''). Before ''''use System.Drawing'''' add a ''''use .. from line'''' for wx.NET {{{ use wx from "wx.NET" use System.Drawing }}} or add an explicit compiler directive ref line and a 'use wx' line {{{ @ref "wx.NET" ... use wx use System.Drawing }}} 5. Namespace decl Namespaces in cobra need to start with an upcased letter. Remove any ''''wx.'''' prefix from namespace line ; ''''namespace wx.Something'''' to ''''namespace Something'''' 5a. Correct any Enum definitions After applying the above its basically removing trailing ',' and ensuring indentation of enum items is the same e.g. {{{ enum Cmd { About, Quit, Dialog } -> enum Cmd About Quit Dialog enum ID_CONTROLS { ID_RADIO_ORIENT = 5999, ID_CHK_SHOWIMAGES, ID_BTN_NEXT_PAGE, ID_NOTEBOOK } -> enum ID_CONTROLS ID_RADIO_ORIENT = 5999 ID_CHK_SHOWIMAGES ID_BTN_NEXT_PAGE ID_NOTEBOOK }}} 6. Fix class declaration syntax Change lines like ''''class X : Y'''' to ''''class X inherits Y'''' 7. Change any class instance attributes/fields to be prefixed with ''''var'''' change type and accessmodifier to cobra forms {{{ name = ; --> var name as = }}} 8. Fixup class constructor definitions For initializer/constructor change lines like ''''public !ClassName(params,...) : base(baseParams,...)'''' to ''''cue init(params, ...) is public''' '''base.init(baseParams,...)'''' within the params list correct type declaration syntax from C# to cobra ''''[ ...] name,' -> ''''name as [is , ...],'''' public is default accessmodifier so can leave that off e.g. {{{ public ListViewFrame (string title, Point pos, Size size) : base(title, pos, size) -> cue init(title as String, pos as Point, size as Size ) is public base.init (title, pos, size) }}} 9. Remove any uses of ''''new'''' to construct a class instance, instead just make a call to the class type passing any initializer args, i.e just remove 'new' e.g. {{{ menuFile = new Menu() -> menuFile = Menu() new Point(10, 100) -> Point(10, 100) new Size(650,340) -> Size(650, 340) }}} For classes that construct delegates (take method names) prefix the methodname with '''ref''', methodNames must start with a lowercase letter and are prefixed by ''''this.'''' or just ''''.'''' so change the methodName accordingly e.g. {{{new EventListener( OnAbout ) -> EventListener( ref .onAbout ) }}} 10. Methods: Prefix methods with '''def''' Change methodnames to start with a lowercase letter, Change param definitions to cobra form. ''''[ ...] name,'''' -> ''''name as [is , ...],'''' Cobra methods by default return void and are public so if the C# code specifies ''''public void''' you can just delete those words. Also, if a method has no parameters then the empty trailing () can be left off. Note builtin types: C# string -> String C# object -> Object - Theres a twist though; wx.NET also defines an Object (wx.Object) so that if you just declare something of Type Object theres a resolution ambiguity message is 'Ambiguous reference "Object" found in namespaces "System" and "wx"' so you have to either rely on the dynamic typing or resolve the ambiguity by specifying the namespace to use e.g. {{{ public void OnAbout( object sender, Event e ) -> def onAbout(sender as System.Object, e as Event) # OR def onAbout(sender, e as Event) # untyped arg defaults to dynamic # no param method public override bool OnInit() -> def onInit as bool is override # or def onInit as bool is public, override # explicit }}} 11. Calls to methods, properties and attributes/fields Instance method names, properties and fields are called with a prefix of ''''this.'''' or just ''''.'''' and they all must be named starting with a lowercase letter so these calls and settings must be modified accordingly. e.g. {{{ menuFile.AppendWL(... -> menuFile.appendWL( ... CreateStatusBar() -> .createStatusBar # or this.createStatusBar }}} Similarly with properties and fields {{{ TextCtrl = TextCtrl(this, ... -> .textCtrl = TextCtrl(this, ... MenuBar = menuBar -> .menuBar = menuBar Log.SetActiveTarget( textCtrl ) -> Log.setActiveTarget(.textCtrl) # static class }}} If a method takes no args then any empty trailing () on a method call can/should be left off. 12. Property definition depending on the property use, prefix properties with get - readable property only set - setable property only pro - getable and setable Change property names to start with a lowercase letter 13. Local variables declared and assigned on first use can usually be changed to remove the type definition (type inferred from the assignment) or can continue to be explicitly typed (if that compiles). {{{ ListItem info = new ListItem() -> info = ListItem # or info as ListItem = ListItem() }}} Heres a composite example {{{ // C# ListItem itemCol = new ListItem(); itemCol.Text = "Second Column"; itemCol.Align = ListCtrl.wxLIST_FORMAT_CENTER; itemCol.Width = 300; InsertColumn( 1, itemCol ); -> # Cobra itemCol = ListItem() itemCol.text = "Second Column" itemCol.align = ListCtrl.wxLIST_FORMAT_CENTER itemCol.width = 300 .insertColumn(1, itemCol) }}} 12. Fixup 'For' loops {{{ for ( name = start ; name < stop; ++name ) -> for name as Type in start : stop : 1 # explicit or equally use shortcuts: for name in start : stop : 1 for name in start : stop # if step is one (1) for name in stop # if start is zero (0) and step is one (1) # same as for name in 0 : stop : 1 }}} e.g {{{ for ( int i = 0; i < 200; ++i ) -> for i in 0 : 200 }}} 13. Casting Casts of form '(Type)name' become 'name to Type' e.g. {{{ mf.AppendWL( (int)Cmd.About,... -> mf.appendWL(Cmd.About to int,... }}} Casts of form 'a as Type' can also become 'name to Type' or 'name to? Type' e.g {{{ ListEvent le = e as ListEvent; -> le = e to ListEvent }}} 14. String catenated with an expression (converted to string) Put the expression (cobra converted) in the string inside [] e.g. {{{ "Value 1st field of selected item: " + le.Text -> "Value 1st field of selected item: [le.text]" }}} 15. Adding eventHandlers Cobra uses the *listen* statement to register eventhandlers where C# uses an override on the += operator. WxWidgets wraps method calls in an EventHandler class instance. Otherwise normal cobra mapping for method names and reference to methods (vs method calls) apply; Methodnames in Cobra must start with lower case and calls to this instance names are prefixed with ''''this.'''' or (easier) ''''.'''' When translating from a 'use'd library namespace, calls to Capcased methodnames are referenced in cobra with the first '''char''' lowercased, Upcased methodnames are referenced with the first '''word''' lowercased so {{{ EVENT += EventListener( MethodName ) in C# becomes listen .EVENT, EventListener( ref .methodName ) EVENT += EventListener( EH_METHOD_NAME ) in C# becomes listen .EVENT, EventListener( ref .eh_METHOD_NAME ) }}} e.g. {{{ ColumnClick += EventListener( OnColumnClick ) ItemSelect += EventListener( OnItemSelect ) ColumnRightClick += EventListener( OnColumnRightClick ) -> listen .columnClick, EventListener(ref .onColumnClick) listen .itemSelect, EventListener(ref .onItemSelect ) listen .columnRightClick, EventListener(ref .onColumnRightClick) }}} !WxWidets menu action handlers can be done in C# using call to EVT_MENU. {{{EVT_MENU((int)MENU_ENUM_VALUE, new EventListener(MethodName)); }}} the equivalent in cobra becomes {{{.evt_MENU(MENU_ENUM_VALUE to int, new EventListener(ref .methodName))}}} e.g. {{{ EVT_MENU((int)Cmd.Quit, new EventListener(OnQuit)); EVT_MENU((int)Cmd.Dialog, new EventListener(OnDialog)); EVT_MENU((int)Cmd.About, new EventListener(OnAbout)); }}} -> {{{ .evt_MENU(Cmd.Quit to int, EventListener(ref .onQuit)) .evt_MENU(Cmd.Dialog to int, EventListener(ref .onDialog)) .evt_MENU(Cmd.About to int, EventListener(ref .onAbout)) }}} 16. Main method public void is default, static is an accessmodifier becomes ''''shared'''' in cobra, C# attributes (!MetaInformation) are denoted with ''''has'''' e.g. {{{ [STAThread] static public void main() -> def main is shared has STAThread }}} 17. Lowercased namespace names (as in wx.NET) used to disambiguate or otherwise explicitly specify the namespace on types (inherits ..., as ....) as opposed to methods or constants can (may/will) generate compile errors of the form ''''error: Cannot find type for "wx.TYPE".''''[[br]] e.g. error: Cannot find type for "wx.Frame". If such occurs the only recourse is to remove the explicit typing and rely on default handling e.g. {{{ use wx from "wx.NET" namespace SampleMinimal class MyFrame inherits wx.Frame # file.cobra(3): error: Cannot find type for "wx.Frame". #Change to use wx from "wx.NET" namespace SampleMinimal class MyFrame inherits Frame }}} {{{ def onAbout(sender as System.Object, e as wx.Event ) }}} # Change to {{{ def onAbout(sender as System.Object, e as Event ) }}} {{{ fileMenu as wx.Menu = wx.Menu() # Change to fileMenu = Menu() }}} Eventually it would be preferable if cobra became a little more flexible in these cases.. Other weirdnesses As of this doc date (Oct 2009) the wx.NET version and cobra seem to not be able to find some properties, specifically[[br]] Frame.Icon, .icon property -> no workaround [[br]] Frame.!StatusBar, .statusBar text property -> use method .setStatusBar(text) instead[[br]]