D言語からObjective-CとCocoaAPIを使いたい
timer
Web 上の Objective-C のコードを真似て作りました。

サンプルコード
Powered by Prism
timer/dub.json
{
"authors": ["hidhok"],
"description": "A D/Objective-C Cocoa application.",
"name": "timer",
"dflags": ["-L-framework", "-LCocoa"],
"sourceFiles": ["../cocoa/window",
"../cocoa/control",
"../cocoa/datetime",
"../cocoa/menus"]
}
timer/source/app.d
/**
* timer/source/app.d Version 0.0.1 Timer App
*/
module timer.main;
import core.attribute : optional, selector;
import std.stdio;
import cocoa.window;
import cocoa.menus;
import timer.view;
string appName;
string versionNo = "0.0.1";
string helpMessage = "CocoaAPIを使用して、簡単なCocoa Appを\nD言語で表示しています。";
NSWindow win;
ViewController vCtrlr;
NSRect wRect = NSMakeRect(0, 0, 200, 100);
void main() {
NSApp.delegate_ = cast(void*) AppDelegate.alloc.init;
NSApp.activationPolicy = NSAppActivationPolicy.Regular;
NSApp.run;
}
void buildWindow() {
appName = NSProcessInfo.processInfo.processName.toDs;
NSApp.menu = miniMenu(appName);
immutable wStyle = WinStyle.Titled | WinStyle.Closable;
win = NSWindow.alloc.init(wRect, wStyle, backing.Buffered, false);
win.title = (appName ~ " (D言語)").toNs;
dView = DrawView.alloc.init;
win.contentView = dView;
vCtrlr = ViewController.alloc.init;
vCtrlr.view.subview = dView;
win.center;
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", helpMessage);
}
}
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");
}
}
timer/source/view.d
/**
* timer/source/view.d
*/
module timer.view;
import core.attribute : optional, selector;
import std.stdio;
import std.format;
import cocoa.window;
import cocoa.control;
import cocoa.datetime;
import timer.main;
DrawView dView;
string timeString;
NSTimer tm;
Label label;
Button btn1, btn2;
int cnt = 0;
NSRect lRect = NSMakeRect(0, 40, 200, 50);
NSRect b1Rect = NSMakeRect(10, 10, 100, 25);
NSRect b2Rect = NSMakeRect(120, 10, 70, 25);
void buildContents() {
timeString = format(" %.1f", 0.0);
label = Label.alloc.init(lRect);
NSFont font = NSFont.nameSize("Menlo Regular".toNs, 40); //
label.attrStr = timeString.toAttrStr(font, NSColor.blue);
label.setValues;
btn1 = Button.alloc.init(b1Rect);
btn1.setButton("Start", NSColor.teal, "onClickedButton");
btn2 = Button.alloc.init(b2Rect);
btn2.setButton("Reset", NSColor.green, "resetButton");
}
extern (Objective-C)
class DrawView : NSView {
override static DrawView alloc() @selector("alloc");
override DrawView init() @selector("init");
override void drawRect(NSRect rectFrame) @selector("drawRect:") {
NSColor.white.set;
NSRectFill(rectFrame);
}
}
extern (Objective-C)
class Label : NSTextField {
override static Label alloc() @selector("alloc");
override Label init(NSRect) @selector("initWithFrame:");
void setValues() @selector("setValues") {
this.editable = false;
this.selectable = false;
this.bordered = false;
this.drawsBg = true;
this.bgColor = NSColor.clear;
this.resizeMask = ResizeMask.Width | ResizeMask.Height;
dView.subview = this;
}
}
extern (Objective-C)
class Button : NSButton {
override static Button alloc() @selector("alloc");
override Button init(NSRect) @selector("initWithFrame:");
void setButton(string title, NSColor color, string action)
@selector("setButtonTitle:color:action:") {
this.title = title;
this.bezelStyle = BezelStyle.Push;
this.bezelColor = color;
this.bordered = true;
this.target = this;
this.action_ = action;
dView.subview = this;
}
void onClickedButton() @selector("onClickedButton") {
if (btn1.title.toDs == "Start") {
tm = btn1.startTimer("onTimerTick", 0.1);
NSRunLoop.main.add(tm, "NSDefaultRunLoopMode".toNs);
btn1.title = "Stop";
btn1.bezelColor = NSColor.red;
} else {
tm.invalidate;
btn1.title = "Start";
btn1.bezelColor = NSColor.teal;
}
}
void resetButton() @selector("resetButton") {
if (btn1.title.toDs == "Start") {
timeString = format(" %.1f", 0.0);
cnt = 0;
this.reDraw(timeString);
}
}
void onTimerTick() @selector("onTimerTick") {
timeString = format("%7.1f", ++cnt / 10.0);
this.reDraw(timeString);
}
void reDraw(string str) @selector("reDraw:") {
NSFont font = NSFont.nameSize("Menlo Regular".toNs, 40); //
label.attrStr = str.toAttrStr(font, NSColor.blue);
dView.needsDisplay = true;
}
}
NSTimer startTimer(NSObject oj, string s, NSTimeInterval ti) {
return NSTimer.scheduledTimer(ti, oj, sel_registerName(s.toCs), null, true);
}
cocoa/datetime.d
cocoa/window.d
cocoa/control.d
cocoa/menus.d
- Log
- 2025-05-21 upload