Searches for the "perfect" GUI. Beginner's Way

Studying the first language, I wanted to see buttons, not just text in the console. I made a calculator on Python3 + tkinter. It took 585 lines. Applying the magic of py2app to the code, I got a bundle of size 45MB. I did not like working with py2app. Sometimes everything stopped working if third-party libraries were used, and sometimes I fixed the py2app code. Because of this, I thought it was very difficult to make standalone applications.









A year later, I met with xCode and the calculator for iOS took only 125 lines. It should be borne in mind that the buttons were made in the visual editor, and from the operations I left only: โ€œ+โ€, โ€œ-โ€, โ€œ*โ€, โ€œ/โ€. Bundle is less than 10 MB.









A couple of weeks ago, I found a way to make a calculator for Mac OS without xCode. I managed to keep within 57 lines and I stopped being afraid of Swift.



import AppKit
let winWid: CGFloat = 256
let wihHei: CGFloat = 180
let dispHei: CGFloat = 18
let rows = 4
let rowHei: CGFloat = 32
class AppDelegate: NSObject, NSApplicationDelegate {
    lazy var window = NSWindow(contentRect: NSMakeRect(0, 0, winWid, wihHei),
                               styleMask: [.titled, .closable], backing: .buffered,
                               defer: false, screen: nil)
    let display = NSText(frame: NSMakeRect(0, wihHei - dispHei, winWid, dispHei))
    func applicationDidFinishLaunching(_ notification: Notification) {
        window.title = "Machine"
        window.contentView?.addSubview(display)

        let eq = NSButton(frame: NSMakeRect(0, 0, winWid, rowHei))
        eq.title = "="
        eq.target = self
        eq.action = #selector(eval)
        window.contentView?.addSubview(eq)

        let items = ["C","0",".","/","1","2","3","*",
                     "4","5","6","-","7","8","9","+"]

        let sz = CGSize(width: (winWid/CGFloat(rows)),
                        height: rowHei)
        for i in 0..<items.count {
            let x = i % rows
            let y = i / rows
            let b = NSButton(
                frame: NSMakeRect(sz.width * CGFloat(x),
                                  sz.height * CGFloat(y) + rowHei,
                                  sz.width, sz.height))
            b.title = items[y*rows+x]
            b.target = self
            b.action = i==0 ? #selector(clear) : #selector(input)
            window.contentView?.addSubview(b)
        }
        window.makeKeyAndOrderFront(nil)
    }
    @objc func input(sender: NSButton) {display.string! += sender.title}
    @objc func eval(sender: NSButton) {
        let exp: NSExpression = NSExpression(format: display.string!)
        if let result: Double = exp.expressionValue(with: nil, context: nil) as? Double {
            display.string = String(result)
        }
    }
    @objc func clear(sender: NSButton) {display.string = ""}
    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        return true
    }
}
let delegate = AppDelegate()
var appl: NSApplication
#if swift(>=5.1)
    appl = NSApplication.shared
#else
    appl = NSApplication.shared()
#endif
appl.setActivationPolicy(.regular)
appl.delegate = delegate
appl.run()

      
      





main.swift :



swiftc main.swift

      
      





, . . "=" , .









, Red. 13 . standalone MacOS 1 MB.



Red [Needs: View]
View [
    title "Red"
    disp: field 330x50 font-size 25 "" return
    style b: button 71x40 [append disp/text face/text]
    b "1" b "2" b "3" b " + " return
    b "4" b "5" b "6" b " - " return
    b "7" b "8" b "9" b " * " return
    b "0" b "." b " / " b " = " [attempt [
        result: form do disp/text
        append clear disp/text result]] return
    button "C" 325x40 [clear disp/text]
]

      
      





main.red :



red -t macOS main.red

      
      











, Windows, Linux, MacOS .

, , Apple 32- macOS 10.15



, - GUI.



All Articles