Wiki

Changes between Initial Version and Version 1 of WxWidgetsPort

Show
Ignore:
Timestamp:
10/29/09 08:35:08 (15 years ago)
Author:
hopscc
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • WxWidgetsPort

    v1 v1  
     1= Porting wxWidgets wx.NET C# source file to cobra = 
     2 
     3The .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 
     4uses a lowercase namespace.[[br]] 
     5Consequently there are some complications with persuading cobra to work with it conveniently. 
     6 
     7see [wiki:C#Diffs Cobra differences fm C#] 
     8 
     9Heres a process for C# generally with some notes re wx.NET generated from converting wx.NET sample file ListView.cs to ListView.cobra 
     10 
     111 Take .cs file, rename to .cobra file 
     12 
     132. Change multiline comments from multiple // or /* */ bounded to be /# #/ bounded.[[br]] 
     14Change single line comments to use leading '#' 
     15 
     16Remove extraneous separator line comments between method calls    
     17        // ------------------------------ 
     18         
     193. Remove trailing ';' from each line they occur on 
     20 
     214. Fixup blocking and indentation. 
     22 
     23  Remove all '{' and '}' indicating start and end blocks from source.[[br]] 
     24  Ensure remaining blocks are all correctly (equally) indented and that  
     25  indentation uses either all spaces or all Tabs and that the 
     26  indents are in multiples of either 4 spaces or 1 tab. 
     27 
     28      
     295. Fix 'using' statements 
     30    ''''using'''' -> ''''use''''' 
     31Remove any lines for  
     32{{{ 
     33    using System 
     34    using System.Collections.Generic 
     35    using System.IO 
     36    using System.Text 
     37}}} 
     38  as cobra includes these automagically 
     39 
     40Change any other lines from  
     41        ''''using xxxx;'''' to ''''use xxxx''''                     
     42You also need to specify to use the C# wrapper library/namespace for wxWidgets (''''wx''''). 
     43 
     44Before ''''use System.Drawing'''' add a ''''use .. from line''''  for wx.NET 
     45{{{ 
     46    use wx from "wx.NET" 
     47    use System.Drawing 
     48}}} 
     49        or  add an explicit compiler directive ref line and a 'use wx' line 
     50{{{ 
     51    @ref "wx.NET" 
     52            ... 
     53    use wx 
     54    use System.Drawing 
     55}}} 
     56 
     575. Namespace decl 
     58   Namespaces in cobra need to start with an upcased letter. 
     59   Remove any ''''wx.'''' prefix from namespace line ;  
     60        ''''namespace wx.Something'''' to  ''''namespace Something'''' 
     61 
     62 
     635a. Correct any Enum definitions 
     64    After applying the above its basically removing trailing ',' and ensuring indentation 
     65    of enum items is the same 
     66    e.g.  
     67{{{ 
     68    enum Cmd { About, Quit, Dialog } -> 
     69    enum Cmd 
     70        About 
     71        Quit 
     72        Dialog 
     73 
     74    enum ID_CONTROLS  { 
     75        ID_RADIO_ORIENT = 5999, 
     76        ID_CHK_SHOWIMAGES, 
     77        ID_BTN_NEXT_PAGE, 
     78        ID_NOTEBOOK 
     79   } 
     80         -> 
     81   enum ID_CONTROLS 
     82        ID_RADIO_ORIENT = 5999 
     83        ID_CHK_SHOWIMAGES 
     84        ID_BTN_NEXT_PAGE 
     85        ID_NOTEBOOK 
     86}}} 
     87 
     88 
     896. Fix class declaration syntax 
     90      Change lines like ''''class X : Y'''' to ''''class X inherits Y''''         
     91 
     92 
     937. Change any class instance attributes/fields to be prefixed with ''''var'''' 
     94   change type and accessmodifier to cobra forms 
     95{{{ 
     96    <Type> name = <init> ; 
     97    --> 
     98    var name as <Type> = <init> 
     99}}}            
     100 
     1018. Fixup class constructor definitions 
     102      For initializer/constructor change lines like 
     103        ''''public !ClassName(params,...) : base(baseParams,...)'''' 
     104      to 
     105        ''''cue init(params, ...) is public''' 
     106             '''base.init(baseParams,...)''''         
     107 
     108     within the params list correct type declaration syntax from C# to cobra 
     109        ''''[<accessModifier> ...] <Type> name,'  
     110            ->  
     111        ''''name as <Type> [is <accessModifier>, ...],'''' 
     112 
     113        public is default accessmodifier so can leave that off   
     114     e.g. 
     115{{{ 
     116    public ListViewFrame (string title, Point pos, Size size) : base(title, pos, size) 
     117           -> 
     118    cue init(title as String, pos as Point, size as Size ) is public 
     119        base.init (title, pos, size) 
     120}}} 
     121                
     1229. Remove any uses of ''''new'''' to construct a class instance,  
     123    instead just make a call to the class type passing any initializer args, i.e just remove 'new' 
     124    e.g. 
     125{{{ 
     126        menuFile = new Menu()   -> menuFile = Menu() 
     127        new Point(10, 100)      -> Point(10, 100) 
     128        new Size(650,340)       -> Size(650, 340) 
     129}}} 
     130 
     131       For classes that construct delegates (take method names) prefix the methodname with 
     132        '''ref''',  
     133        methodNames must start with a lowercase letter and are prefixed by ''''this.'''' or just ''''.'''' 
     134        so change the methodName accordingly 
     135            e.g. {{{new EventListener( OnAbout )  -> EventListener( ref .onAbout ) }}} 
     136 
     137 
     13810. Methods: 
     139    Prefix methods with '''def''' 
     140    Change methodnames to start with a lowercase letter,  
     141    Change param definitions to cobra form. 
     142        ''''[<accessModifier> ...] <Type> name,'''' -> ''''name as <Type> [is <accessModifier>, ...],'''' 
     143    Cobra methods by default return void and are public so if the C# code specifies ''''public void'''  
     144    you can just delete those words. 
     145    Also, if a method has no parameters then the empty trailing () can be left off. 
     146             
     147    Note builtin types: 
     148        C# string -> String 
     149        C# object -> Object - Theres a twist though; wx.NET also defines an Object (wx.Object) so 
     150            that if you just declare something of Type Object theres a resolution ambiguity 
     151                message is 'Ambiguous reference "Object" found in namespaces "System" and "wx"' 
     152            so you have to either rely on the dynamic typing or resolve the ambiguity by  
     153            specifying the namespace to use 
     154        e.g.  
     155{{{ 
     156    public void OnAbout( object sender, Event e ) 
     157                -> 
     158    def onAbout(sender as System.Object, e as Event)   
     159    # OR def onAbout(sender, e as Event)  # untyped arg defaults to dynamic 
     160 
     161    # no param method 
     162    public override bool OnInit() 
     163           -> 
     164    def onInit as bool is override  
     165    # or def onInit as bool is public, override # explicit 
     166}}} 
     167             
     16811. Calls to methods, properties and attributes/fields 
     169     Instance method names, properties and fields are called with a prefix of ''''this.'''' or just ''''.''''  
     170     and they all must be named starting with a lowercase letter so these calls and settings 
     171     must be modified accordingly. 
     172     e.g. 
     173{{{ 
     174    menuFile.AppendWL(...   ->  menuFile.appendWL( ... 
     175    CreateStatusBar()       -> .createStatusBar # or this.createStatusBar 
     176}}} 
     177    Similarly with properties and fields 
     178{{{ 
     179    TextCtrl = TextCtrl(this, ...   ->  .textCtrl = TextCtrl(this, ... 
     180    MenuBar = menuBar               ->  .menuBar = menuBar 
     181    Log.SetActiveTarget( textCtrl ) ->  Log.setActiveTarget(.textCtrl) # static class 
     182}}} 
     183    If a method takes no args then any empty trailing () on a method call can/should be left off. 
     184 
     18512.  Property definition depending on the property use, prefix properties with  
     186        get - readable property only 
     187        set - setable property only 
     188        pro - getable and setable 
     189 
     190    Change property names to start with a lowercase letter 
     191 
     192 
     19313. Local variables declared and assigned on first use can usually be changed to remove  
     194    the type definition (type inferred from the assignment) or can continue to be explicitly typed 
     195    (if that compiles). 
     196{{{ 
     197     ListItem info = new ListItem()  
     198      -> 
     199     info = ListItem     # or    info as ListItem = ListItem() 
     200}}} 
     201     
     202 Heres a composite example  
     203{{{ 
     204    //  C# 
     205    ListItem itemCol = new ListItem(); 
     206    itemCol.Text = "Second Column"; 
     207    itemCol.Align = ListCtrl.wxLIST_FORMAT_CENTER; 
     208    itemCol.Width = 300; 
     209    InsertColumn( 1, itemCol ); 
     210            -> 
     211    # Cobra 
     212    itemCol = ListItem() 
     213    itemCol.text = "Second Column" 
     214    itemCol.align = ListCtrl.wxLIST_FORMAT_CENTER 
     215    itemCol.width = 300 
     216    .insertColumn(1, itemCol) 
     217}}}                 
     218 
     219 
     22012. Fixup 'For' loops 
     221{{{ 
     222    for ( <Type> name = start ; name < stop; ++name )  
     223            -> 
     224    for name as Type in start : stop : 1 # explicit or equally use shortcuts: 
     225    for name in start : stop : 1  
     226    for name  in start : stop  # if step is one (1) 
     227    for name in stop           # if start is zero (0) and step is one (1) 
     228        # same as for name in 0 : stop : 1 
     229}}} 
     230     
     231  e.g 
     232{{{ 
     233    for ( int i = 0; i < 200; ++i ) -> for i in 0 : 200 
     234}}}     
     235 
     23613. Casting 
     237    Casts of form '(Type)name' become 'name to Type' 
     238    e.g.   
     239{{{ 
     240    mf.AppendWL( (int)Cmd.About,...  
     241        ->   
     242    mf.appendWL(Cmd.About to int,... 
     243}}} 
     244 
     245    Casts of form 'a as Type' can also become 'name to Type' or 'name to? Type' 
     246    e.g 
     247{{{ 
     248    ListEvent le = e as ListEvent;  
     249    ->  
     250    le = e to ListEvent  
     251}}} 
     252         
     25314. String catenated with an expression (converted to string) 
     254    Put the expression (cobra converted) in the string inside [] 
     255    e.g.  
     256{{{ 
     257    "Value 1st field of selected item: " + le.Text   
     258             ->  
     259    "Value 1st field of selected item: [le.text]" 
     260}}} 
     261              
     26215. Adding eventHandlers 
     263    Cobra uses the *listen* statement to register eventhandlers where C# uses an override on  
     264    the += operator.  WxWidgets wraps method calls in an EventHandler class instance. 
     265    Otherwise normal cobra mapping for method names and reference to methods (vs method calls) 
     266    apply; Methodnames in Cobra must start with lower case and calls to this instance names  
     267        are prefixed with ''''this.'''' or (easier) ''''.''''     
     268    When translating from a 'use'd library namespace,  calls to  
     269        Capcased methodnames are referenced in cobra with the first '''char''' lowercased,  
     270        Upcased methodnames  are referenced with the first '''word''' lowercased 
     271    so  
     272{{{ 
     273    EVENT += EventListener( MethodName ) in C# becomes 
     274    listen .EVENT,      EventListener( ref .methodName )  
     275 
     276    EVENT += EventListener( EH_METHOD_NAME ) in C# becomes 
     277    listen .EVENT,      EventListener( ref .eh_METHOD_NAME )  
     278}}} 
     279    e.g. 
     280{{{ 
     281    ColumnClick += EventListener( OnColumnClick ) 
     282    ItemSelect  +=  EventListener( OnItemSelect ) 
     283    ColumnRightClick +=  EventListener( OnColumnRightClick ) 
     284        -> 
     285    listen .columnClick,    EventListener(ref .onColumnClick)  
     286    listen .itemSelect,     EventListener(ref .onItemSelect ) 
     287    listen .columnRightClick, EventListener(ref .onColumnRightClick) 
     288}}} 
     289 
     290    !WxWidets menu action handlers can be done in C# using call to EVT_MENU. 
     291        {{{EVT_MENU((int)MENU_ENUM_VALUE, new EventListener(MethodName)); }}} 
     292    the equivalent in cobra becomes 
     293        {{{.evt_MENU(MENU_ENUM_VALUE to int,    new EventListener(ref .methodName))}}} 
     294                 
     295    e.g.     
     296{{{ 
     297    EVT_MENU((int)Cmd.Quit,    new EventListener(OnQuit)); 
     298    EVT_MENU((int)Cmd.Dialog,  new EventListener(OnDialog)); 
     299    EVT_MENU((int)Cmd.About,   new EventListener(OnAbout)); 
     300}}} 
     301            -> 
     302{{{ 
     303    .evt_MENU(Cmd.Quit to int,    EventListener(ref .onQuit)) 
     304    .evt_MENU(Cmd.Dialog to int,  EventListener(ref .onDialog)) 
     305    .evt_MENU(Cmd.About to int,   EventListener(ref .onAbout)) 
     306}}} 
     307 
     30816. Main method 
     309    public void is default, static is an accessmodifier becomes ''''shared'''' in cobra, 
     310    C# attributes (!MetaInformation) are denoted with ''''has'''' 
     311    e.g. 
     312{{{ 
     313    [STAThread] 
     314    static public void main() 
     315            ->   
     316    def main is shared has STAThread 
     317}}}     
     318 
     31917. Lowercased namespace names (as in wx.NET) used to disambiguate or otherwise explicitly  
     320    specify the namespace  on types (inherits ..., as ....) as opposed to methods or constants  
     321    can (may/will) generate compile errors of the form  
     322        ''''error: Cannot find type for "wx.TYPE".''''[[br]] 
     323        e.g. error: Cannot find type for "wx.Frame".         
     324    If such occurs the only recourse is to remove the explicit typing and rely on default handling 
     325    e.g. 
     326{{{ 
     327    use wx from "wx.NET" 
     328    namespace SampleMinimal 
     329        class MyFrame inherits wx.Frame 
     330                # file.cobra(3): error: Cannot find type for "wx.Frame".    
     331    #Change to          
     332    use wx from "wx.NET" 
     333    namespace SampleMinimal 
     334        class MyFrame inherits Frame 
     335}}} 
     336         
     337{{{     def onAbout(sender as System.Object, e as wx.Event ) }}} 
     338    #    Change to  
     339{{{     def onAbout(sender as System.Object, e as Event ) }}} 
     340         
     341{{{      
     342    fileMenu as wx.Menu = wx.Menu()  
     343    #    Change to  
     344    fileMenu = Menu()  
     345}}} 
     346    Eventually it would be preferable if cobra became a little more flexible in these cases..  
     347 
     348 
     349Other weirdnesses 
     350    As of this doc date (Oct 2009) the wx.NET version and cobra seem to not be able to find 
     351    some properties, specifically[[br]] 
     352        Frame.Icon, .icon property -> no workaround [[br]] 
     353        Frame.!StatusBar, .statusBar text property -> use method .setStatusBar(text) instead[[br]]