Skip to content
This repository has been archived by the owner on Mar 18, 2024. It is now read-only.

Commit

Permalink
Use Cocoa instead of GTK3 on Mac OS X
Browse files Browse the repository at this point in the history
  • Loading branch information
bekker committed Mar 17, 2018
1 parent bdada26 commit 2614def
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 79 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ All the other jobs stop until the user responds. It runs fine with OpenGL window
It supports multi-platform, and maintains separate dependencies per platform, thus light-weight.
- Synchronous Message Modal
- Multi-platform (Linux GTK3+, Windows and OSX so far)
- Multi-platform (Linux GTK3+, Windows and OSX)
- Light-weight
"""
repository = "https://github.com/bekker/msgbox-rs"
Expand All @@ -28,4 +28,5 @@ user32-sys = "0.2.0"
gtk = "0.1.2"

[target.'cfg(target_os = "macos")'.dependencies]
gtk = "0.1.2"
cocoa = "0.14.0"
objc = "0.2"
49 changes: 23 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@

| OS | Build Status
| -- | -----
| Linux & OSX | [![Build Status](https://travis-ci.org/bekker/msgbox-rs.svg?branch=master)](https://travis-ci.org/bekker/msgbox-rs)
| Windows |
| Linux | [![Build Status](https://travis-ci.org/bekker/msgbox-rs.svg?branch=master)](https://travis-ci.org/bekker/msgbox-rs)

![Example for windows](examples/hello_world_windows.png?raw=true "Example for windows")
![Example for Linux](examples/hello_world_linux.png?raw=true "Example for linux")

Simple, cross-platform message box GUI library.
```rust
extern crate msgbox;

All it does is to show a message box modal with a OK button, which runs synchronously.
use msgbox::IconType;

All the other jobs stop until the user responds.
It runs fine with OpenGL windows already open.
fn main() {
msgbox::create("Hello Title", "Hello World!", IconType::INFO);
}
```

<img src="examples/hello_world_windows.png?raw=true" width="200px" />

<img src="examples/hello_world_linux.png?raw=true" width="300px" />

<img src="examples/hello_world_macos.png?raw=true" width="600px" />

Simple, cross-platform message box GUI library.

All it does is to show a message box modal with an OK button, which runs synchronously.

It supports multi-platform, and maintains separate dependencies per platform, thus light-weight.

I use this library when an error occurs in OpenGL applications with [glium](https://github.com/tomaka/glium).
Example use case is to show a modal when an error occurs in OpenGL applications.

- Synchronous Message Modal
- Multi-platform (Linux GTK3+, Windows and OS X so far)
- Multi-platform (Linux GTK3+, Windows and OS X)
- Light-weight

```toml
Expand All @@ -32,10 +42,8 @@ msgbox = "0.1.0"

## Platform support
* Linux with GTK 3+ (Tested on Ubuntu Gnome 16.04)
* Windows (Tested on Windows 8.1)
* OS X

As long as [gtk](https://github.com/gtk-rs/gtk) or [winapi](https://github.com/retep998/winapi-rs) library working, any platform with it would work.
* Windows (Tested on Windows 8.1 and 10)
* OS X (Tested on MacOS 10.13.3 High Sierra)

## Dev Requirements

Expand All @@ -47,18 +55,7 @@ As long as [gtk](https://github.com/gtk-rs/gtk) or [winapi](https://github.com/r
* Windows version compatible with [winapi](https://github.com/retep998/winapi-rs)

### OS X
* `cairo gtk+3` for brew

## Usage

```rust
extern crate msgbox;

fn main() {
msgbox::create("Hello Title", "Hello World!", msgbox::IconType::INFO);
msgbox::create("Error", "Error occured at hello_world.rs:5.\nTerminating..", msgbox::IconType::ERROR);
}
```
* Tested on High Sierra 10.13.3, but it should work on 10.3+

## License
Distributed under MIT License
6 changes: 4 additions & 2 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
extern crate msgbox;

use msgbox::IconType;

fn main() {
msgbox::create("Hello Title", "Hello World!", msgbox::IconType::INFO);
msgbox::create("Error", "Error occured at hello_world.rs:5.\nTerminating..", msgbox::IconType::ERROR);
msgbox::create("Hello Title", "Hello World!", IconType::INFO);
msgbox::create("Error", "Error occured at hello_world.rs:5.\nTerminating..", IconType::ERROR);
}
Binary file added examples/hello_world_macos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 31 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
mod icon;
pub use icon::IconType;

/**
* GTK+3
*/
#[cfg(target_os = "linux")]
extern crate gtk;

#[cfg(target_os = "linux")]
mod linux;

#[cfg(target_os = "linux")]
pub use linux::create;
pub use linux::*;

/**
* Cocoa
*/
#[cfg(target_os = "macos")]
#[macro_use]
extern crate objc;

#[cfg(target_os = "macos")]
extern crate cocoa;

#[cfg(target_os = "macos")]
mod mac;
mod macos;

#[cfg(target_os = "macos")]
pub use mac::create;
pub use macos::*;

/**
* WinAPI
*/
#[cfg(target_os = "windows")]
extern crate user32;

#[cfg(target_os = "windows")]
extern crate winapi;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
pub use windows::create;
pub use windows::*;
5 changes: 2 additions & 3 deletions src/linux.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
extern crate gtk;
use self::gtk::prelude::*;
use self::gtk::{ButtonsType, DialogFlags, MessageType, MessageDialog};
use ::gtk::prelude::*;
use ::gtk::{ButtonsType, DialogFlags, MessageType, MessageDialog};

use icon::IconType;

Expand Down
37 changes: 0 additions & 37 deletions src/mac.rs

This file was deleted.

90 changes: 90 additions & 0 deletions src/macos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use ::cocoa::base::{id, nil, class};
use ::cocoa::foundation::NSString;

use icon::IconType;

/**
* cocoa-rs doesn't implement NSAlert yet (0.14.0)
* Then implement it!
* Someone would stub and implement all methods for NSAlert, and make it to the upstream?
*/

/**
* NSAlert.Style
* https://developer.apple.com/documentation/appkit/nsalert.style
*/
#[repr(u64)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum NSAlertStyle {
warning = 0, // Same visual as informational
informational = 1,
critical = 2
}

/**
* NSAlert
* https://developer.apple.com/documentation/appkit/nsalert
*/
pub trait NSAlert: Sized {
unsafe fn alloc(_: Self) -> id {
msg_send![class("NSAlert"), alloc]
}

unsafe fn init(self) -> id;
unsafe fn autorelease(self) -> id;

unsafe fn setAlertStyle(self, style: NSAlertStyle);
unsafe fn setMessageText(self, messageText: id);
unsafe fn setInformativeText(self, informativeText: id);
unsafe fn addButton(self, withTitle: id);
unsafe fn runModal(self) -> id;
}

impl NSAlert for id {
unsafe fn init(self) -> id {
msg_send![self, init]
}

unsafe fn autorelease(self) -> id {
msg_send![self, autorelease]
}

unsafe fn setAlertStyle(self, alertStyle: NSAlertStyle) {
msg_send![self, setAlertStyle: alertStyle]
}

unsafe fn setMessageText(self, messageText: id) {
msg_send![self, setMessageText: messageText]
}

unsafe fn setInformativeText(self, informativeText: id) {
msg_send![self, setInformativeText: informativeText]
}

unsafe fn addButton(self, withTitle: id) {
msg_send![self, addButtonWithTitle: withTitle]
}

unsafe fn runModal(self) -> id {
msg_send![self, runModal]
}
}

pub fn create(title:&str, content:&str, icon_type:IconType) {
let alert_style = match icon_type {
IconType::ERROR => NSAlertStyle::critical,
IconType::INFO => NSAlertStyle::informational,

// AppKit doesn't support NSAlert without any icon
IconType::NONE => NSAlertStyle::informational,
};

unsafe {
let alert = NSAlert::alloc(nil).init().autorelease();
alert.addButton(NSString::alloc(nil).init_str("OK"));
alert.setMessageText(NSString::alloc(nil).init_str(title));
alert.setInformativeText(NSString::alloc(nil).init_str(content));
alert.setAlertStyle(alert_style);
alert.runModal();
}
}
7 changes: 2 additions & 5 deletions src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
extern crate user32;
extern crate winapi;

use icon::IconType;

pub fn create(title:&str, content:&str, icon_type:IconType) {
use std::ffi::CString;
use std::ptr::null_mut;
use self::user32::MessageBoxA;
use self::winapi::winuser::{MB_OK, MB_ICONINFORMATION, MB_ICONERROR, MB_SYSTEMMODAL};
use ::user32::MessageBoxA;
use ::winapi::winuser::{MB_OK, MB_ICONINFORMATION, MB_ICONERROR, MB_SYSTEMMODAL};

let lp_text = CString::new(content).unwrap();
let lp_caption = CString::new(title).unwrap();
Expand Down

0 comments on commit 2614def

Please sign in to comment.