Repository: servo/core-foundation-rs (language: rust)

Issue:
Missing NSColors
I was looking for changing the NSWindow background color.
Found setBackgroundColor_ and NSColor, but there is no white or any color, only clearColor.

I didn't even find a function to create a color.
How can i change the background ? Did i miss something ?


Discussion / hints:
https://github.com/servo/core-foundation-rs/issues/184

Fix patch:
diff --git a/cocoa/examples/color.rs b/cocoa/examples/color.rs
new file mode 100644
index 000000000..2cacbfc5d
--- /dev/null
+++ b/cocoa/examples/color.rs
@@ -0,0 +1,120 @@
+extern crate cocoa;
+
+use cocoa::base::{selector, id, nil, NO};
+
+use cocoa::foundation::{NSRect, NSPoint, NSSize, NSAutoreleasePool, NSProcessInfo,
+                        NSString};
+use cocoa::appkit::{NSApp, NSColor, NSColorSpace, NSApplication, NSApplicationActivationPolicyRegular,
+                    NSMenu, NSMenuItem, NSWindowStyleMask, NSBackingStoreType, NSWindow,
+                    NSRunningApplication, NSApplicationActivateIgnoringOtherApps};
+
+
+fn main() {
+    unsafe {
+        // Create the app.
+        let app = create_app();
+        
+        // Create some colors
+        let clear = NSColor::clearColor(nil);
+        let black = NSColor::colorWithRed_blue_green_alpha_(nil, 0.0, 0.0, 0.0, 1.0);
+        let srgb_red = NSColor::colorWithSRGBRed_blue_green_alpha_(nil, 1.0, 0.0, 0.0, 1.0);
+        let device_green = NSColor::colorWithDeviceRed_blue_green_alpha_(nil, 0.0, 1.0, 0.0, 1.0);
+        let display_p3_blue = NSColor::colorWithDisplayP3Red_blue_green_alpha_(nil, 0.0, 0.0, 1.0, 1.0);
+        let calibrated_cyan = NSColor::colorWithCalibratedRed_blue_green_alpha_(nil, 0.0, 1.0, 1.0, 1.0);
+
+        // Create windows with different color types.
+        let _win_clear = create_window(NSString::alloc(nil).init_str("clear"), clear);
+        let _win_black = create_window(NSString::alloc(nil).init_str("black"), black);
+        let _win_srgb_red = create_window(NSString::alloc(nil).init_str("srgb_red"), srgb_red);
+        let _win_device_green = create_window(NSString::alloc(nil).init_str("device_green"), device_green);
+        let _win_display_p3_blue = create_window(NSString::alloc(nil).init_str("display_p3_blue"), display_p3_blue);
+        let _win_calibrated_cyan = create_window(NSString::alloc(nil).init_str("calibrated_cyan"), calibrated_cyan);
+
+        // Extract component values from a color.
+        // NOTE: some components will raise an exception if the color is not
+        // in the correct NSColorSpace. Refer to Apple's documentation for details.
+        // https://developer.apple.com/documentation/appkit/nscolor?language=objc
+        let my_color = NSColor::colorWithRed_blue_green_alpha_(nil, 0.25, 0.75, 0.5, 0.25);
+        println!("alphaComponent: {:?}", my_color.alphaComponent());
+        println!("redComponent: {:?}", my_color.redComponent());
+        println!("greenComponent: {:?}", my_color.greenComponent());
+        println!("blueComponent: {:?}", my_color.blueComponent());
+        println!("hueComponent: {:?}", my_color.hueComponent());
+        println!("saturationComponent: {:?}", my_color.saturationComponent());
+        println!("brightnessComponent: {:?}", my_color.brightnessComponent());
+        
+        // Changing color spaces.
+        let my_color_cmyk_cs = my_color.colorUsingColorSpace_(NSColorSpace::deviceCMYKColorSpace(nil));
+        println!("blackComponent: {:?}", my_color_cmyk_cs.blackComponent());
+        println!("cyanComponent: {:?}", my_color_cmyk_cs.cyanComponent());
+        println!("magentaComponent: {:?}", my_color_cmyk_cs.magentaComponent());
+        println!("yellowComponent: {:?}", my_color_cmyk_cs.yellowComponent());
+
+        // Getting NSColorSpace name.
+        let cs = NSColorSpace::genericGamma22GrayColorSpace(nil);
+        let cs_name = cs.localizedName();
+        let cs_name_bytes = cs_name.UTF8String() as *const u8;
+        let cs_name_string = std::str::from_utf8(std::slice::from_raw_parts(cs_name_bytes, cs_name.len())).unwrap();
+        println!("NSColorSpace: {:?}", cs_name_string);
+
+        // Creating an NSColorSpace from CGColorSpaceRef.
+        let cg_cs = cs.CGColorSpace();
+        let cs = NSColorSpace::alloc(nil).initWithCGColorSpace_(cg_cs);
+        let cs_name = cs.localizedName();
+        let cs_name_bytes = cs_name.UTF8String() as *const u8;
+        let cs_name_string = std::str::from_utf8(std::slice::from_raw_parts(cs_name_bytes, cs_name.len())).unwrap();
+        println!("initWithCGColorSpace_: {:?}", cs_name_string);
+
+        app.run();
+    }
+}
+
+unsafe fn create_window(title: id, color: id) -> id {
+    let window = NSWindow::alloc(nil).initWithContentRect_styleMask_backing_defer_(
+		NSRect::new(NSPoint::new(0., 0.), NSSize::new(200., 200.)),
+		NSWindowStyleMask::NSTitledWindowMask |
+            NSWindowStyleMask::NSClosableWindowMask |
+            NSWindowStyleMask::NSResizableWindowMask |
+            NSWindowStyleMask::NSMiniaturizableWindowMask |
+            NSWindowStyleMask::NSUnifiedTitleAndToolbarWindowMask,
+		NSBackingStoreType::NSBackingStoreBuffered,
+		NO
+	).autorelease();
+
+    window.cascadeTopLeftFromPoint_(NSPoint::new(20., 20.));
+    window.setTitle_(title);
+    window.setBackgroundColor_(color);
+    window.makeKeyAndOrderFront_(nil);
+    window
+}
+
+unsafe fn create_app() -> id {
+    let _pool = NSAutoreleasePool::new(nil);
+
+    let app = NSApp();
+    app.setActivationPolicy_(NSApplicationActivationPolicyRegular);
+
+    // create Menu Bar
+    let menubar = NSMenu::new(nil).autorelease();
+    let app_menu_item = NSMenuItem::new(nil).autorelease();
+    menubar.addItem_(app_menu_item);
+    app.setMainMenu_(menubar);
+
+    // create Application menu
+    let app_menu = NSMenu::new(nil).autorelease();
+    let quit_prefix = NSString::alloc(nil).init_str("Quit ");
+    let quit_title =
+        quit_prefix.stringByAppendingString_(NSProcessInfo::processInfo(nil).processName());
+    let quit_action = selector("terminate:");
+    let quit_key = NSString::alloc(nil).init_str("q");
+    let quit_item = NSMenuItem::alloc(nil)
+        .initWithTitle_action_keyEquivalent_(quit_title, quit_action, quit_key)
+        .autorelease();
+    app_menu.addItem_(quit_item);
+    app_menu_item.setSubmenu_(app_menu);
+
+    let current_app = NSRunningApplication::currentApplication(nil);
+    current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps);
+
+    return app;
+}
diff --git a/cocoa/src/appkit.rs b/cocoa/src/appkit.rs
index d55456c77..a2a8acb7d 100644
--- a/cocoa/src/appkit.rs
+++ b/cocoa/src/appkit.rs
@@ -3825,16 +3825,166 @@ impl NSLayoutDimension for id {
     unsafe fn constraintGreaterThanOrEqualToConstant(self, c: CGFloat) -> id {
         msg_send![self, constraintGreaterThanOrEqualToConstant:c]
     }
- }
+}
+
+pub trait NSColorSpace: Sized {
+    unsafe fn deviceRGBColorSpace(_:Self) -> id;
+    unsafe fn genericRGBColorSpace(_:Self) -> id;
+    unsafe fn deviceCMYKColorSpace(_:Self) -> id;
+    unsafe fn genericCMYKColorSpace(_:Self) -> id;
+    unsafe fn deviceGrayColorSpace(_:Self) -> id;
+    unsafe fn genericGrayColorSpace(_:Self) -> id;
+    unsafe fn sRGBColorSpace(_:Self) -> id;
+    unsafe fn extendedSRGBColorSpace(_:Self) -> id;
+    unsafe fn displayP3ColorSpace(_:Self) -> id;
+    unsafe fn genericGamma22GrayColorSpace(_:Self) -> id;
+    unsafe fn extendedGenericGamma22GrayColorSpace(_:Self) -> id;
+    unsafe fn adobeRGB1998ColorSpace(_:Self) -> id;
+
+    unsafe fn alloc(_: Self) -> id;
+
+    unsafe fn initWithCGColorSpace_(self, cg_color_space: *const c_void /* (CGColorSpaceRef) */) -> id;
+    unsafe fn CGColorSpace(self) -> *const c_void /* (CGColorSpaceRef) */;
+    unsafe fn localizedName(self) -> id;
+}
+
+impl NSColorSpace for id {
+    unsafe fn deviceRGBColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), deviceRGBColorSpace]
+    }
+    unsafe fn genericRGBColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), genericRGBColorSpace]
+    }
+    unsafe fn deviceCMYKColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), deviceCMYKColorSpace]
+    }
+    unsafe fn genericCMYKColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), genericCMYKColorSpace]
+    }
+    unsafe fn deviceGrayColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), deviceGrayColorSpace]
+    }
+    unsafe fn genericGrayColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), genericGrayColorSpace]
+    }
+    unsafe fn sRGBColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), sRGBColorSpace]
+    }
+    unsafe fn extendedSRGBColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), extendedSRGBColorSpace]
+    }
+    unsafe fn displayP3ColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), displayP3ColorSpace]
+    }
+    unsafe fn genericGamma22GrayColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), genericGamma22GrayColorSpace]
+    }
+    unsafe fn extendedGenericGamma22GrayColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), extendedGenericGamma22GrayColorSpace]
+    }
+    unsafe fn adobeRGB1998ColorSpace(_:Self) -> id {
+        msg_send![class!(NSColorSpace), adobeRGB1998ColorSpace]
+    }
+
+    unsafe fn alloc(_: Self) -> id {
+        msg_send![class!(NSColorSpace), alloc]
+    }
+
+    unsafe fn initWithCGColorSpace_(self, cg_color_space: *const c_void /* (CGColorSpaceRef) */) -> id {
+        msg_send![self, initWithCGColorSpace:cg_color_space]
+    }
+    unsafe fn CGColorSpace(self) -> *const c_void /* (CGColorSpaceRef) */ {
+        msg_send![self, CGColorSpace]
+    }
+    unsafe fn localizedName(self) -> id {
+        msg_send![self, localizedName]
+    }
+}
 
 pub trait NSColor: Sized {
     unsafe fn clearColor(_: Self) -> id;
+    unsafe fn colorWithRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id;
+    unsafe fn colorWithSRGBRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id;
+    unsafe fn colorWithDeviceRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id;
+    unsafe fn colorWithDisplayP3Red_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id;
+    unsafe fn colorWithCalibratedRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id;
+
+    unsafe fn colorUsingColorSpace_(self, color_space: id) -> id;
+
+    unsafe fn alphaComponent(self) -> CGFloat;
+    unsafe fn whiteComponent(self) -> CGFloat;
+    unsafe fn redComponent(self) -> CGFloat;
+    unsafe fn greenComponent(self) -> CGFloat;
+    unsafe fn blueComponent(self) -> CGFloat;
+    unsafe fn cyanComponent(self) -> CGFloat;
+    unsafe fn magentaComponent(self) -> CGFloat;
+    unsafe fn yellowComponent(self) -> CGFloat;
+    unsafe fn blackComponent(self) -> CGFloat;
+    unsafe fn hueComponent(self) -> CGFloat;
+    unsafe fn saturationComponent(self) -> CGFloat;
+    unsafe fn brightnessComponent(self) -> CGFloat;
 }
 
 impl NSColor for id {
     unsafe fn clearColor(_: Self) -> id {
         msg_send![class!(NSColor), clearColor]
     }
+    unsafe fn colorWithRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id {
+        msg_send![class!(NSColor), colorWithRed:r green:g blue:b alpha:a]
+    }
+    unsafe fn colorWithSRGBRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id {
+        msg_send![class!(NSColor), colorWithSRGBRed:r green:g blue:b alpha:a]
+    }
+    unsafe fn colorWithDeviceRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id {
+        msg_send![class!(NSColor), colorWithDeviceRed:r green:g blue:b alpha:a]
+    }
+    unsafe fn colorWithDisplayP3Red_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id {
+        msg_send![class!(NSColor), colorWithDisplayP3Red:r green:g blue:b alpha:a]
+    }
+    unsafe fn colorWithCalibratedRed_blue_green_alpha_(_:Self, r: CGFloat, b: CGFloat, g: CGFloat, a: CGFloat) -> id {
+        msg_send![class!(NSColor), colorWithCalibratedRed:r green:g blue:b alpha:a]
+    }
+
+    unsafe fn colorUsingColorSpace_(self, color_space: id) -> id {
+        msg_send![self, colorUsingColorSpace:color_space]
+    }
+
+    unsafe fn alphaComponent(self) -> CGFloat {
+        msg_send![self, alphaComponent]
+    }
+    unsafe fn whiteComponent(self) -> CGFloat {
+        msg_send![self, whiteComponent]
+    }
+    unsafe fn redComponent(self) -> CGFloat {
+        msg_send![self, redComponent]
+    }
+    unsafe fn greenComponent(self) -> CGFloat {
+        msg_send![self, greenComponent]
+    }
+    unsafe fn blueComponent(self) -> CGFloat {
+        msg_send![self, blueComponent]
+    }
+    unsafe fn cyanComponent(self) -> CGFloat {
+        msg_send![self, cyanComponent]
+    }
+    unsafe fn magentaComponent(self) -> CGFloat {
+        msg_send![self, magentaComponent]
+    }
+    unsafe fn yellowComponent(self) -> CGFloat {
+        msg_send![self, yellowComponent]
+    }
+    unsafe fn blackComponent(self) -> CGFloat {
+        msg_send![self, blackComponent]
+    }
+    unsafe fn hueComponent(self) -> CGFloat {
+        msg_send![self, hueComponent]
+    }
+    unsafe fn saturationComponent(self) -> CGFloat {
+        msg_send![self, saturationComponent]
+    }
+    unsafe fn brightnessComponent(self) -> CGFloat {
+        msg_send![self, brightnessComponent]
+    }
 }
 
 pub trait NSToolbar: Sized {


Test patch: