D言語からObjective-CとCocoaAPIを使いたい
NSSlider を使ってみたい
NSSlider を使って リサージュ曲線を表示します。

サンプルコード
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
- Log
- 2025-03-04 修正しました
- 2025-01-10 修正しました
- 2024-06-07 修正しました
- 2023-06-20 修正・更新
- 2023-05-16 修正・更新
- 2023-03-20 upload