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

star2 : star の改版です

Code を分けてみました。スライダーの数値を矢印キーでも操作できるようにしました。

star2.png

サンプルコード

Powered by Prism

star2/dub.json

{
    "authors": ["hidhok"],
    "description": "A D/Objective-C Cocoa application.",
    "name": "star2",
    "dflags": ["-L-framework", "-LCocoa"],
    "sourceFiles": ["../cocoa/window",
                    "../cocoa/control",
                    "../cocoa/menus"]
}               
star2/source/app.d

/**
 *	  star2/source/app.d       Version 0.1.3
 */
module star2.main;
import core.attribute : optional, selector;
import std.stdio;
import cocoa.window;
import cocoa.control;
import cocoa.menus;
import star2.draw;

string appName;
string versionNo = "0.1.3";
string helpMessage =  "CocoaAPIを使用して、Cocoa App を\nD言語で表示してみました。";

ViewController vCtrlr;

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

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;
        buildContents;
    }
    void aboutPanel() @selector("aboutPanel") {
        NSMutableDictionary options = NSMutableDictionary.dictionary;
        // NSImage img = NSImage.name("AppIcon.icns".toNs);
        // options.setObjKey(img, "ApplicationIcon".toNs);
        options.setObjKey(versionNo.toNs, "Version".toNs);
        options.setObjKey("horkew.la.coocan.jp".toNs, "Copyright".toNs);
        options.setObjKey(versionNo.toNs, "ApplicationVersion".toNs);
        NSApplication.shared_.aboutPanelOptions(options.copy);
    }
    void showHelp() @selector("showHelp") {
        dialog("Help", helpMessage);
    }
} 

void buildWindow() {
    NSWindow win;
    NSRect w_rect = NSMakeRect(100, 550, 400, 400);
    appName = NSProcessInfo.processInfo.processName.toDs;
    NSApp.menu = miniMenu(appName);
    immutable w_style = NSWindowStyleMask.titled |
                        NSWindowStyleMask.closable |
                        NSWindowStyleMask.resizable |
                        NSWindowStyleMask.miniaturizable;
    win = NSWindow.alloc.init(w_rect, w_style, backing.Buffered, false);
    win.title = (appName ~ " (D言語テスト)").toNs;
    drView = DrawView.alloc.init;
    win.contentView = drView;
    vCtrlr = ViewController.alloc.init;
    vCtrlr.view.subview = drView;
    win.makeKeyAndOrderFront = null ;
    NSApp.activateIgnoringOtherApps = true;
}

extern (Objective-C) 
class ViewController : NSViewController {
    override static ViewController alloc() @selector("alloc");
    override ViewController init() @selector("init");
    override void loadView() @selector("loadView") {
        // printf("loadView    star2 ... running Now\n");
        writefln("loadView   %s ... running Now", appName);
    }
    override void viewDidLoad() @selector("viewDidLoad") {
        printf("viewDidLoad\n");
    }
}               
star2/source/draw.d

/** 
 *    star2/source/draw.d
 */
module star2.draw;
import core.attribute : optional, selector;
import std.stdio;
import std.conv;
import std.math;
import std.format;
import cocoa.window;
import cocoa.control;
import star2.main;

DrawView drView;
Slider slider;
Label nLabel;
int n = 12;

void buildContents() {
    slider = Slider.alloc.init(nRect(28, 1, 80, 25));
    slider.setValues(n, 1, 60);
    nLabel = Label.alloc.init(nRect(5, 3, 20, 20));
    nLabel.text = format("%1.2d", n);
}

extern (Objective-C)
class DrawView : NSView, NSStandardKeyBindingResponding {
    override static DrawView alloc() @selector("alloc");
    override DrawView init() @selector("init");
    override DrawView init(NSRect) @selector("initWithFrame:");
    override void drawRect(NSRect r) @selector("drawRect:") {
        double X(ref double t) { return (sin(t) + 1) * r.size.width * 0.5; }
        double Y(ref double t) { return (cos(t) + 1) * r.size.height * 0.5; }
        double f, g;
        double pi = PI;  // 2 * acos(0.0);

        NSColor.white.set;
        NSRectFill(r);
        NSBezierPath path = NSBezierPath.bezierPath;
        NSBezierPath.lineWidth = 0.1;
        NSColor.black.stroke; 

        for (f = 0; f < 2 * pi; f += 2 * pi / n) {
            for (g = 0; g < 2 * pi; g += 2 * pi / n) {
                NSPoint p1 = NSMakePoint(X(f), Y(f));
                NSPoint p2 = NSMakePoint(X(g), Y(g));
                path.strokeLine(p1, p2);
            }
        }
    }
    override bool acceptsFirstResponder() @selector("acceptsFirstResponder") {
        return true;
    }
    void moveUp(NSEvent event) @selector("moveUp:") {
        if (n > 0 && n < 60) {
            slider.value = ++n;
            slider.sliderAction();
        }
    }
    void moveRight(NSEvent event) @selector("moveRight:") {
        this.moveUp(event);
    }
    void moveDown(NSEvent event) @selector("moveDown:") {
        if (n > 0 && n <= 60) {
            slider.value = --n;
            slider.sliderAction();
        }
    }
    void moveLeft(NSEvent event) @selector("moveLeft:") {
        this.moveDown(event);
    }
}

extern (Objective-C)
class Slider : NSSlider {
    override static Slider alloc() @selector("alloc");
    override Slider init(NSRect) @selector("initWithFrame:");
    void setValues(int start, int min, int max) 
            @selector("setValues:min:max:") {
        this.target = this;
        this.action_ = "sliderAction";
        this.continuous = true;
        this.maxValue = max;
        this.minValue = min;
        this.value = start;
        this.sliderType = NSSliderType.Linear;
        this.vertical = false;
        drView.subview = this;
    }
    void sliderAction() @selector("sliderAction") {
        n = this.value.to!int;
        nLabel.text = format("%1.2d", n);
        drView.needsDisplay = true;
    }
}

extern (Objective-C)
class Label : NSTextField {
    override static Label alloc() @selector("alloc");
    override Label init(NSRect) @selector("initWithFrame:");
    void text(string labelStr) @selector("setValuesText:") {
        this.bgColor = NSColor.clear;
        this.bordered = false;
        this.editable = false;
        this.selectable = false;
        this.str = labelStr;
        drView.subview = this;
    }
}               
cocoa/window.d
cocoa/control.d
cocoa/menus.d