JXA NSWindow

今回は JXA でウインドウを作ってみる。

実はウチの PyGObject Tips ページのアクセス数で解るんだけどさ。
ウインドウを作るのページだけブッチギリで多いのよ、初心者ってそんなもんだ。
なんだかなぁ、プログラミングが面白いのはその先からだと思うんですけど。
ということで画像も表示してみる。

検索すると色々な実装があるけど結果は全部同じだね。
それなら簡潔で理解が早い人が多いっぽい実装を選んでみよう。

でも気に入らないのは大半の人がウインドウを閉じると終了するコードだ。
おい macOS だぞ、メニューバーに command+Q は必須だろ?
それと無意味な即時実行多すぎ、多分よく解っていないんだろうけど。

NSApp.servicesMenu in JXA ? GitHub

なんだよ、command+Q メニューはこんなにアッサリ実装できるんかい。
まさかこんなところでバックコーテーションを使うとは。
alloc.init だけなら new メソッドでいいみたい、ふむふむ。

しかし一回しか使わない関数なら無名関数の即時実行でいいのに。
即時実行ってそういう場合に使うと思うんだが。
ということで、こんなサンプルコードになりました。

#!/usr/bin/osascript

ObjC.import("Cocoa");

const imgePath = $("/Users/sasakima-nao/Pictures/[シクシクおよよ]三嶋ゆらら(SSR).jpg");

/**
 * Contents
 */
let image = $.NSImage.alloc.initWithContentsOfFile(imgePath);
if (image.isNil()) {
    console.log("Image Not Found.");
}
let imageView = $.NSImageView.alloc.initWithFrame(
    $.NSMakeRect(0, 0, 320, 400)
);
imageView.setImageScaling($.NSScaleToFit);
imageView.setImage(image);

/**
 * Window
 */
let window = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer(
    $.NSMakeRect(0, 0, 320, 400),
    $.NSTitledWindowMask
    | $.NSClosableWindowMask
    | $.NSMiniaturizableWindowMask,
    //| $.NSResizableWindowMask,
    $.NSBackingStoreBuffered,
    false
);
window.title = $("[シクシクおよよ]三嶋ゆらら(SSR)");
window.center;
window.orderFrontRegardless;
window.contentView.addSubview(imageView);

/**
 * Application
 */
let app = $.NSApplication.sharedApplication;
app.setActivationPolicy($.NSApplicationActivationPolicyRegular);
app.mainMenu = function() {
    
    function newMenu(title, action, key) {
       return $.NSMenuItem.alloc.initWithTitleActionKeyEquivalent(title, action, key);
    }
    
    const appName = "Test Window";
    
    const mainMenu = $.NSMenu.new;
    const itemApp  = $.NSMenuItem.new;
    const menuApp  = $.NSMenu.new;
    itemApp.submenu  = menuApp;
    mainMenu.addItem(itemApp);
    menuApp.addItem(newMenu(`Quit ${appName}`, 'terminate:', 'q') );

    return mainMenu;
}();
app.run;

やばい、ゆららちゃんがこんなにカワイイとは!
つい炭酸全部使ってフルマカロン取っ、、、、、いやそれはどうでもよくて。

macOS アプリって Application と Window に何も関連性が無いんだね。
あぁだから macOS では Window を全部閉じてもアプリは終了しないのか。

GTK+, WPF, VCL 等は全部 Application class が Window を管理している。
で、管理する Window が無くなったら Application が終了する、という流れ。
mac は本当に独特なんだなと。

しかしメソッドに括弧が無いのは相変わらず慣れない。
app.run にすら不要って意味ワカンネ!