From 054a56d3ed8a0e2dd03d9e2059a1accafa54b593 Mon Sep 17 00:00:00 2001 From: Adrien Navratil Date: Thu, 2 May 2019 19:28:52 +0200 Subject: [PATCH 1/2] Added delegate! macro --- cocoa/src/lib.rs | 2 ++ cocoa/src/macros.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 cocoa/src/macros.rs diff --git a/cocoa/src/lib.rs b/cocoa/src/lib.rs index 179c0d3..4c5cce0 100644 --- a/cocoa/src/lib.rs +++ b/cocoa/src/lib.rs @@ -28,3 +28,5 @@ pub mod base; pub mod foundation; #[cfg(target_os = "macos")] pub mod quartzcore; +#[macro_use] +mod macros; diff --git a/cocoa/src/macros.rs b/cocoa/src/macros.rs new file mode 100644 index 0000000..c178a26 --- /dev/null +++ b/cocoa/src/macros.rs @@ -0,0 +1,75 @@ +// Copyright 2013 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// Creates a Cocoa delegate to use e.g. with `NSWindow.setDelegate_`. +/// Adds instance variables and methods to the definition. +/// +/// # Example with NSWindowDelegate +/// ``` no_run +/// #[macro_use] extern crate cocoa; +/// #[macro_use] extern crate objc; +/// +/// use cocoa::appkit::NSWindow; +/// use cocoa::base::nil; +/// +/// # unsafe fn main() { +/// let my_window: id = NSWindow::alloc(nil); +/// +/// extern fn on_enter_fullscreen(this: &Object, _cmd: Sel, _notification: id) { +/// unsafe { +/// let window: id = *this.get_ivar("window"); +/// window.setToolbar_(nil); +/// } +/// } +/// +/// my_window.setDelegate_(delegate!("MyWindowDelegate", { +/// window: id = my_window, // Declare instance variable(s) +/// (onWindowWillEnterFullscreen:) => on_enter_fullscreen as extern fn(&Object, Sel, id) // Declare function(s) +/// })); +/// # } +/// ``` +#[macro_export] +macro_rules! delegate { + ( + $name:expr, { + $( ($($sel:ident :)+) => $func:expr),* + } + ) => ( + delegate!($name, { + , + $( ($($sel :)+) => $func),* + }) + ); + + ( + $name:expr, { + $($var:ident : $var_type:ty = $value:expr),* , + $( ($($sel:ident :)+) => $func:expr),* + } + ) => ({ + let mut decl = objc::declare::ClassDecl::new($name, class!(NSObject)).unwrap(); + + $( + decl.add_ivar::<$var_type>(stringify!($var)); + )* + + $( + decl.add_method(sel!($($sel :)+), $func); + )* + + let cl = decl.register(); + let delegate: id = msg_send![cl, alloc]; + + $( + (*delegate).set_ivar(stringify!($var), $value); + )* + + delegate + }); +} From f65f59b83aa0deaa8ffa9d02fe673499dc02e784 Mon Sep 17 00:00:00 2001 From: Adrien Navratil Date: Thu, 2 May 2019 20:05:36 +0200 Subject: [PATCH 2/2] Fixed delegate! example code --- cocoa/src/macros.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/cocoa/src/macros.rs b/cocoa/src/macros.rs index c178a26..77c6a16 100644 --- a/cocoa/src/macros.rs +++ b/cocoa/src/macros.rs @@ -16,22 +16,26 @@ /// #[macro_use] extern crate objc; /// /// use cocoa::appkit::NSWindow; -/// use cocoa::base::nil; +/// use cocoa::base::{id, nil}; /// -/// # unsafe fn main() { -/// let my_window: id = NSWindow::alloc(nil); +/// use objc::runtime::{Object, Sel}; /// -/// extern fn on_enter_fullscreen(this: &Object, _cmd: Sel, _notification: id) { -/// unsafe { -/// let window: id = *this.get_ivar("window"); -/// window.setToolbar_(nil); +/// # fn main() { +/// unsafe { +/// let my_window: id = NSWindow::alloc(nil); +/// +/// extern fn on_enter_fullscreen(this: &Object, _cmd: Sel, _notification: id) { +/// unsafe { +/// let window: id = *this.get_ivar("window"); +/// window.setToolbar_(nil); +/// } /// } -/// } /// -/// my_window.setDelegate_(delegate!("MyWindowDelegate", { -/// window: id = my_window, // Declare instance variable(s) -/// (onWindowWillEnterFullscreen:) => on_enter_fullscreen as extern fn(&Object, Sel, id) // Declare function(s) -/// })); +/// my_window.setDelegate_(delegate!("MyWindowDelegate", { +/// window: id = my_window, // Declare instance variable(s) +/// (onWindowWillEnterFullscreen:) => on_enter_fullscreen as extern fn(&Object, Sel, id) // Declare function(s) +/// })); +/// } /// # } /// ``` #[macro_export]