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

NSButton TypeRadio を使ってみたい

RadioButton を使ってみる。

RadioButton の Sample

サンプルコード

Powered by Prism

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

/**
 *  radbtn/source/app.d     Version 0.0.5        Radio Button Test
 */
module radbtn.main;
import core.attribute : optional, selector;
import std.stdio;
import cocoa.window;
import cocoa.control;
import cocoa.menus;

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

NSWindow win;
BezierView bzView;
string pathType, dashType;

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

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

void buildWindow() {
    appName = NSProcessInfo.processInfo.processName.toDs;
    NSApp.menu = miniMenu(appName);
    NSRect w_rect = NSMakeRect(0, 0, 300, 400);
    immutable w_style = NSWindowStyleMask.titled | 
                        NSWindowStyleMask.closable | 
                        NSWindowStyleMask.miniaturizable;
    win = NSWindow.alloc.init(w_rect, w_style, backing.buffered, false);
    win.title = (appName ~ "  (D言語)").toNs;
    win.moveTop = NSPoint(200, 900);
    ViewController vCtrler = ViewController.alloc.init;
    vCtrler.view.subview = win.contentView;
    win.makeKeyAndOrderFront = null;
    NSApp.activateIgnoringOtherApps = true;
}

void buildContents() {
   /* BezierView */
	bzView = BezierView.alloc.init(NSMakeRect(10, 110, 280, 280));
    // bzView.bgColor = NSColor.white;
	win.contentView.subview = bzView;
   /* Box */
	Box box1, box2;
	box1 = Box.alloc.init(NSMakeRect(10, 10, 135, 88));
	box2 = Box.alloc.init(NSMakeRect(155, 10, 135, 88));
	box1.setBoxTitle("Path Type");
	box2.setBoxTitle("Dash Type");
   /* Radio Button */
    RadioBtn[6] rb;
    string[6] btnTitle = ["Line", "Square", "Oval", "Solid", "10-10", "8-2-8"];
    foreach(i; 0 .. 3) {
        int j = i + 3;
        rb[i] = RadioBtn.alloc.init(NSMakeRect(0, 40 - i * 20, 100, 20));
        rb[j] = RadioBtn.alloc.init(NSMakeRect(0, 40 - i * 20, 100, 20));
        rb[i].setRadioBtn(btnTitle[i], box1, "onRadioBtnBox1");
        rb[j].setRadioBtn(btnTitle[j], box2, "onRadioBtnBox2");
    }
   /* Initial value setting */
    pathType = "Square";
    rb[1].state = StateValue.On;
    rb[3].state = StateValue.On;
}

extern (Objective-C)
class Box : NSBox {
    override static Box alloc() @selector("alloc");
    override Box init(NSRect) @selector("initWithFrame:");
    void setBoxTitle(string title) @selector("setBoxTitle:") {
        this.title = title;
        win.contentView.subView = this;
    }
}

extern (Objective-C)
class RadioBtn : NSButton, Res {
    override static RadioBtn alloc() @selector("alloc");
    override RadioBtn init(NSRect) @selector("initWithFrame:");
    bool respondsToSelector(SEL) @selector("respondsToSelector:");
	void setRadioBtn(string title, Box box, string actionStr) 
        @selector("setRadioBtn:box:act:") {
        this.title = title;
        this.type = NSButtonType.Radio;
        this.target = this;
        this.action_ = actionStr;
        box.subview = this;
    }
    void onRadioBtnBox1() @selector("onRadioBtnBox1") {
        pathType = this.title.toDs;
        bzView.needsDisplay = true;
    }
    void onRadioBtnBox2() @selector("onRadioBtnBox2") {
        dashType = this.title.toDs;
        bzView.needsDisplay = true;
    }
}

extern (Objective-C)
class BezierView : NSView {
    override static BezierView alloc() @selector("alloc");
    override BezierView init(NSRect) @selector("initWithFrame:");
    override void drawRect(NSRect r) @selector("drawRect:") {
        NSColor.white.setFill;
        NSRectFill(r);
        NSBezierPath path = NSBezierPath.bezierPath;
        path.lineWidth = 20;
        NSColor.red.stroke;
        switch (pathType) {
          case "Line":
            path = NSBezierPath.bezierPath;
            path.moveToPoint(NSPoint(50, 50));
            path.lineToPoint(NSPoint(230, 230));
            break;
          case "Square": 
            path = NSBezierPath.rect(NSMakeRect(70, 70, 140, 140));
            break;
          case "Oval":
            path = NSBezierPath.oval(NSMakeRect(50, 90, 180, 100));
            break;
          default: break;
        }
        switch (dashType) {
          case "Solid": 
            break;
          case "10-10": 
            path.dashLine([10, 10]); 
            break;
          case "8-2-8": 
            path.dashLine([8, 2, 8]); 
            break;
          default: 
            break;
        }
        path.stroke;
    }
}               
cocoa/window.d
cocoa/control.d
cocoa/menus.d