D言語からObjective-CとCocoaAPIを使いたい
NSColorWell を表示する
D言語から Mac の GUI を使用して NSColorWellとColorPanel を表示します。
「MacOS X プログラミング入門 Cocoa + Java (2001年)」を参考にしました。

サンプルコード
Powered by Prism
color/dub.json
{
"authors": ["hidhok"],
"description": "A D/Objective-C Cocoa application.",
"name": "color",
"dflags": ["-L-framework", "-LCocoa"],
"sourceFiles": ["../cocoa/window",
"../cocoa/control",
"../cocoa/menus"]
}
color/source/app.d
/**
* color/source/app.d Version 0.0.7
*/
module color.main;
import core.attribute : optional, selector;
import std.format;
import std.stdio;
import std.conv;
import cocoa.window;
import cocoa.control;
import cocoa.menus;
string appName;
string versionNo = "0.0.7";
View dView;
ColorWell cw;
NSTextField codeField;
void main() {
auto delegate_ = AppDelegate.alloc.init;
NSApp.delegate_ = cast(void*) delegate_;
NSApp.activationPolicy = NSAppActivationPolicy.regular;
NSApp.run;
}
void buildWindow() {
NSWindow win;
appName = NSProcessInfo.processInfo.processName.toDs;
NSApp.menu = miniMenu(appName);
NSRect w_rect = NSMakeRect(0, 0, 300, 150);
immutable w_style = NSWindowStyleMask.titled |
NSWindowStyleMask.closable |
NSWindowStyleMask.miniaturizable;
win = NSWindow.alloc.init(w_rect, w_style, NSBacking.buffered, false);
win.title = (appName ~ " (ColorWell Test)").toNs;
win.moveTop = NSPoint(400, 900);
ViewController vCtrler = ViewController.alloc.init;
dView = View.alloc.init;
vCtrler.view.subview = dView;
win.contentView = dView;
win.makeKeyAndOrderFront = null;
NSApp.activateIgnoringOtherApps = true;
}
extern (Objective-C)
class View : NSView {
override static View alloc() @selector("alloc");
override View init() @selector("init");
override View init(NSRect) @selector("initWithFrame:");
override void drawRect(NSRect) @selector("drawRect:");
}
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") {
string helpMessage = "RGBカラーコードのコピペができます。\n"
~ "アルファ(透明度)の機能は未実装です。";
dialog(appName ~ " Help", helpMessage);
}
}
void buildContents() {
// Label
NSFont labelFont = NSFont.nameSize("Helvetica".toNs, 20);
Label label1 = Label.alloc.init(NSMakeRect( 30, 110, 120, 20));
Label label2 = Label.alloc.init(NSMakeRect(160, 110, 120, 20));
Label label3 = Label.alloc.init(NSMakeRect(170, 70, 100, 20));
dView.subview = label1.textVal("Color Well", labelFont);
dView.subview = label2.textVal("Color Code", labelFont);
dView.subview = label3.textVal("R G B α", labelFont);
// ColorWell
cw = ColorWell.alloc.init(NSMakeRect(30, 30, 100, 60));
cw.setColorWellValues;
// Field
codeField = NSTextField.alloc.init(NSMakeRect(150, 30, 120, 30));
cw.setColorCode;
}
extern (Objective-C)
class ColorWell : NSColorWell {
override static ColorWell alloc() @selector("alloc");
override ColorWell init(NSRect r) @selector("initWithFrame:");
void setColorWellValues() @selector("setColorWellValues") {
this.bordered = false;
this.activate = true;
this.target = this;
// this.action = sel_registerName("setColorCode".toCs); //
this.action_ = "setColorCode"; //
dView.subview = this;
}
void setColorCode() @selector("setColorCode") {
codeField.font = NSFont.nameSize("Monaco".toNs, 20);
codeField.target = this;
// codeField.action = sel_registerName("readCode".toCs); //
codeField.action_ = "readCode"; //
ColorEncoder ce = new ColorEncoder;
ce.encode = this;
dView.subview = codeField;
}
void readCode() @selector("readCode") {
string s = codeField.str.toDs;
// 入力無効文字の排除処理
if (s.length == 0) s = "#ffffffff";
if ('#' != s[0]) s = '#' ~ s;
if (s.length > 8) s = s[0..9];
if (s.length < 8) {
while (s.length < 9) {
s ~= "f";
}
}
string ss = "#";
foreach (i; 1..9) {
if ((s[i] >= '0' && s[i] <= '9')
|| (s[i] >= 'A' && s[i] <= 'F')
|| (s[i] >= 'a' && s[i] <= 'f')) {
ss ~= s[i];
} else {
ss ~= "f";
}
}
s = ss;
// Color Code に変換し表示
double r = s[1..3].strToDouble / 255.9999;
double g = s[3..5].strToDouble / 255.9999;
double b = s[5..7].strToDouble / 255.9999;
// double a = s[7..9].strToDouble / 255.9999;
double a = "ff".strToDouble / 255.9999;
this.color(NSColor.colorRGB(r, g, b, a));
string str = '#' ~ s[1..7] ~ "ff";
codeField.attrStr = str.toAttrStr(null, NSColor.darkGray);
}
}
double strToDouble(string s) { // 16進数文字列をdoubleに変換する
return (parse!(int)(s, 16)).to!double;
}
class ColorEncoder {
void encode(ColorWell cw) {
NSColor color = cw.color.spaceName(DeRGB.toNs); // NSColorSpaceName
int r = cast(int)(color.redComponent * 255.9999);
int g = cast(int)(color.greenComponent * 255.9999);
int b = cast(int)(color.blueComponent * 255.9999);
int a = cast(int)(color.alphaComponent * 255.9999);
string fieldStr = format("#%02x%02x%02x%02x", r, g, b, a);
NSFont font = NSFont.nameSize("Monaco".toNs, 20);
codeField.attrStr = fieldStr.toAttrStr(font, NSColor.darkGray);
}
}
extern (Objective-C)
class Label : NSTextField {
override static Label alloc() @selector("alloc");
override Label init(NSRect) @selector("initWithFrame:");
Label textVal(string labelStr, NSFont font) @selector("setValues:font:") {
this.bgColor = NSColor.clear;
this.bordered = false;
this.editable = false;
this.selectable = false;
this.attrStr = labelStr.toAttrStr(font, NSColor.darkGray);
return this;
}
}
cocoa/window.d
cocoa/control.d
cocoa/menus.d
- Log
- 2025-03-04 修正しました
- 2024-06-07 修正しました
- 2023-10-12 修正しました
- 2023-01-24 修正しました
- 2023-01-14 修正しました
- 2022-12-22 version up
- 2022-11-30 upload