kael 0.1.1

GPU-accelerated native UI framework for Rust — build desktop apps with Metal, DirectX, and Vulkan rendering
Documentation
use crate::{DialogKind, DialogOptions};
use cocoa::base::{id, nil};
use cocoa::foundation::{NSAutoreleasePool, NSString};
use futures::channel::oneshot;
use objc::{class, msg_send, sel, sel_impl};

const NS_ALERT_STYLE_WARNING: u64 = 0;
const NS_ALERT_STYLE_INFORMATIONAL: u64 = 1;
const NS_ALERT_STYLE_CRITICAL: u64 = 2;
const NS_ALERT_FIRST_BUTTON_RETURN: i64 = 1000;

pub fn show_dialog(options: DialogOptions) -> oneshot::Receiver<usize> {
    let (tx, rx) = oneshot::channel();
    unsafe {
        let pool = NSAutoreleasePool::new(nil);

        let alert: id = msg_send![class!(NSAlert), new];
        let style = match options.kind {
            DialogKind::Info => NS_ALERT_STYLE_INFORMATIONAL,
            DialogKind::Warning => NS_ALERT_STYLE_WARNING,
            DialogKind::Error => NS_ALERT_STYLE_CRITICAL,
        };
        let _: () = msg_send![alert, setAlertStyle: style];

        let title = NSString::alloc(nil).init_str(options.title.as_ref());
        let _: id = msg_send![title, autorelease];
        let _: () = msg_send![alert, setMessageText: title];

        let informative = if let Some(detail) = &options.detail {
            format!("{}\n\n{}", options.message.as_ref(), detail.as_ref())
        } else {
            options.message.as_ref().to_string()
        };
        let message = NSString::alloc(nil).init_str(&informative);
        let _: id = msg_send![message, autorelease];
        let _: () = msg_send![alert, setInformativeText: message];

        for button_label in &options.buttons {
            let label = NSString::alloc(nil).init_str(button_label.as_ref());
            let _: id = msg_send![label, autorelease];
            let _: () = msg_send![alert, addButtonWithTitle: label];
        }
        if options.buttons.is_empty() {
            let ok_label = NSString::alloc(nil).init_str("OK");
            let _: id = msg_send![ok_label, autorelease];
            let _: () = msg_send![alert, addButtonWithTitle: ok_label];
        }

        let response: i64 = msg_send![alert, runModal];
        let index = (response - NS_ALERT_FIRST_BUTTON_RETURN) as usize;
        tx.send(index).ok();

        let _: () = msg_send![alert, release];
        let _: () = msg_send![pool, drain];
    }
    rx
}