今回は JXA でメニューバーとキーボードショートカット。
GNOME は取っ払ってしまったけど macOS ではまだ必須だもんな。
またデリゲートの登録か。。。。。
action に普通の関数を入れてみたりしたけど動かなかった。
従うしかないな。
それと前回 JavaScript 文字列を NSString に変換していなかった。
アルファベットしか使わないならそれでもいいんだけどね。
ということで前回のコードに書き足しと修正を行なって。
ついでに osacompile でコンパイル実行してみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #!/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 でアプリを作る雛形はこんなもんでいいかな。