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

Ulam Spiral (ウラムの螺旋)

Ulam Spiral (ウラムの螺旋)を表示してみました。

Ulam Spiral の Sample

サンプルコード

Powered by Prism

ulamspiral/dub.json

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

/**
 *  ulamspiral/source/app.d     Version 0.0.2   
 */
module ulamspiral.main;
import core.attribute : optional, selector;
import std.stdio;
import std.math : pow, sqrt;
import cocoa.window;
import cocoa.menus;

string appName;
string versionNo = "0.0.2";
string helpMessage =  "簡単なGUIアプリをCocoaAPIを使用して、\nD言語で表示しています。"
                    ~ "\n\nウラムの螺旋を表示してみました。";

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 = miniMenu(appName);
    NSRect w_rect = NSMakeRect(0, 0, 300, 300);
    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;
    DrawView dView = DrawView.alloc.init;
    vCtrl.view.subview = 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 " ~ versionNo);
    }
    void showHelp() @selector("showHelp") {
        dialog("Help", helpMessage);
    }
} 

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 DrawView : NSView {
    override static DrawView alloc() @selector("alloc");
    override DrawView init() @selector("init");
    override void drawRect(NSRect r) @selector("drawRect:") {
        double ox = r.size.width / 2;
        double oy = r.size.height / 2;
        NSColor primeColor = NSColor.blue;
        NSColor compoColor = NSColor.white;
        NSBezierPath path = NSBezierPath.bezierPath;
        NSPoint[50000] p;
        int n = 5;  // dot size
        void setDot(int ii) {
            NSRect dotRect = NSMakeRect(p[ii].x, p[ii].y, n, n);
            path.appendRect(dotRect);
            if (isPrime(ii)) 
                primeColor.fill; // prime number
            else
                compoColor.fill; // composite number
            NSRectFill(dotRect);
        }

        int i = 2, j, k = 1;
        p[1] = NSMakePoint(ox, oy);
        setDot(1);
        while (k < 222) {
            for (j = 0; j < k; j++, i++) {
                p[i] = NSMakePoint(p[i - 1].x + n, p[i - 1].y );
                setDot(i);
            }
            for (j = 0; j < k; j++, i++) {
                p[i] = NSMakePoint(p[i - 1].x, p[i - 1].y + n);
                setDot(i);
            }
            k++;
            for (j = 0; j < k; j++, i++) {
                p[i] = NSMakePoint(p[i - 1].x - n, p[i - 1].y);
                setDot(i);
            }
            for (j = 0; j < k; j++, i++) {
                p[i] = NSMakePoint(p[i - 1].x, p[i - 1].y - n);
                setDot(i);
            }
            k++;
        } 
        // writefln("i = %d  j = %d  k = %d", i, j, k);
    }
}

bool isPrime(int n) {
    if (n == 2)
        return true;
    else if (n % 2 == 0 || n < 2)
        return false;
    else
        for (int i = 3; i <= sqrt(float(n)); i += 2) 
            if (n % i == 0) 
                return false;
    return true;
}               
cocoa/window.d
cocoa/control.d
cocoa/menus.d