今回は JXA でメニューバーとキーボードショートカット。
GNOME は取っ払ってしまったけど macOS ではまだ必須だもんな。
またデリゲートの登録か。。。。。
action に普通の関数を入れてみたりしたけど動かなかった。
従うしかないな。
それと前回 JavaScript 文字列を NSString に変換していなかった。
アルファベットしか使わないならそれでもいいんだけどね。
ということで前回のコードに書き足しと修正を行なって。
ついでに osacompile でコンパイル実行してみる。
#!/usr/bin/osascript
// osacompile -l JavaScript -o MenuTest.app jxa_menu.js
ObjC.import("Cocoa");
class ButtonWindow {
constructor(app) {
ObjC.registerSubclass({
name: "WinDelegate",
protocols: ["NSWindowDelegate"],
methods: {
"windowWillClose:": {
types: ["void", ["id"]],
implementation: (notification)=> {
app.terminate(0);
}
}
}
});
ObjC.registerSubclass({
name: "AppDelegate",
methods: {
"onButtonClicked:": {
types: ["void", ["id"]],
implementation: (button)=> {
this.window.title = $("Click!");
}
}
}
});
let appDelegate = $.AppDelegate.new;
// NSButton
this.button = $.NSButton.alloc.initWithFrame($.NSMakeRect(50, 5, 200, 30));
this.button.title = $("Click!");
this.button.bezelStyle = $.NSRoundedBezelStyle;
this.button.buttonType = $.NSMomentaryLightButton;
this.button.target = appDelegate;
this.button.action = "onButtonClicked:";
// NSWindow
this.window = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer(
$.NSMakeRect(0, 0, 300, 50),
$.NSTitledWindowMask
| $.NSClosableWindowMask
| $.NSMiniaturizableWindowMask
| $.NSResizableWindowMask,
$.NSBackingStoreBuffered,
false
);
this.window.title = $("Title");
this.window.orderFrontRegardless;
this.window.delegate = $.WinDelegate.new;
this.window.contentView.addSubview(this.button);
this.window.makeKeyAndOrderFront(this.window);
}
changeTitle() {
this.window.title = $("Menu !");
}
}
function run(argv) {
const app = $.NSApplication.sharedApplication;
const window = new ButtonWindow(app);
app.setActivationPolicy($.NSApplicationActivationPolicyRegular);
ObjC.registerSubclass({
name: "MenuAction",
methods: {
"changeTitle:": {
types: ["void", ["id"]],
implementation: (sender)=> {
window.changeTitle();
}
}
}
});
app.mainMenu = function() {
function nm(title, action, key, target) {
let item = $.NSMenuItem.new;
if (target) item.target = target;
item.title = $(title);
item.action = action;
item.keyEquivalent = $(key);
return item;
}
// main
const mainMenu = $.NSMenu.new;
// Menubar
const itemApp = $.NSMenuItem.new;
const itemFile = $.NSMenuItem.new;
mainMenu.addItem(itemApp);
mainMenu.addItem(itemFile);
// Drop Down Menu
const menuApp = $.NSMenu.alloc.initWithTitle($("Comipoli"));
const menuFile = $.NSMenu.alloc.initWithTitle($("File"));
itemApp.submenu = menuApp;
itemFile.submenu = menuFile;
// Action
menuApp.addItem(nm("Quit", "terminate:", "q", null));
//
let ac = $.MenuAction.new;
menuFile.addItem(nm("Change", "changeTitle:", "w", ac));
//
return mainMenu;
}();
app.run;
}
メニューやキーボードショートカットが動作しているのが解る。
コンパイルするとアプリ名になってくれるようだ。
js のまま実行するとアプリ名が osascript になる。
osacompile はシバンを付けたままでも実行できるようです。
何故かスクリプトエディタ.app からはエラーでコンパイルできなかった。
こんなショボいエディタを使っている人はいないだろうからどうでもいいけど。
とりあえず JXA でアプリを作る雛形はこんなもんでいいかな。
