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

NSSlider を使ってみたい

NSSlider を使って リサージュ曲線を表示します。

Lissajous' curve の Sample

サンプルコード

Powered by Prism

lissajous/dub.json

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

/**
 *  lissajous/source/app.d     Version 0.0.6
 */
module lissajous.main;
import core.attribute : optional, selector;
import std.stdio;
import std.format;
import std.conv : to;
import std.math;
import cocoa.window;
import cocoa.control;
import cocoa.menus;

string appName;
string versionNo = "0.0.6";
NSWindow win;
DrawView dView;
Slider[3] sld;
Label[3] title, val;

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

void buildWindow() {
    NSRect w_rect = NSMakeRect(0, 0, 400, 500);
    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+Cocoa)").toNs;
    win.minSize = NSSize(300, 400);
    win.moveTop = NSPoint(100, 970);
    ViewController vCtrler = ViewController.alloc.init;
    vCtrler.view.subview = win.contentView;    
    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;
        buildContents;
    }
    void aboutPanel() @selector("aboutPanel") {
        dialog(appName, "Version " ~ versionNo);
    }
    void showHelp() @selector("showHelp") {
        dialog("Help", "macOS の GUI である Cocoaを使用して、\n"
            ~ "Slider を D言語で表示しています。\n" 
            ~ "window Size を少し変えて表示すると\n"
            ~ "見やすくなります。");
    }
} 

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.set;
        NSRectFill(rect);

        CGFloat w = this.bounds.size.width / 2;
        CGFloat h = this.bounds.size.height / 2;
        CGFloat or = w < h ? w : h;
        NSRect dot;
        dot.size = NSMakeSize(2.2, 2.2);
        NSBezierPath liss = NSBezierPath.bezierPath;
        NSColor.black.set;
       // Lissajous' curve  リサージュ曲線
        double x, y, f;
        for (int i = 0; i < 7200; i++) {
            f = 2 * PI * or * i / 720;
            x = or * sin(sld[0].value * f) * sld[2].value + w - 1.1;
            y = or * sin(sld[1].value * f) * sld[2].value + h - 1.1;
            dot.origin = NSMakePoint(x, y);
            liss.fillRect(dot);
        }
    }
}

void buildContents() {
   // DrawView
    dView = DrawView.alloc.init(NSMakeRect(10, 110, 380, 380));
    dView.resizeMask = ResizeMask.Width | ResizeMask.Height;
    win.contentView.subview = dView;
   // slider title value
    for (int i = 0; i < 3; i++) {
        sld[i] = Slider.alloc.init(NSMakeRect(200, 70 - i * 30, 190, 20));
        title[i] = Label.alloc.init(NSMakeRect(10, 75 - i * 30, 120, 20));
        val[i] =  Label.alloc.init(NSMakeRect(120, 75 - i * 30, 80, 20));
        // sld[i].action = sel_registerName(("sldAction" ~ i.to!string).toCs);
        sld[i].action_ = "sldAction" ~ i.to!string; // 
        sld[i].setInitValuesMax = 99.99999;
    }
    sld[2].setInitValuesMax = 1;
    sld[0].value = 46.73534;
    sld[1].value = 43.57970;
    sld[2].value = 0.7;
    title[0].text("x = sin mθ\tm =");
    title[1].text("y = sin nθ\tn =");
    title[2].text("縮小倍率\t✕");
    for (int i = 0; i < 3; i++) {
        val[i].text(format("%3.5f", sld[i].value));
    }
}

extern (Objective-C)
class Label : NSTextField {
    override static Label alloc() @selector("alloc");
    override Label init(NSRect) @selector("initWithFrame:");
    void text(string labelStr) @selector("setValues:") {
        NSFont label_Font = NSFont.nameSize("Helvetica".toNs, 14);
        this.bgColor = NSColor.clear;
        this.bordered = false;
        this.editable = false;
        this.selectable = false;
        this.attrStr = labelStr.toAttrStr(label_Font, NSColor.darkGray);
        win.contentView.subview = this;
    }
} 

extern (Objective-C)
class Slider : NSSlider {
    override static Slider alloc() @selector("alloc");
    override Slider init(NSRect) @selector("initWithFrame:");
    void setInitValuesMax(double max) @selector("setInitValuesMax:") {
        this.target = this;
        this.continuous = false;
        this.maxValue = max;
        this.minValue = 0;
        this.sliderType = NSSliderType.Linear;
        this.trackFillColor = NSColor.lightGray;
        this.vertical = false;
        this.resizingMask = ResizingMask.WidthSizable;
        this.sizeToFit;
        win.contentView.subview = this;
    }
    void sldAction0() @selector("sldAction0") {
        val[0].text(format("%3.5f", sld[0].value));
        dView.needsDisplay = true;
    }
    void sldAction1() @selector("sldAction1") {
        val[1].text(format("%3.5f", sld[1].value));
        dView.needsDisplay = true;
    }
    void sldAction2() @selector("sldAction2") {
        val[2].text(format("%3.5f", sld[2].value));
        dView.needsDisplay = true;
    }
}               
cocoa/window.d
cocoa/control.d
cocoa/menus.d