D言語からObjective-CとCocoaAPIを使いたい

D言語で Mac の GUI を、extern(Objective-C) を使用して Cocoa API (Window) を表示します。

CocoaAPI を使用して、簡単な Window を表示

WindowのSample

サンプルコード

Powered by Prism


/**
 *  simpleWin.d     Version 0.0.1
 *      dmd -L-framework -LCocoa simpleWin.d CocoaAPI.o
 */
module simpleWin;
import core.attribute : optional, selector;
import std.stdio;
import CocoaAPI;

string appName;
string Version = "Version 0.0.1";

void main() {
    auto delegate_ = AppDelegate.alloc.init;
    NSApp.delegate_ = cast(void*) delegate_;
    NSApp.activationPolicy = NSAppActivationPolicy.regular;
    NSApp.run;
}

void buildWindow() {
    NSWindow win;
    appName = NSProcessInfo.processInfo.processName.toDs;
    NSApp.menu = MainMenu(appName);
    NSRect w_rect = NSMakeRect(0, 0, 300, 200);
    immutable w_style = NSWindowStyleMask.titled | 
                        NSWindowStyleMask.closable | 
                        NSWindowStyleMask.resizable | 
                        NSWindowStyleMask.miniaturizable;
    win = NSWindow.alloc.init(w_rect, w_style, NSBacking.buffered, false);
    win.title = (appName ~ "  (D言語)").toNs;
    ViewController vCtrl = ViewController.alloc.init;
    View dView = View.alloc.init;
    vCtrl.view.addSubview = dView;
    win.contentView = dView;
    win.minSize = NSSize(150, 100);
    win.moveTop = NSPoint(200, 900);
    win.bgColor = NSColor.white;
    win.makeKeyAndOrderFront = null;
    NSApp.activateIgnoringOtherApps = true;
}

extern (Objective-C)
class AppDelegate : NSObject {
    override static AppDelegate alloc() @selector("alloc");
    override typeof(this) init() @selector("init");
    bool applicationShouldTerminateAfterLastWindowClosed(
            NSNotification notification) @selector(
            "applicationShouldTerminateAfterLastWindowClosed:") {
        return true;
    }
    void applicationDidFinishLaunching(NSNotification notification) 
            @selector("applicationDidFinishLaunching:") {
        buildWindow;
    }
    void AboutPanel() @selector("AboutPanel") {
        Dialog(appName, Version);
    }
    void Perferences() @selector("Perferences") {
        Dialog("環境設定", "未設定です。");
    }
    void ShowHelp() @selector("showHelp") {
        Dialog("Help", "簡単なWindowをCocoaAPIを使用して、\n"
            ~ "D言語で表示しています。");
    }
} 

extern (Objective-C) 
class ViewController : NSViewController {
    override static ViewController alloc() @selector("alloc");
    override ViewController init() @selector("init");
    override void loadView() @selector("loadView") { 
        printf("loadView\n"); 
    }
    override void viewDidLoad() @selector("viewDidLoad") { 
        printf("viewDidLoad\n"); 
    }
}

extern (Objective-C)
class View : NSView {
    override static View alloc() @selector("alloc");
    override View init() @selector("init");
    override View init(NSRect) @selector("initWithFrame:");
    override void drawRect(NSRect) @selector("drawRect:");
}

extern (Objective-C)
string Dialog(string msgText, string infoText) {
    NSAlert alert = NSAlert.alloc.init;
    alert.addButton= "OK".toNs;
    alert.messageText = msgText.toNs;
    alert.information = infoText.toNs;
    alert.style = alertStyle.warning;
    switch (alert.run) {
        case response.OK: return("OK");
        default: return("Other");
    }
}

NSMenu MainMenu(string aName) {
    NSMenu mainMenu = NSMenu.alloc.init;
    NSMenuItem appItem = NSMenuItem.alloc.init;
    mainMenu.item = appItem;
    // application menu
    NSMenu appMenu = NSMenu.alloc.init;
    appItem.submenu = appMenu;
    appMenu.item = NSMenuItem.alloc.init("About " ~ aName ~ " ", "AboutPanel", "");
    appMenu.item = NSMenuItem.separatorItem;
    appMenu.item = NSMenuItem.alloc.init("Perferences…", "Perferences", ",");
    appMenu.item = NSMenuItem.separatorItem;
    appMenu.item = NSMenuItem.alloc.init("Hide " ~ aName, "hide:", "h");
    appMenu.item = NSMenuItem.alloc.init("Hide Others", "hideOtherApplications:", "H");
    appMenu.item = NSMenuItem.alloc.init("Show All", "unhideAllApplications:", "");
    appMenu.item = NSMenuItem.separatorItem;
    appMenu.item = NSMenuItem.alloc.init("Quit " ~ aName , "terminate:", "q");
    mainMenu.submenu(appMenu, appItem);
    // edit menu
    NSMenu editMenu = NSMenu.alloc.init("Edit");
    NSMenuItem editItem = mainMenu.addItem("Edit", null, "");
    mainMenu.submenu(editMenu, editItem);
    editMenu.item = NSMenuItem.alloc.init("Cut", "cut:", "x");
    editMenu.item = NSMenuItem.alloc.init("Copy", "copy:", "c");
    editMenu.item = NSMenuItem.alloc.init("Paste", "paste:", "v");
    editMenu.item = NSMenuItem.alloc.init("Delete", "delete:", "\b");
    // help menu
    NSMenu helpMenu = NSMenu.alloc.init("Help");
    NSMenuItem helpItem = mainMenu.addItem("Help", null, "");
    mainMenu.submenu(helpMenu, helpItem);
    helpMenu.item = NSMenuItem.alloc.init("Help", "showHelp", "");
    return mainMenu;
}