D言語からObjective-CとCocoaAPIを使いたい
Quartz2D Test Program
Quart2D (Quartz View) のグラフィックを D/Cocoa で動かしてみました。
プログラムソースは、Apple Documentation Archive : Quartz 2D Programming Guideです。

サンプルコード
Powered by Prism
quartzview/dub.json
{
"authors": ["hidhok"],
"description": "A D/Objective-C Cocoa application.",
"name": "QuartzView",
"dflags": ["-L-framework", "-LCocoa"],
"sourceFiles": ["../cocoa/window",
"../cocoa/control",
"../cocoa/graphics",
"../cocoa/menus"]
}
quartzview/source/app.d
/**
* quartzview/source/app.d Version 0.0.3 Quartz View Sample Program
* Apple Documentation Archive : Quartz 2D Programming Guide
*/
module quartzview.main;
import core.attribute : optional, selector;
import std.stdio;
import cocoa.window;
import cocoa.control;
import cocoa.menus;
import quartzview.view;
string appName;
string versionNo = "0.0.3";
string helpMessage = "簡単な Quartz View を\nCocoaAPI "
~ "を使用して、\nD言語で表示しています。";
NSWindow win;
// ViewController vCtrl;
QuartzView qView;
void main() {
auto delegate_ = AppDelegate.alloc.init;
NSApp.delegate_ = cast(void*) delegate_;
NSApp.activationPolicy = NSAppActivationPolicy.Regular;
NSApp.run;
}
void buildMainWindow() {
appName = NSProcessInfo.processInfo.processName.toDs;
NSApp.menu = miniMenu(appName);
NSRect wRect = nR(0, 0, 300, 300);
immutable wStyle = WinStyle.Titled |
WinStyle.Closable |
WinStyle.Resizable |
WinStyle.Miniaturizable;
win = NSWindow.alloc.init(wRect, wStyle, NSBacking.Buffered, false);
win.title = (appName ~ " (D言語)").toNs;
// vCtrl = ViewController.alloc.init;
qView = QuartzView.alloc.init;
// vCtrl.view.subview = qView;
win.contentView = qView;
// win.bgColor = NSColor.white;
win.minSize = nS(150, 100);
win.moveTop = nP(150, 900);
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:") {
buildMainWindow;
}
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");
}
} */
quartzview/source/view.d
/**
* quartzview/source/view.d
*/
module quartzview.view;
import core.attribute : optional, selector;
import std.stdio;
import cocoa.window;
import cocoa.control;
import cocoa.graphics;
import quartzview.main;
extern (Objective-C)
class QuartzView : NSView {
override static QuartzView alloc() @selector("alloc");
override QuartzView init() @selector("init");
override QuartzView init(NSRect) @selector("initWithFrame:");
void draw(NSRect r) @selector("drawRect:") {
NSColor.white.set;
NSRectFill(r);
CGContextRef aContext = NSGraphicsContext.current.cgContext;
/*
CGContextSetRGBFillColor(aContext, 1, 0, 0, 1);
CGContextFillRect(aContext, CGRectMake(10, 10, 200, 100));
CGContextSetRGBFillColor(aContext, 0, 0, 1, 0.5);
CGContextFillRect(aContext, CGRectMake(10, 10, 100, 200));
*/
aContext.setRGBFillColor( 1, 0, 0, 1);
aContext.fillRect = CGRectMake(10, 10, 200, 100);
aContext.setRGBFillColor(0, 0, 1, 0.5);
aContext.fillRect = CGRectMake(10, 10, 100, 200);
}
}
cocoa/graphics.d
/**
* cocoa/graphics.d Version 0.0.2
*/
module cocoa.graphics;
import core.attribute : optional, selector;
import std.conv : to;
import cocoa.window;
import cocoa.control;
struct CGContext;
alias CGContextRef = CGContext*;
extern (Objective-C)
extern class NSGraphicsContext : NSObject {
static NSGraphicsContext graphicsContextWithAttributes(NSDictionary)
@selector("graphicsContextWithAttributes:");
static NSGraphicsContext graphicsContextWithCGContext(CGContextRef, bool)
@selector("graphicsContextWithCGContext:flipped:");
static NSGraphicsContext currentContext() @selector("currentContext");
static NSGraphicsContext current() @selector("currentContext");
CGContextRef cgContext() @selector("CGContext");
static void saveGraphicsState() @selector("saveGraphicsState");
static void restoreGraphicsState() @selector("restoreGraphicsState");
}
extern(C) void CGContextFillRect(CGContextRef c, CGRect rect);
extern(C) void CGContextSetRGBFillColor(CGContextRef c,
CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
void fillRect(CGContextRef c, CGRect rect) {
return CGContextFillRect(c, rect);
}
void setRGBFillColor(CGContextRef c, CGFloat red,
CGFloat green, CGFloat blue, CGFloat alpha) {
return CGContextSetRGBFillColor(c, red, green, blue, alpha);
}
extern (Objective-C)
extern class NSGradient : NSObject {
override static NSGradient alloc() @selector("alloc");
NSGradient initColorsLocations(NSColor, ...)
@selector("initWithColorsAndLocations:...");
NSGradient initStartColor(NSColor, NSColor)
@selector("initWithStartingColor:endingColor:");
void drawInBezierPath(NSBezierPath, CGFloat)
@selector("drawInBezierPath:angle:");
void drawFromCenter(NSPoint, CGFloat, NSPoint, CGFloat, NSUInteger)
@selector("drawFromCenter:radius:toCenter:radius:options:");
}
enum NSGradientDraws: size_t { // NSGradientDrawingOptions
None = 0,
BeforeStart = 1 << 0, // NSGradientDrawsBeforeStartingLocation
AfterEnd = 1 << 1 // NSGradientDrawsAfterEndingLocation
}
cocoa/window.d
cocoa/control.d
cocoa/menus.d
- Log
- 2025-03-27 修正しました
- 2025-03-25 修正しました
- 2025-03-24 upload