Swift Translator

Below is sample Swift code that was automatically generated by reading an Xojo project file
Right now is seems to handle all the UI controls (except for listbox :frowning: ) and does about an 80% accurate job of translated Xojo/Basic to Swift

The project that made this example has a single pushbutton, and a control array of two others
while all events can be tacked on I only used KEYDOWN as an example … All controls will have an OPEN with the option of also executing user supplied code.

import Cocoa
import Foundation
import DSFramework //<----- THIS HOLDS "the magic"
//
//┌─────────────────────────────┐
//│   Create Window 'Window1'   │
//└─────────────────────────────┘
var Window1 = Window1_class(type: .document)
class Window1_class : uxWINDOW {
    //│   Window Control Objects   │
    private var pb : [sub_pb] = []
    private var PushButton1  = sub_PushButton1()
    //│   Window Initialzation   │
    override func open() {
        self.title = "Untitled"
        self.height = 400
        self.width = 600
        //│   Create an Instance of each Control   │
        pb.append(sub_pb(frame:NSRect(x:188.0,y:44.0,width:80,height:20)))
        pb.append(sub_pb(frame:NSRect(x:280.0,y:44.0,width:80,height:20)))
        PushButton1 = sub_PushButton1(frame:NSRect(x:236.0,y:12.0,width:80,height:20))
        //│   Insert each control in proper zOrder   │
        self.addSubView(PushButton1)
        self.addSubView(pb[0])
        self.addSubView(pb[1])
        // User Supplied WINDOW OPEN code
        var i : Int = 0
        for i in(1...10) {
            var z : Int = i
            // this is canvas activate
        } // next i
    } // end Open Event

    //│   Create a Subclass of each Control   │
    fileprivate class sub_pb : uxPUSHBUTTON {
        static  var z$INDEX : Int = 0
        private var _INDEX  : Int = 0
        @MainActor required init?(coder: NSCoder) {fatalError("init(coder:) has not been implemented")}
        override init(frame:CGRect) {
            _INDEX              = sub_pb.z$INDEX
            sub_pb..z$INDEX += 1
            super.init(frame: frame)
        }
        public var index : Int { get { return _INDEX } }
        public override func open() {
            switch index {
                case 0 :
                    caption = "pb1"
                case 1 :
                    caption = "pb2"

                default : break
            }
        } // end of OPEN EVENT
        public override func keyDown(_ key : String)-> Bool {
            switch index {
                case 0 :
                    var x : Int = 3
                    x = x / 2
                case 1 :
                    var y : Int = 9
                    y = y / 4
                default : break } // end select
        }
    } // end of control
    fileprivate class sub_PushButton1 : uxPUSHBUTTON {
        public override func open() {
            caption = "Cancel"
        } // end of OPEN EVENT

        public override func keyDown(_ key : String)-> Bool {
            //
        }
    } // end of control
}
4 Likes

so cool!

Since my projects are quite small, I created most/all of them from scratch, using SwiftUI, SwiftData

This app and the companion framework were designed to make “most” GUI tasks much easier, as all the properties and events as well as error handling and initialization are all encompassed.

Not only does it contain all the Xojo related controls (except Listbox for now), but it has File handling, SQLite, as well as String and Math functions all using more familiar syntax

DISCLAIMER : Xojo does not condone nor endorse this project or the underlying concepts and methods. This project is written in 100% Apple Swift™ and no reverse engineering of any other software was included. How the user creates the properly formatted XML file to provide as input to this app is at the sole discretion of said user.

recently modified code to not have OPEN as the default event, but rather a CONSTRUCTOR event instead, this allows the user supplied OPEN code (if any) to be treated like any other user activated event.

constructor event ?

how is that different than an actual constructor ?

open, while badly named in many cases, should maybe have been “Init” or “Initialize”

by default evey Swit object already had an INIT event
This is used to define the basic subclass instance, but is unaware of any property changes the user desires… it then calls a CONSTRUCTOR event , which is defined in an NSRESPONDER extenstion as

open func constructor() { open() }

The constructor event is MANDATORY, but is created by the translator, not by the user

this can then be overriden by the user for each subclass instance to define the specific properties of that object (color, font , etc), the OPEN event is optional and is created by the user

So the chain of events is

  • INIT // defined by SWIFT : define instance of SUBCLASS
  • CONSTRUCTOR // defined by NSRESPONDER : define properties of Subclass
  • OPEN // optional and defined by user : define any specific open CODE by the user

DEFINE ? as in dim someCustomProperty as integer
or SET properties ? me.left = 90

property instances are defined in the subclass… the Constructor just sets values if the differ from the default values

class sub_PushButton1 : uxPUSHBUTTON {
   public override func constructor() {
      caption = "Cancel"
      setLockBottom = false
      setLockLeft = true
      setLockRight = false
      setLockTop = true
      isTransparent = false
      super.constructor()
   } // end of CONSTRUCTOR EVENT

uxPUSHBUTTON is the subclass define inside the imported framework, this constructor override sets the values of properties … the super.constructor calls any OPEN event

The INIT is private and inside the framework, and is not exposed directly to the user

OK so this “constructor” event is not really a constructor but an initializer event like OPEN is/was in Xojo

I’d almost just call it “Initialize” for clarity

name isn’t too important, since the user doesn’t ever create/write or interact with it. it does appear in the emitted project code, but only as a result of the properties that user defined for that object

and ‘Initialize’ (to me at least) causes confusion with INIT which is predefined by SWIFT itself

I just find constructor misleading for the same reasons :slight_smile:

Esp since it ISNT constructing (certainly not in the C++ sense)
Its fully constructed by then (like Xojo) and all you’re doing is setting properties that already exist to starting value

Maybe “Setup” ?

For ex-Xojoers they’ll go looking for “open”

OPEN is to set user defined event acttions…
CONSTRUCTOR is to set properties defined in the IDE… not written by the user,

OPEN sets actions ?
like event handlers ?

I’m confused now

sorry… CONSTRUCTOR sets properties defined in the IDE (right side panel in Xojo)
OPEN runs what ever user code was define in the OPEN event handler (which could include setting other properties)

I think I’d need to see the entire class & its use to follow along as I’m kind of lost / confused still

LOL… figured as much… when I get it back to generating proper code, I’ll post a simple example

Very interesting and useful.
Be good to see the Xojo code and then the swift version.
would chatGPT be helpful in completing the remanning areas that need work? I know it can convert some Xojo code to swift, not sure how good it is.
Phil

Thanks, but I’m not about to tie an AI into my Swift project… what I have now is about 80% accurate in translating Xojo code to Swift, Right now it makes a best “guess” then Xcode tells it what is wrong and it recursively fixes things. Biggest problem is with optionals, since Xojo has no such thing

Fair enough. Xcode does a good job of complaining, so that is probably the optimal solution. Congratulations on this body of work.
Phil

Simplified example of created output

import Cocoa
import Foundation
import DSFramework
//
var Window1 = Window1_class(type: .document) // THIS calls INIT for windo
//
class Window1_class : uxWINDOW {
    //
    private var PushButton1  = sub_PushButton1()
    //
    override func constructor() { // THIS SETS INITIAL PROPERTIES FOR WINDOW
        self.title = "Untitled"
        self.height = 400
        self.width = 600
        // add a control to the window
        PushButton1 = sub_PushButton1(frame:NSRect(x:236.0,y:12.0,width:80,height:20))
        self.addSubview(PushButton1)
    }
    //
    override func open () { // THIS IS USER SUPPLIED OPEN EVENT CODE (optional)
        for i in(1...10) { //[For i = 1 To 10]
            var z : Int = i //[Dim z As Integer=i]
        } // next i
    }
    //
    class sub_PushButton1 : uxPUSHBUTTON {
        public override func constructor() {
            caption = "Cancel"
            super.constructor()
        } 
          //
        public override func keyDown ( Key : String ) -> Bool {
            if Key == "aBc" { return false } //[if key="aBc" then return false]
            return true
        }
        //
    } // end of control
}