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

画像を表示する

D言語から Mac の GUI を使用して 画像を表示します。

NSImageのSample

サンプルコード

Powered by Prism

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

/**
 *      iview/source/app.d     Version 0.0.4
 */
module iview.main;
import core.attribute : optional, selector;
import std.conv : to;
import std.stdio;
import cocoa.window;
import cocoa.menus;

string appName;
string versionNo = "0.0.4";
string helpMessage = "CocoaAPIを使用して、jpg画像を\nD言語で表示しています。";
string urlStr = "http://horkew.la.coocan.jp/D+CocoAPI/rainbow.jpg";

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("iview 画像表示", 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, NSBacking.buffered, false);
    win.minSize = NSSize(200, 100);
    win.title = (appName ~ " (D言語テスト)").toNs;
    ViewController vCtrler = ViewController.alloc.init;
    DrawView dView = DrawView.alloc.init;
    vCtrler.view.subview = dView;
    win.contentView = dView;
    // dView.bgColor = NSColor.white;
    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:") {
        void print(string str, CGFloat x, CGFloat y) { 
            str.toNs.draw(NSMakePoint(x, y), null); }
           
        NSColor.white.setFill;
        NSRectFill(rect);
    /*
        NSBundle bundle = NSBundle.mainBundle();
        NSString path = bundle.path("rainbow".toNs, "jpg".toNs);
        NSImage image = NSImage.alloc.init(path);
    */
        string urlStr = "http://horkew.la.coocan.jp/D+CocoAPI/rainbow.jpg";
        NSURL nsUrlPath = NSURL.toNsURL(urlStr.toNs);
        NSImage image = NSImage.alloc.init(nsUrlPath);

        double w = rect.size.width, h = rect.size.height;
        double r = image.size.width / image.size.height;
        double x = rect.origin.x,   y = rect.origin.y;
        double x0 = w / 2,          y0 = h / 2;
        if (w > h * r) { w = h * r; x = x0 - w / 2; } 
        else { h = w / r; y = y0 - h / 2; }
        image.draw(NSMakeRect(x, y, w, h));
        string str = "支笏湖でバラした Big Rainbow  " ~ 
                    " W:" ~ (cast(int)w).to!string ~ 
                    " H:" ~ (cast(int)h).to!string;
        print(str, 20, 0);
    }
}

extern (Objective-C)
extern class NSImage {
    static NSImage alloc() @selector("alloc");
    NSImage init(NSString) @selector("initWithContentsOfFile:");
    NSImage init(NSURL) @selector("initWithContentsOfURL:");
    void draw(NSRect) @selector("drawInRect:");
    void draw(NSPoint, NSRect, NSUInteger, CGFloat)
        @selector("drawAtPoint:fromRect:operation:fraction:");
    NSSize size() @selector("size");
    // void drawInRect(NSRect, NSRect, NSUInteger, CGFloat, BOOL, NSDictionary)
    //     @selector("drawInRect:fromRect:operation:fraction:respectFlipped, hints");
    // void drawRepresentation() @selector("drawRepresentation:inRect:");
    // void setScale(NSUInteger) @selector("setImageScaling:");
}

extern (Objective-C) 
extern class NSURL {
    static NSURL urlPath(NSString) @selector("fileURLWithPath:");
    static NSURL url(NSString, NSURL) @selector("URLWithString:relativeToURL:");
    NSString toNsStr() @selector("absoluteString");
    static NSURL toNsURL(NSString) @selector("URLWithString:");
}

extern (Objective-C)
extern class NSBundle : NSObject {
    static NSBundle mainBundle() @selector("mainBundle");
    NSString path(NSString, NSString) @selector("pathForResource:ofType:");
    NSString url(NSString) @selector("bundleWithURL:");
}               
cocoa/window.d
cocoa/control.d
cocoa/menus.d