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

Apple Documents の Cocoa Drawing Guide の中から、Advanced Drawing Techniques の Creating Gradient Fills のサンプルを D言語に置き換えてみました。

NSGradientのSample

NSGradientのSample

サンプルコード

Powered by Prism

ball/dub.json

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

/**
 *   ball/source/app.d        Version 0.0.5
 */
module ball.main;
import core.attribute : selector;
import std.algorithm : min;
import std.stdio;
import cocoa.window;
import cocoa.menus;

string appName;
string versionNo = "0.0.5";
string helpMessage =  "CocoaAPIを使用して、簡単なWindowを\nD言語で表示しています。";

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;
    }
    void aboutPanel() @selector("aboutPanel") {
        dialog(appName, "Version " ~ versionNo);
    }
    void showHelp() @selector("showHelp") {
        dialog("Help", helpMessage);
    }
} 

void buildWindow() {
    NSWindow win;
    NSRect w_rect = NSMakeRect(0, 0, 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.minSize = NSMakeSize(200, 100);
    win.title = (appName ~ " (D言語テスト)").toNs;
    ViewController vCtrler = ViewController.alloc.init;
    DrawView dView = DrawView.alloc.init;
    vCtrler.view.subview = dView;
    win.contentView = dView;
    win.moveTop = NSPoint(100, 970);
    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\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 DrawView init(NSRect) @selector("initWithFrame:"); 
    override void drawRect(NSRect rect) @selector("drawRect:") {
        NSColor.white.setFill; 
        NSRectFill(rect);

        NSRect bounds = NSMakeRect(rect.origin.x + 50, rect.origin.y + 50, 
            rect.size.width - 100, rect.size.height - 100);
        NSGradient aGradient = NSGradient.alloc.initStartColor(
            NSColor.orange, NSColor.cyan);

        NSPoint centerPoint = NSMakePoint(
            rect.size.width / 2, rect.size.height / 2);
        NSPoint otherPoint = NSMakePoint(centerPoint.x + 60.0,
                                         centerPoint.y + 60.0);
        CGFloat firstRadius = min( ((bounds.size.width  / 2.0) - 2.0),
                                   ((bounds.size.height / 2.0) - 2.0) );
        aGradient.drawFromCenter(centerPoint, firstRadius, 
            otherPoint, 5.0, NSGradientDraws.AfterEnd);                            
    }
}

extern (Objective-C)
extern class NSGradient : NSObject {
    override static NSGradient alloc() @selector("alloc");
    NSGradient initColorsLocations(NSColor, ...) 
        @selector("initWithColorsAndLocations:...");
    NSGradient initStartColor(NSColor, NSColor) 
        @selector("initWithStartingColor:endingColor:");
    void drawInBezierPath(NSBezierPath, CGFloat) 
        @selector("drawInBezierPath:angle:");
    void drawFromCenter(NSPoint, CGFloat, NSPoint, CGFloat, NSUInteger) 
        @selector("drawFromCenter:radius:toCenter:radius:options:");
}

enum NSGradientDraws: size_t {  // NSGradientDrawingOptions
    None         = 0,
    BeforeStart  = 1 << 0,      // NSGradientDrawsBeforeStartingLocation
    AfterEnd     = 1 << 1       // NSGradientDrawsAfterEndingLocation
}               
cocoa/window.d
cocoa/control.d
cocoa/menus.d