Version 1 (modified by hopscc, 15 years ago) |
---|
Porting wxWidgets wx.NET C# source file to cobra
The .NET wrapper library ( wx.NET) for wxWidgets is an interesting case for cobra since it is one of the few .NET libraries that
uses a lowercase namespace.
Consequently there are some complications with persuading cobra to work with it conveniently.
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.
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.
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
<Type> name = <init> ; --> var name as <Type> = <init>
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
'[<accessModifier> ...] <Type> name,'
->
'name as <Type> [is <accessModifier>, ...],'
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.
'[<accessModifier> ...] <Type> name,' -> 'name as <Type> [is <accessModifier>, ...],'
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 classIf 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 ( <Type> 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".'
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
Frame.Icon, .icon property -> no workaround
Frame.StatusBar, .statusBar text property -> use method .setStatusBar(text) instead
Attachments
- ListView.cs (4.5 KB) - added by hopscc 15 years ago.
- ListView.cobra (3.7 KB) - added by hopscc 15 years ago.