uchcode
12/31/2016 - 7:38 AM

JXA (JavaScript for Automation) Window applet example.

JXA (JavaScript for Automation) Window applet example.

ObjC.import('Cocoa')

class UserInterface {
  constructor() {
    this.lateLabel = Label(10, 110, 160, 26); {
      this.lateLabel.alignment = $.NSRightTextAlignment
      this.lateLabel.stringValue = 'Exchange Rate per $1:'
    }
    this.dollersLabel = Label(10, 80, 160, 26); {
      this.dollersLabel.alignment = $.NSRightTextAlignment
      this.dollersLabel.stringValue = 'Dollers to Convert:'
    }
    this.totalLabel = Label(10, 50, 160, 26); {
      this.totalLabel.alignment = $.NSRightTextAlignment
      this.totalLabel.stringValue = 'Amount in Other Currency:'
    }
    this.rateField = TextField(180, 116, 200, 22); {
    }
    this.dollersField = TextField(180, 86, 200, 22); {
    }
    this.totalField = TextField(180, 56, 200, 22); {
      this.totalField.editable = false
      this.totalField.selectable = true
    }
    this.horizontalLine = Line(10, 50, 380, 1); {
    }
    this.convertButton = Button(300, 10, 90, 26); {
      this.convertButton.title  = 'Convert'
    }
    this.window = Window(-1, -1, 400, 160); {
      this.window.title = 'Currency Converter'
      //this.window.frameAutosaveName = 'main'
      this.window.contentView.addSubview(this.lateLabel)
      this.window.contentView.addSubview(this.dollersLabel)
      this.window.contentView.addSubview(this.totalLabel)
      this.window.contentView.addSubview(this.rateField)
      this.window.contentView.addSubview(this.dollersField)
      this.window.contentView.addSubview(this.totalField)
      this.window.contentView.addSubview(this.horizontalLine)
      this.window.contentView.addSubview(this.convertButton)
      this.window.defaultButtonCell = this.convertButton.cell
    }
  }
  get rate() {
    return this.rateField.floatValue
  }
  set rate(value) {
    this.rateField.floatValue = value
  }
  get dollers() {
    return this.dollersField.floatValue
  }
  set dollers(value) {
    this.dollersField.floatValue = value
  }
  get total() {
    return this.totalField.floatValue
  }
  set total(value) {
    this.totalField.floatValue = value
  }
}

MyAction = SimpleSubclass('Action', {
  convertRateDollers(sender) {
    MyUI.total = MyUI.rate * MyUI.dollers
  },
})

function reopen() {
  MyUI.window.makeKeyAndOrderFront(null)
}

function run(argv) {
  MyUI = new UserInterface()
  MyUI.convertButton.target = MyAction
  MyUI.convertButton.action = 'convertRateDollers:'
  MyUI.rate = 117
  MyUI.dollers = 1
  MyUI.window.makeKeyAndOrderFront(null)
  MyAction.convertRateDollers(null)
}

//=====================================================================

function Window(x, y, width, height) {
  let r = $.NSMakeRect(x, y, width, height)
  let s = $.NSTitledWindowMask
      s|= $.NSClosableWindowMask
      s|= $.NSMiniaturizableWindowMask
  let b = $.NSBackingStoreBuffered
  let d = false
  let w = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer(r, s, b, d)
  w.releasedWhenClosed = false
  if (x==-1 && y==-1) w.center
  return w
}

function WindowDelegate() {
  if (!$.WindowDelegate) ObjC.registerSubclass({
    name:'WindowDelegate',
    protocols: ['NSWindowDelegate'],
    methods: {
      'windowWillClose:' (notification) {
        return $.NSApplication.sharedApplication.terminate(null)
      },
    },
  })
  return $.WindowDelegate.alloc.init
}

function Button(x, y, width, height) {
  let r = $.NSMakeRect(x, y, width, height)
  let b = $.NSButton.alloc.initWithFrame(r)
  b.bezelStyle = $.NSRoundedBezelStyle
  return b
}

function Label(x, y, width, height) {
  let r = $.NSMakeRect(x, y, width, height)
  let t = $.NSTextField.alloc.initWithFrame(r)
  t.drawsBackground = false
  t.bordered = false
  t.editable = false
  t.selectable = true
  return t
}

function TextField(x, y, width, height) {
  let r = $.NSMakeRect(x, y, width, height)
  let t = $.NSTextField.alloc.initWithFrame(r)
  return t
}

function Line(x, y, width, height) {
  let r = $.NSMakeRect(x, y, width, height)
  let b = $.NSBox.alloc.initWithFrame(r)
  b.boxType = $.NSBoxSeparator
  return b
}

function SimpleSubclass(_name, methods) {
  if ($[_name]) return $[_name].alloc.init
  let _methods = {}
  for (let m in methods) {
    _methods[m+':'] = {
      types: ['void', ['id']],
      implementation: methods[m],
    }
  }
  ObjC.registerSubclass({
    name: _name,
    methods: _methods,
  })
  return $[_name].alloc.init
}