Run cargo fmt

This commit is contained in:
Mads Marquart 2022-07-15 16:14:02 +02:00
parent fd1a3ce26d
commit db4f2c0720
159 changed files with 1925 additions and 1820 deletions

View file

@ -9,10 +9,10 @@ use cacao::color::Color;
use cacao::layout::{Layout, LayoutConstraint, LayoutConstraintAnimatorProxy};
use cacao::view::{View, ViewAnimatorProxy};
use cacao::appkit::{App, AppDelegate, AnimationContext};
use cacao::appkit::{Event, EventMask, EventMonitor};
use cacao::appkit::menu::Menu;
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate};
use cacao::appkit::{AnimationContext, App, AppDelegate};
use cacao::appkit::{Event, EventMask, EventMonitor};
struct BasicApp {
window: Window<AppWindow>
@ -54,33 +54,26 @@ const ANIMATIONS: [[[f64; 5]; 4]; 3] = [
[44., 16., 100., 100., 1.],
[128., 84., 144., 124., 1.],
[32., 32., 44., 44., 0.7],
[328., 157., 200., 200., 0.7],
[328., 157., 200., 200., 0.7]
],
// Red
[
[44., 132., 100., 100., 1.],
[40., 47., 80., 64., 0.7],
[84., 220., 600., 109., 1.0],
[48., 600., 340., 44., 0.7],
[48., 600., 340., 44., 0.7]
],
// Green
[
[44., 248., 100., 100., 1.],
[420., 232., 420., 244., 0.7],
[310., 440., 150., 238., 0.7],
[32., 32., 44., 44., 1.],
[32., 32., 44., 44., 1.]
]
];
/// A helper method for generating frame constraints that we want to be animating.
fn apply_styles(
view: &View,
parent: &View,
background_color: Color,
animation_table_index: usize
) -> [LayoutConstraint; 4] {
fn apply_styles(view: &View, parent: &View, background_color: Color, animation_table_index: usize) -> [LayoutConstraint; 4] {
view.set_background_color(background_color);
view.layer.set_corner_radius(16.);
parent.add_subview(view);
@ -117,11 +110,14 @@ impl WindowDelegate for AppWindow {
let red_frame = apply_styles(&self.red, &self.content, Color::SystemRed, 1);
let green_frame = apply_styles(&self.green, &self.content, Color::SystemGreen, 2);
let alpha_animators = [&self.blue, &self.red, &self.green].iter().map(|view| {
view.animator.clone()
}).collect::<Vec<ViewAnimatorProxy>>();
let alpha_animators = [&self.blue, &self.red, &self.green]
.iter()
.map(|view| view.animator.clone())
.collect::<Vec<ViewAnimatorProxy>>();
let constraint_animators = [blue_frame, red_frame, green_frame].iter().map(|frame| {
let constraint_animators = [blue_frame, red_frame, green_frame]
.iter()
.map(|frame| {
LayoutConstraint::activate(frame);
vec![
@ -130,7 +126,8 @@ impl WindowDelegate for AppWindow {
frame[2].animator.clone(),
frame[3].animator.clone(),
]
}).collect::<Vec<Vec<LayoutConstraintAnimatorProxy>>>();
})
.collect::<Vec<Vec<LayoutConstraintAnimatorProxy>>>();
// Monitor key change events for w/a/s/d, and then animate each view to their correct
// frame and alpha value.
@ -175,5 +172,6 @@ impl WindowDelegate for AppWindow {
fn main() {
App::new("com.test.window", BasicApp {
window: Window::with(WindowConfig::default(), AppWindow::default())
}).run();
})
.run();
}

View file

@ -5,9 +5,9 @@ use cacao::color::{Color, Theme};
use cacao::layout::{Layout, LayoutConstraint};
use cacao::view::View;
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate};
use cacao::appkit::{App, AppDelegate};
struct BasicApp {
window: Window<AppWindow>
@ -23,23 +23,16 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
])
MenuItem::new("Bring All to Front"),
]),
]);
App::activate();
@ -89,16 +82,14 @@ impl WindowDelegate for AppWindow {
self.blue.leading.constraint_equal_to(&self.content.leading).offset(16.),
self.blue.bottom.constraint_equal_to(&self.content.bottom).offset(-16.),
self.blue.width.constraint_equal_to_constant(100.),
self.red.top.constraint_equal_to(&self.content.top).offset(46.),
self.red.leading.constraint_equal_to(&self.blue.trailing).offset(16.),
self.red.bottom.constraint_equal_to(&self.content.bottom).offset(-16.),
self.green.top.constraint_equal_to(&self.content.top).offset(46.),
self.green.leading.constraint_equal_to(&self.red.trailing).offset(16.),
self.green.trailing.constraint_equal_to(&self.content.trailing).offset(-16.),
self.green.bottom.constraint_equal_to(&self.content.bottom).offset(-16.),
self.green.width.constraint_equal_to_constant(100.),
self.green.width.constraint_equal_to_constant(100.)
]);
}
}
@ -106,5 +97,6 @@ impl WindowDelegate for AppWindow {
fn main() {
App::new("com.test.window", BasicApp {
window: Window::with(WindowConfig::default(), AppWindow::default())
}).run();
})
.run();
}

View file

@ -4,10 +4,10 @@
use cacao::notification_center::Dispatcher;
use cacao::webview::{WebView, WebViewConfig, WebViewDelegate};
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::toolbar::Toolbar;
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate, WindowToolbarStyle};
use cacao::appkit::{App, AppDelegate};
mod toolbar;
use toolbar::BrowserToolbar;
@ -39,13 +39,9 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("Edit", vec![
MenuItem::Undo,
MenuItem::Redo,
@ -54,21 +50,16 @@ impl AppDelegate for BasicApp {
MenuItem::Copy,
MenuItem::Paste,
MenuItem::Separator,
MenuItem::SelectAll
MenuItem::SelectAll,
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
MenuItem::new("Bring All to Front"),
]),
Menu::new("Help", vec![])
Menu::new("Help", vec![]),
]);
App::activate();
@ -84,9 +75,15 @@ impl Dispatcher for BasicApp {
let webview = &window.content;
match message {
Action::Back => { webview.go_back(); },
Action::Forwards => { webview.go_forward(); },
Action::Load(url) => { window.load_url(&url); }
Action::Back => {
webview.go_back();
},
Action::Forwards => {
webview.go_forward();
},
Action::Load(url) => {
window.load_url(&url);
}
}
}
}
@ -132,13 +129,17 @@ impl WindowDelegate for AppWindow {
fn main() {
App::new("com.test.window", BasicApp {
window: Window::with({
window: Window::with(
{
let mut config = WindowConfig::default();
// This flag is necessary for Big Sur to use the correct toolbar style.
config.toolbar_style = WindowToolbarStyle::Expanded;
config
}, AppWindow::new())
}).run();
},
AppWindow::new()
)
})
.run();
}

View file

@ -1,10 +1,9 @@
use cacao::objc::{msg_send, sel, sel_impl};
use cacao::button::Button;
use cacao::input::{TextField, TextFieldDelegate};
use cacao::appkit::toolbar::{Toolbar, ToolbarDisplayMode, ToolbarItem, ItemIdentifier, ToolbarDelegate};
use cacao::appkit::toolbar::{ItemIdentifier, Toolbar, ToolbarDelegate, ToolbarDisplayMode, ToolbarItem};
use super::Action;
@ -74,7 +73,7 @@ impl BrowserToolbar {
ItemIdentifier::Custom(FWDS_BUTTON),
ItemIdentifier::Space,
ItemIdentifier::Custom(URL_BAR),
ItemIdentifier::Space
ItemIdentifier::Space,
]
}
}
@ -99,7 +98,9 @@ impl ToolbarDelegate for BrowserToolbar {
BACK_BUTTON => &self.back_item,
FWDS_BUTTON => &self.forwards_item,
URL_BAR => &self.url_bar_item,
_ => { std::unreachable!(); }
_ => {
std::unreachable!();
}
}
}
}

View file

@ -1,10 +1,10 @@
use cacao::layout::{LayoutConstraint, Layout};
use cacao::button::Button;
use cacao::color::Color;
use cacao::layout::{Layout, LayoutConstraint};
use cacao::view::View;
use crate::calculator::Msg;
use crate::content_view::{button, BUTTON_WIDTH, BUTTON_HEIGHT};
use crate::content_view::{button, BUTTON_HEIGHT, BUTTON_WIDTH};
pub struct ButtonRow {
pub view: View,
@ -15,8 +15,11 @@ impl ButtonRow {
pub fn new(x: [Msg; 4], color: Color, action_color: Color) -> Self {
let view = View::new();
let buttons: Vec<Button> = x.iter().map(|y| {
let button = button(match y {
let buttons: Vec<Button> = x
.iter()
.map(|y| {
let button = button(
match y {
Msg::Clear => "C",
Msg::Add => "+",
Msg::Subtract => "-",
@ -34,12 +37,14 @@ impl ButtonRow {
Msg::Push(i) if *i == 8 => "8",
Msg::Push(i) if *i == 9 => "9",
_ => "W"
}, y.clone());
},
y.clone()
);
view.add_subview(&button);
button
}).collect();
})
.collect();
buttons[0].set_background_color(color.clone());
buttons[1].set_background_color(color.clone());
@ -53,30 +58,22 @@ impl ButtonRow {
buttons[0].leading.constraint_equal_to(&view.leading),
buttons[0].bottom.constraint_equal_to(&view.bottom),
width.constraint_equal_to_constant(BUTTON_WIDTH),
buttons[1].top.constraint_equal_to(&view.top),
buttons[1].leading.constraint_equal_to(&buttons[0].trailing).offset(1.),
buttons[1].bottom.constraint_equal_to(&view.bottom),
buttons[1].width.constraint_equal_to(&width),
buttons[2].top.constraint_equal_to(&view.top),
buttons[2].leading.constraint_equal_to(&buttons[1].trailing).offset(1.),
buttons[2].bottom.constraint_equal_to(&view.bottom),
buttons[2].width.constraint_equal_to(&width),
buttons[3].top.constraint_equal_to(&view.top),
buttons[3].leading.constraint_equal_to(&buttons[2].trailing).offset(1.),
buttons[3].trailing.constraint_equal_to(&view.trailing),
buttons[3].bottom.constraint_equal_to(&view.bottom),
buttons[3].width.constraint_equal_to(&width),
view.height.constraint_equal_to_constant(BUTTON_HEIGHT)
]);
Self {
view,
buttons
Self { view, buttons }
}
}
}

View file

@ -1,7 +1,7 @@
use std::sync::{Arc, RwLock};
use cacao::lazy_static::lazy_static;
use cacao::appkit::App;
use cacao::lazy_static::lazy_static;
use crate::CalculatorApp;
@ -92,10 +92,14 @@ impl Calculator {
println!("Expr: {}", expr);
match eval::eval(&expr) {
Ok(val) => { App::<CalculatorApp, String>::dispatch_main(val.to_string()); },
Err(e) => { eprintln!("Error parsing expression: {:?}", e); }
Ok(val) => {
App::<CalculatorApp, String>::dispatch_main(val.to_string());
},
Err(e) => {
eprintln!("Error parsing expression: {:?}", e);
}
}
},
_ => {}
}

View file

@ -1,8 +1,8 @@
use cacao::text::{Font, Label, TextAlign};
use cacao::layout::{LayoutConstraint, Layout};
use cacao::button::{Button, BezelStyle};
use cacao::color::Color;
use cacao::appkit::FocusRingType;
use cacao::button::{BezelStyle, Button};
use cacao::color::Color;
use cacao::layout::{Layout, LayoutConstraint};
use cacao::text::{Font, Label, TextAlign};
use cacao::view::{View, ViewDelegate};
use crate::button_row::ButtonRow;
@ -53,21 +53,29 @@ impl CalculatorView {
results_wrapper,
label,
row0: ButtonRow::new([
Msg::Clear, Msg::Invert, Msg::Mod, Msg::Divide
], Color::rgb(69, 69, 69), Color::rgb(255, 148, 10)),
row0: ButtonRow::new(
[Msg::Clear, Msg::Invert, Msg::Mod, Msg::Divide],
Color::rgb(69, 69, 69),
Color::rgb(255, 148, 10)
),
row1: ButtonRow::new([
Msg::Push(7), Msg::Push(8), Msg::Push(9), Msg::Multiply
], Color::rgb(100, 100, 100), Color::rgb(255, 148, 10)),
row1: ButtonRow::new(
[Msg::Push(7), Msg::Push(8), Msg::Push(9), Msg::Multiply],
Color::rgb(100, 100, 100),
Color::rgb(255, 148, 10)
),
row2: ButtonRow::new([
Msg::Push(4), Msg::Push(5), Msg::Push(6), Msg::Subtract
], Color::rgb(100, 100, 100), Color::rgb(255, 148, 10)),
row2: ButtonRow::new(
[Msg::Push(4), Msg::Push(5), Msg::Push(6), Msg::Subtract],
Color::rgb(100, 100, 100),
Color::rgb(255, 148, 10)
),
row3: ButtonRow::new([
Msg::Push(1), Msg::Push(2), Msg::Push(3), Msg::Add
], Color::rgb(100, 100, 100), Color::rgb(255, 148, 10)),
row3: ButtonRow::new(
[Msg::Push(1), Msg::Push(2), Msg::Push(3), Msg::Add],
Color::rgb(100, 100, 100),
Color::rgb(255, 148, 10)
),
zero: button("0", Msg::Push(0)),
dot: button(".", Msg::Decimal),
@ -108,38 +116,43 @@ impl ViewDelegate for CalculatorView {
self.results_wrapper.leading.constraint_equal_to(&view.leading),
self.results_wrapper.trailing.constraint_equal_to(&view.trailing),
self.results_wrapper.height.constraint_equal_to_constant(80.),
self.label.leading.constraint_equal_to(&self.results_wrapper.leading).offset(22.),
self.label.trailing.constraint_equal_to(&self.results_wrapper.trailing).offset(-16.),
self.label.bottom.constraint_equal_to(&self.results_wrapper.bottom).offset(-4.),
self.label
.leading
.constraint_equal_to(&self.results_wrapper.leading)
.offset(22.),
self.label
.trailing
.constraint_equal_to(&self.results_wrapper.trailing)
.offset(-16.),
self.label
.bottom
.constraint_equal_to(&self.results_wrapper.bottom)
.offset(-4.),
// Buttons laid out from top-left
self.row0.view.top.constraint_equal_to(&self.results_wrapper.bottom).offset(1.),
self.row0
.view
.top
.constraint_equal_to(&self.results_wrapper.bottom)
.offset(1.),
self.row0.view.leading.constraint_equal_to(&view.leading),
self.row0.view.trailing.constraint_equal_to(&view.trailing),
self.row1.view.top.constraint_equal_to(&self.row0.view.bottom).offset(1.),
self.row1.view.leading.constraint_equal_to(&view.leading),
self.row1.view.trailing.constraint_equal_to(&view.trailing),
self.row2.view.top.constraint_equal_to(&self.row1.view.bottom).offset(1.),
self.row2.view.leading.constraint_equal_to(&view.leading),
self.row2.view.trailing.constraint_equal_to(&view.trailing),
self.row3.view.top.constraint_equal_to(&self.row2.view.bottom).offset(1.),
self.row3.view.leading.constraint_equal_to(&view.leading),
self.row3.view.trailing.constraint_equal_to(&view.trailing),
self.zero.top.constraint_equal_to(&self.row3.view.bottom).offset(1.),
self.zero.leading.constraint_equal_to(&view.leading),
self.zero.bottom.constraint_equal_to(&view.bottom),
self.dot.top.constraint_equal_to(&self.row3.view.bottom).offset(1.),
self.dot.leading.constraint_equal_to(&self.zero.trailing).offset(1.),
self.dot.bottom.constraint_equal_to(&view.bottom),
self.dot.width.constraint_equal_to_constant(BUTTON_WIDTH),
self.dot.height.constraint_equal_to_constant(BUTTON_HEIGHT),
self.equals.top.constraint_equal_to(&self.row3.view.bottom).offset(1.),
self.equals.leading.constraint_equal_to(&self.dot.trailing).offset(1.),
self.equals.trailing.constraint_equal_to(&view.trailing),

View file

@ -11,8 +11,8 @@
use std::sync::RwLock;
use cacao::appkit::window::{TitleVisibility, Window, WindowConfig};
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::window::{Window, WindowConfig, TitleVisibility};
use cacao::appkit::{Event, EventMask, EventMonitor};
use cacao::color::Color;
use cacao::notification_center::Dispatcher;
@ -109,5 +109,6 @@ fn main() {
window: Window::new(config),
content: View::with(CalculatorView::new()),
key_monitor: RwLock::new(None)
}).run();
})
.run();
}

View file

@ -5,10 +5,10 @@ use cacao::color::Color;
use cacao::layout::{Layout, LayoutConstraint};
use cacao::view::View;
use cacao::macos::{App, AppDelegate};
use cacao::image::{DrawConfig, Image, ImageView};
use cacao::macos::menu::{Menu, MenuItem};
use cacao::macos::window::{Window};
use cacao::image::{ImageView, Image, DrawConfig};
use cacao::macos::window::Window;
use cacao::macos::{App, AppDelegate};
struct BasicApp {
window: Window,
@ -22,7 +22,7 @@ impl Default for BasicApp {
let config = DrawConfig {
source: (100., 100.),
target: (800., 800.),
resize: cacao::image::ResizeBehavior::Stretch,
resize: cacao::image::ResizeBehavior::Stretch
};
Self {
@ -97,17 +97,15 @@ impl Default for BasicApp {
impl AppDelegate for BasicApp {
fn did_finish_launching(&self) {
App::set_menu(vec![
Menu::new("", vec![
App::set_menu(vec![Menu::new("", vec![
MenuItem::Services,
MenuItem::Separator,
MenuItem::Hide,
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
])
]);
MenuItem::Quit,
])]);
App::activate();
self.window.set_title("Hello World!");
@ -120,7 +118,7 @@ impl AppDelegate for BasicApp {
self.image_view.top.constraint_equal_to(&self.content_view.top),
self.image_view.leading.constraint_equal_to(&self.content_view.leading),
self.image_view.trailing.constraint_equal_to(&self.content_view.trailing),
self.image_view.bottom.constraint_equal_to(&self.content_view.bottom),
self.image_view.bottom.constraint_equal_to(&self.content_view.bottom)
]);
self.window.set_content_view(&self.content_view);

View file

@ -6,9 +6,9 @@ use cacao::geometry::Rect;
use cacao::layout::Layout;
use cacao::view::View;
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate};
use cacao::appkit::{App, AppDelegate};
const CORNER_RADIUS: f64 = 16.;
const SPACING: f64 = 10.;
@ -30,23 +30,16 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
])
MenuItem::new("Bring All to Front"),
]),
]);
App::activate();
@ -115,5 +108,6 @@ impl WindowDelegate for AppWindow {
fn main() {
App::new("com.test.window", BasicApp {
window: Window::with(WindowConfig::default(), AppWindow::default())
}).run();
})
.run();
}

View file

@ -1,9 +1,6 @@
use std::sync::RwLock;
use cacao::uikit::{
App, AppDelegate, Scene, SceneConfig, SceneSession,
SceneConnectionOptions, WindowSceneDelegate, Window
};
use cacao::uikit::{App, AppDelegate, Scene, SceneConfig, SceneConnectionOptions, SceneSession, Window, WindowSceneDelegate};
use cacao::color::Color;
use cacao::layout::{Layout, LayoutConstraint};
@ -44,12 +41,10 @@ impl ViewDelegate for RootView {
self.red.leading.constraint_equal_to(&view.leading).offset(16.),
self.red.trailing.constraint_equal_to(&view.trailing).offset(-16.),
self.red.height.constraint_equal_to_constant(100.),
self.green.top.constraint_equal_to(&self.red.bottom).offset(16.),
self.green.leading.constraint_equal_to(&view.leading).offset(16.),
self.green.trailing.constraint_equal_to(&view.trailing).offset(-16.),
self.green.height.constraint_equal_to_constant(120.),
self.blue.top.constraint_equal_to(&self.green.bottom).offset(16.),
self.blue.leading.constraint_equal_to(&view.leading).offset(16.),
self.blue.trailing.constraint_equal_to(&view.trailing).offset(-16.),
@ -65,12 +60,7 @@ pub struct WindowScene {
}
impl WindowSceneDelegate for WindowScene {
fn will_connect(
&self,
scene: Scene,
session: SceneSession,
options: SceneConnectionOptions
) {
fn will_connect(&self, scene: Scene, session: SceneSession, options: SceneConnectionOptions) {
let bounds = scene.get_bounds();
let mut window = Window::new(bounds);
window.set_window_scene(scene);
@ -90,7 +80,5 @@ impl WindowSceneDelegate for WindowScene {
}
fn main() {
App::new(TestApp::default(), || {
Box::new(WindowScene::default())
}).run();
App::new(TestApp::default(), || Box::new(WindowScene::default())).run();
}

View file

@ -1,13 +1,13 @@
//! This example showcases setting up a basic application and window, setting up some views to
//! work with autolayout, and some basic ways to handle colors.
use cacao::layout::{Layout, LayoutConstraint};
use cacao::input::{TextField, TextFieldDelegate};
use cacao::layout::{Layout, LayoutConstraint};
use cacao::view::View;
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate};
use cacao::appkit::{App, AppDelegate};
struct BasicApp {
window: Window<AppWindow>
@ -23,13 +23,9 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("Edit", vec![
MenuItem::Undo,
MenuItem::Redo,
@ -38,21 +34,16 @@ impl AppDelegate for BasicApp {
MenuItem::Copy,
MenuItem::Paste,
MenuItem::Separator,
MenuItem::SelectAll
MenuItem::SelectAll,
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
MenuItem::new("Bring All to Front"),
]),
Menu::new("Help", vec![])
Menu::new("Help", vec![]),
]);
App::activate();
@ -79,7 +70,6 @@ impl TextFieldDelegate for ConsoleLogger {
println!("Did change to: {}", value);
}
fn text_did_end_editing(&self, value: &str) {
println!("Ended: {}", value);
}
@ -95,7 +85,7 @@ impl AppWindow {
pub fn new() -> Self {
AppWindow {
input: TextField::with(ConsoleLogger),
content: View::new(),
content: View::new()
}
}
}
@ -121,5 +111,6 @@ impl WindowDelegate for AppWindow {
fn main() {
App::new("com.test.window", BasicApp {
window: Window::with(WindowConfig::default(), AppWindow::new())
}).run();
})
.run();
}

View file

@ -9,16 +9,14 @@ mod view;
use view::AddNewTodoContentView;
pub struct AddNewTodoWindow {
pub content: ViewController<AddNewTodoContentView>,
pub content: ViewController<AddNewTodoContentView>
}
impl AddNewTodoWindow {
pub fn new() -> Self {
let content = ViewController::new(AddNewTodoContentView::default());
AddNewTodoWindow {
content: content
}
AddNewTodoWindow { content: content }
}
pub fn on_message(&self, message: Message) {

View file

@ -6,8 +6,8 @@
//! changes before version 0.1. This approach is unlikely to break as an example while those
//! changes are poked and prodded at, even if it is a bit verbose and confusing.
use cacao::text::Label;
use cacao::layout::{Layout, LayoutConstraint};
use cacao::text::Label;
use cacao::view::{View, ViewDelegate};
use cacao::button::Button;
@ -60,11 +60,9 @@ impl ViewDelegate for AddNewTodoContentView {
instructions.top.constraint_equal_to(&view.top).offset(16.),
instructions.leading.constraint_equal_to(&view.leading).offset(16.),
instructions.trailing.constraint_equal_to(&view.trailing).offset(-16.),
input.top.constraint_equal_to(&instructions.bottom).offset(8.),
input.leading.constraint_equal_to(&view.leading).offset(16.),
input.trailing.constraint_equal_to(&view.trailing).offset(-16.),
button.top.constraint_equal_to(&input.bottom).offset(8.),
button.trailing.constraint_equal_to(&view.trailing).offset(-16.),
button.bottom.constraint_equal_to(&view.bottom).offset(-16.)

View file

@ -14,8 +14,5 @@ mod todos;
mod windows;
fn main() {
App::new(
"com.cacao.todo",
app::TodosApp::default()
).run();
App::new("com.cacao.todo", app::TodosApp::default()).run();
}

View file

@ -14,11 +14,9 @@ pub fn menu() -> Vec<Menu> {
Menu::new("", vec![
MenuItem::About("Todos".to_string()),
MenuItem::Separator,
MenuItem::new("Preferences").key(",").action(|| {
dispatch_ui(Message::OpenPreferencesWindow);
}),
MenuItem::Separator,
MenuItem::Services,
MenuItem::Separator,
@ -26,24 +24,19 @@ pub fn menu() -> Vec<Menu> {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::new("Open/Show Window").key("n").action(|| {
dispatch_ui(Message::OpenMainWindow);
}),
MenuItem::Separator,
MenuItem::new("Add Todo").key("+").action(|| {
dispatch_ui(Message::OpenNewTodoSheet);
}),
MenuItem::Separator,
MenuItem::CloseWindow
MenuItem::CloseWindow,
]),
Menu::new("Edit", vec![
MenuItem::Undo,
MenuItem::Redo,
@ -52,20 +45,15 @@ pub fn menu() -> Vec<Menu> {
MenuItem::Copy,
MenuItem::Paste,
MenuItem::Separator,
MenuItem::SelectAll
MenuItem::SelectAll,
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
MenuItem::new("Bring All to Front"),
]),
Menu::new("Help", vec![])
Menu::new("Help", vec![]),
]
}

View file

@ -1,5 +1,5 @@
use cacao::text::{Label, TextAlign};
use cacao::layout::{Layout, LayoutConstraint};
use cacao::text::{Label, TextAlign};
use cacao::view::{View, ViewDelegate};
/// A blank advanced preferences view.
@ -12,7 +12,8 @@ impl ViewDelegate for AdvancedPreferencesContentView {
const NAME: &'static str = "AdvancedPreferencesContentView";
fn did_load(&mut self, view: View) {
self.label.set_text("And this is where advanced preferences would be... if we had any.");
self.label
.set_text("And this is where advanced preferences would be... if we had any.");
self.label.set_text_alignment(TextAlign::Center);
view.add_subview(&self.label);
@ -24,4 +25,3 @@ impl ViewDelegate for AdvancedPreferencesContentView {
]);
}
}

View file

@ -12,7 +12,7 @@ use super::toggle_option_view::ToggleOptionView;
/// A general preferences view.
#[derive(Debug, Default)]
pub struct GeneralPreferencesContentView {
pub example_option: ToggleOptionView,
pub example_option: ToggleOptionView
}
impl ViewDelegate for GeneralPreferencesContentView {
@ -30,10 +30,17 @@ impl ViewDelegate for GeneralPreferencesContentView {
LayoutConstraint::activate(&[
self.example_option.view.top.constraint_equal_to(&view.top).offset(22.),
self.example_option.view.leading.constraint_equal_to(&view.leading).offset(22.),
self.example_option.view.trailing.constraint_equal_to(&view.trailing).offset(-22.),
self.example_option
.view
.leading
.constraint_equal_to(&view.leading)
.offset(22.),
self.example_option
.view
.trailing
.constraint_equal_to(&view.trailing)
.offset(-22.),
self.example_option.view.bottom.constraint_equal_to(&view.bottom).offset(-22.)
]);
}
}

View file

@ -1,7 +1,7 @@
//! Implements a stock-ish Preferences window.
use cacao::appkit::window::{Window, WindowDelegate};
use cacao::appkit::toolbar::Toolbar;
use cacao::appkit::window::{Window, WindowDelegate};
use cacao::view::ViewController;
use crate::storage::Message;

View file

@ -1,7 +1,7 @@
use cacao::text::Label;
use cacao::layout::{Layout, LayoutConstraint};
use cacao::switch::Switch;
use cacao::view::{View};
use cacao::text::Label;
use cacao::view::View;
/// A reusable widget for a toggle; this is effectively a standard checkbox/label combination for
/// toggling a boolean value.
@ -31,11 +31,9 @@ impl Default for ToggleOptionView {
switch.top.constraint_equal_to(&view.top),
switch.leading.constraint_equal_to(&view.leading),
switch.width.constraint_equal_to_constant(24.),
title.top.constraint_equal_to(&view.top),
title.leading.constraint_equal_to(&switch.trailing),
title.trailing.constraint_equal_to(&view.trailing),
subtitle.top.constraint_equal_to(&title.bottom),
subtitle.leading.constraint_equal_to(&switch.trailing),
subtitle.trailing.constraint_equal_to(&view.trailing),

View file

@ -1,7 +1,7 @@
//! Implements an example toolbar for a Preferences app. Could be cleaner, probably worth cleaning
//! up at some point.
use cacao::appkit::toolbar::{Toolbar, ToolbarDelegate, ToolbarItem, ItemIdentifier};
use cacao::appkit::toolbar::{ItemIdentifier, Toolbar, ToolbarDelegate, ToolbarItem};
use cacao::image::{Image, MacSystemIcon};
use crate::storage::{dispatch_ui, Message};
@ -11,7 +11,8 @@ pub struct PreferencesToolbar((ToolbarItem, ToolbarItem));
impl Default for PreferencesToolbar {
fn default() -> Self {
PreferencesToolbar(({
PreferencesToolbar((
{
let mut item = ToolbarItem::new("general");
item.set_title("General");
@ -23,7 +24,8 @@ impl Default for PreferencesToolbar {
});
item
}, {
},
{
let mut item = ToolbarItem::new("advanced");
item.set_title("Advanced");
@ -35,7 +37,8 @@ impl Default for PreferencesToolbar {
});
item
}))
}
))
}
}
@ -62,7 +65,9 @@ impl ToolbarDelegate for PreferencesToolbar {
match identifier {
"general" => &self.0 .0,
"advanced" => &self.0 .1,
_ => { unreachable!(); }
_ => {
unreachable!();
}
}
}
}

View file

@ -52,7 +52,10 @@ fn toggle_bool(key: &str) {
panic!("Attempting to toggle a boolean value for {}, but it's not a boolean.", key);
}
panic!("Attempting to toggle a boolean value for {}, but this key does not exist.", key);
panic!(
"Attempting to toggle a boolean value for {}, but this key does not exist.",
key
);
}
/// A helper method for loading a boolean value held at the specified key. If the value cannot

View file

@ -9,7 +9,7 @@ mod defaults;
pub use defaults::Defaults;
mod todos;
pub use todos::{Todos, Todo, TodoStatus};
pub use todos::{Todo, TodoStatus, Todos};
/// Message passing is our primary way of instructing UI changes without needing to do
/// constant crazy referencing in Rust. Dispatch a method using either `dispatch_ui` for the main

View file

@ -2,8 +2,8 @@
//! doing this stuff on the main thread; in a more complicated app, you'd probably make different
//! choices.
use std::rc::Rc;
use std::cell::RefCell;
use std::rc::Rc;
/// The status of a Todo.
#[derive(Debug)]

View file

@ -7,8 +7,8 @@ use cacao::layout::{Layout, LayoutConstraint};
use cacao::listview::ListView;
use cacao::view::{View, ViewDelegate};
use crate::storage::Message;
use super::list::TodosListView;
use crate::storage::Message;
#[derive(Debug)]
pub struct TodosContentView {

View file

@ -2,12 +2,9 @@
//! mostly single-threaded example, so we can get away with cutting a few corners and keeping our
//! data store in here - but for a larger app, you'd likely do something else.
use cacao::listview::{
ListView, ListViewDelegate, ListViewRow,
RowAnimation, RowEdge, RowAction, RowActionStyle
};
use cacao::listview::{ListView, ListViewDelegate, ListViewRow, RowAction, RowActionStyle, RowAnimation, RowEdge};
use crate::storage::{dispatch_ui, Message, Todos, TodoStatus};
use crate::storage::{dispatch_ui, Message, TodoStatus, Todos};
mod row;
use row::TodoViewRow;
@ -97,15 +94,23 @@ impl ListViewDelegate for TodosListView {
self.todos.with(row, |todo| match todo.status {
TodoStatus::Complete => {
actions.push(RowAction::new("Mark Incomplete", RowActionStyle::Destructive, move |_action, row| {
actions.push(RowAction::new(
"Mark Incomplete",
RowActionStyle::Destructive,
move |_action, row| {
dispatch_ui(Message::MarkTodoIncomplete(row));
}));
}
));
},
TodoStatus::Incomplete => {
actions.push(RowAction::new("Mark Complete", RowActionStyle::Regular, move |_action, row| {
actions.push(RowAction::new(
"Mark Complete",
RowActionStyle::Regular,
move |_action, row| {
dispatch_ui(Message::MarkTodoComplete(row));
}));
}
));
}
});

View file

@ -1,7 +1,7 @@
use cacao::color::Color;
use cacao::layout::{Layout, LayoutConstraint};
use cacao::text::{Font, Label, LineBreakMode};
use cacao::view::{View, ViewDelegate};
use cacao::color::Color;
use crate::storage::{Todo, TodoStatus};
@ -50,7 +50,6 @@ impl ViewDelegate for TodoViewRow {
self.title.top.constraint_equal_to(&view.top).offset(16.),
self.title.leading.constraint_equal_to(&view.leading).offset(16.),
self.title.trailing.constraint_equal_to(&view.trailing).offset(-16.),
self.status.top.constraint_equal_to(&self.title.bottom).offset(8.),
self.status.leading.constraint_equal_to(&view.leading).offset(16.),
self.status.trailing.constraint_equal_to(&view.trailing).offset(-16.),

View file

@ -1,7 +1,7 @@
//! The main Todos window.
use cacao::appkit::window::{Window, WindowDelegate};
use cacao::appkit::toolbar::Toolbar;
use cacao::appkit::window::{Window, WindowDelegate};
use cacao::view::ViewController;
use crate::storage::Message;
@ -16,7 +16,7 @@ mod list;
pub struct TodosWindow {
pub content: ViewController<TodosContentView>,
pub toolbar: Toolbar<TodosToolbar>,
pub toolbar: Toolbar<TodosToolbar>
}
impl TodosWindow {

View file

@ -1,10 +1,7 @@
//! The main Todos window toolbar. Contains a button to enable adding a new task.
use cacao::appkit::toolbar::{ItemIdentifier, Toolbar, ToolbarDelegate, ToolbarDisplayMode, ToolbarItem};
use cacao::button::Button;
use cacao::appkit::toolbar::{
Toolbar, ToolbarDelegate, ToolbarItem,
ToolbarDisplayMode, ItemIdentifier
};
use crate::storage::{dispatch_ui, Message};

View file

@ -5,14 +5,14 @@
use std::sync::RwLock;
use cacao::appkit::window::{Window, WindowConfig, WindowStyle, WindowDelegate, WindowToolbarStyle};
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate, WindowStyle, WindowToolbarStyle};
use cacao::notification_center::Dispatcher;
use crate::storage::Message;
use crate::add::AddNewTodoWindow;
use crate::todos::TodosWindow;
use crate::preferences::PreferencesWindow;
use crate::todos::TodosWindow;
#[derive(Default)]
pub struct WindowManager {
@ -42,9 +42,7 @@ where
impl WindowManager {
pub fn open_main(&self) {
open_or_show(&self.main, || (
WindowConfig::default(), TodosWindow::new()
));
open_or_show(&self.main, || (WindowConfig::default(), TodosWindow::new()));
}
/// When we run a sheet, we want to run it on our main window, which is all
@ -100,8 +98,10 @@ impl WindowManager {
config.set_initial_dimensions(100., 100., 400., 400.);
config.set_styles(&[
WindowStyle::Resizable, WindowStyle::Miniaturizable,
WindowStyle::Closable, WindowStyle::Titled
WindowStyle::Resizable,
WindowStyle::Miniaturizable,
WindowStyle::Closable,
WindowStyle::Titled
]);
config.toolbar_style = WindowToolbarStyle::Preferences;

View file

@ -3,10 +3,10 @@
use cacao::webview::{WebView, WebViewConfig, WebViewDelegate};
use cacao::macos::{App, AppDelegate};
use cacao::macos::menu::{Menu, MenuItem};
use cacao::macos::toolbar::Toolbar;
use cacao::macos::window::{Window, WindowConfig, WindowDelegate, WindowToolbarStyle};
use cacao::macos::{App, AppDelegate};
struct BasicApp {
window: Window<AppWindow>
@ -56,8 +56,8 @@ impl WebViewDelegate for WebViewInstance {
return match requested_asset_path.as_str() {
"/hello.html" => Some(link_html.as_bytes().into()),
_ => Some(index_html.as_bytes().into()),
}
_ => Some(index_html.as_bytes().into())
};
}
}
@ -100,5 +100,6 @@ impl WindowDelegate for AppWindow {
fn main() {
App::new("com.test.window", BasicApp {
window: Window::with(WindowConfig::default(), AppWindow::new())
}).run();
})
.run();
}

View file

@ -1,8 +1,8 @@
//! This example showcases setting up a basic application and window.
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::window::Window;
use cacao::appkit::{App, AppDelegate};
#[derive(Default)]
struct BasicApp {
@ -19,23 +19,16 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
])
MenuItem::new("Bring All to Front"),
]),
]);
App::activate();

View file

@ -4,9 +4,9 @@
//!
//! If you're not using that, you can probably get by fine with a standard `NSWindow`.
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::window::{Window, WindowConfig, WindowController, WindowDelegate};
use cacao::appkit::{App, AppDelegate};
struct BasicApp {
window: WindowController<MyWindow>
@ -22,23 +22,16 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
])
MenuItem::new("Bring All to Front"),
]),
]);
App::activate();
@ -70,5 +63,6 @@ impl WindowDelegate for MyWindow {
fn main() {
App::new("com.test.window-delegate", BasicApp {
window: WindowController::with(WindowConfig::default(), MyWindow::default())
}).run();
})
.run();
}

View file

@ -1,9 +1,9 @@
//! This example showcases setting up a basic application and window delegate.
//! Window Delegate's give you lifecycle methods that you can respond to.
use cacao::appkit::{App, AppDelegate};
use cacao::appkit::menu::{Menu, MenuItem};
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate};
use cacao::appkit::{App, AppDelegate};
struct BasicApp {
window: Window<MyWindow>
@ -19,23 +19,16 @@ impl AppDelegate for BasicApp {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
])
MenuItem::new("Bring All to Front"),
]),
]);
App::activate();
@ -80,5 +73,6 @@ impl WindowDelegate for MyWindow {
fn main() {
App::new("com.test.window-delegate", BasicApp {
window: Window::with(WindowConfig::default(), MyWindow::default())
}).run();
})
.run();
}

View file

@ -3,3 +3,4 @@ match_block_trailing_comma = true
# Nightly
overflow_delimited_expr = true
trailing_comma = "Never"

View file

@ -24,9 +24,9 @@
//! }
//! ```
use objc_id::Id;
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, NSString};

View file

@ -6,7 +6,7 @@ use std::sync::Once;
use objc::class;
use objc::declare::ClassDecl;
use objc::runtime::{Class};
use objc::runtime::Class;
/// Used for injecting a custom NSApplication. Currently does nothing.
pub(crate) fn register_app_class() -> *const Class {
@ -19,7 +19,5 @@ pub(crate) fn register_app_class() -> *const Class {
APP_CLASS = decl.register();
});
unsafe {
APP_CLASS
}
unsafe { APP_CLASS }
}

View file

@ -7,16 +7,16 @@ use std::sync::Once;
use block::Block;
use objc::{class, msg_send, sel, sel_impl};
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, msg_send, sel, sel_impl};
use url::Url;
use crate::error::Error;
use crate::foundation::{id, nil, to_bool, BOOL, YES, NO, NSUInteger, NSArray, NSString};
use crate::appkit::app::{APP_PTR, AppDelegate};
use crate::appkit::app::{AppDelegate, APP_PTR};
use crate::appkit::printing::PrintSettings;
use crate::error::Error;
use crate::foundation::{id, nil, to_bool, NSArray, NSString, NSUInteger, BOOL, NO, YES};
use crate::user_activity::UserActivity;
#[cfg(feature = "cloudkit")]
@ -33,78 +33,78 @@ fn app<T>(this: &Object) -> &T {
}
/// Fires when the Application Delegate receives a `applicationWillFinishLaunching` notification.
extern fn will_finish_launching<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_finish_launching<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_finish_launching();
}
/// Fires when the Application Delegate receives a `applicationDidFinishLaunching` notification.
extern fn did_finish_launching<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_finish_launching<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_finish_launching();
}
/// Fires when the Application Delegate receives a `applicationWillBecomeActive` notification.
extern fn will_become_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_become_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_become_active();
}
/// Fires when the Application Delegate receives a `applicationDidBecomeActive` notification.
extern fn did_become_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_become_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_become_active();
}
/// Fires when the Application Delegate receives a `applicationWillResignActive` notification.
extern fn will_resign_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_resign_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_resign_active();
}
/// Fires when the Application Delegate receives a `applicationDidResignActive` notification.
extern fn did_resign_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_resign_active<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_resign_active();
}
/// Fires when the Application Delegate receives a 'applicationShouldTerminate:` notification.
extern fn should_terminate<T: AppDelegate>(this: &Object, _: Sel, _: id) -> NSUInteger {
extern "C" fn should_terminate<T: AppDelegate>(this: &Object, _: Sel, _: id) -> NSUInteger {
app::<T>(this).should_terminate().into()
}
/// Fires when the Application Delegate receives a `applicationWillTerminate:` notification.
extern fn will_terminate<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_terminate<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_terminate();
}
/// Fires when the Application Delegate receives a `applicationWillHide:` notification.
extern fn will_hide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_hide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_hide();
}
/// Fires when the Application Delegate receives a `applicationDidHide:` notification.
extern fn did_hide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_hide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_hide();
}
/// Fires when the Application Delegate receives a `applicationWillUnhide:` notification.
extern fn will_unhide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_unhide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_unhide();
}
/// Fires when the Application Delegate receives a `applicationDidUnhide:` notification.
extern fn did_unhide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_unhide<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_unhide();
}
/// Fires when the Application Delegate receives a `applicationWillUpdate:` notification.
extern fn will_update<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_update<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).will_update();
}
/// Fires when the Application Delegate receives a `applicationDidUpdate:` notification.
extern fn did_update<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_update<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_update();
}
/// Fires when the Application Delegate receives a
/// `applicationShouldHandleReopen:hasVisibleWindows:` notification.
extern fn should_handle_reopen<T: AppDelegate>(this: &Object, _: Sel, _: id, has_visible_windows: BOOL) -> BOOL {
extern "C" fn should_handle_reopen<T: AppDelegate>(this: &Object, _: Sel, _: id, has_visible_windows: BOOL) -> BOOL {
match app::<T>(this).should_handle_reopen(to_bool(has_visible_windows)) {
true => YES,
false => NO
@ -113,7 +113,7 @@ extern fn should_handle_reopen<T: AppDelegate>(this: &Object, _: Sel, _: id, has
/// Fires when the application delegate receives a `applicationDockMenu:` request.
// @TODO: Make this return Vec<MenuItem>.
extern fn dock_menu<T: AppDelegate>(this: &Object, _: Sel, _: id) -> id {
extern "C" fn dock_menu<T: AppDelegate>(this: &Object, _: Sel, _: id) -> id {
match app::<T>(this).dock_menu() {
Some(mut menu) => &mut *menu.0,
None => nil
@ -121,19 +121,19 @@ extern fn dock_menu<T: AppDelegate>(this: &Object, _: Sel, _: id) -> id {
}
/// Fires when the application delegate receives a `application:willPresentError:` notification.
extern fn will_present_error<T: AppDelegate>(this: &Object, _: Sel, _: id, error: id) -> id {
extern "C" fn will_present_error<T: AppDelegate>(this: &Object, _: Sel, _: id, error: id) -> id {
let error = Error::new(error);
app::<T>(this).will_present_error(error).into_nserror()
}
/// Fires when the application receives a `applicationDidChangeScreenParameters:` notification.
extern fn did_change_screen_parameters<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_change_screen_parameters<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).did_change_screen_parameters();
}
/// Fires when the application receives a `application:willContinueUserActivityWithType:`
/// notification.
extern fn will_continue_user_activity_with_type<T: AppDelegate>(this: &Object, _: Sel, _: id, activity_type: id) -> BOOL {
extern "C" fn will_continue_user_activity_with_type<T: AppDelegate>(this: &Object, _: Sel, _: id, activity_type: id) -> BOOL {
let activity = NSString::retain(activity_type);
match app::<T>(this).will_continue_user_activity(activity.to_str()) {
@ -143,7 +143,7 @@ extern fn will_continue_user_activity_with_type<T: AppDelegate>(this: &Object, _
}
/// Fires when the application receives a `application:continueUserActivity:restorationHandler:` notification.
extern fn continue_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, activity: id, handler: id) -> BOOL {
extern "C" fn continue_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, activity: id, handler: id) -> BOOL {
// @TODO: This needs to support restorable objects, but it involves a larger question about how
// much `NSObject` retainping we want to do here. For now, pass the handler for whenever it's
// useful.
@ -160,57 +160,52 @@ extern fn continue_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, a
/// Fires when the application receives a
/// `application:didFailToContinueUserActivityWithType:error:` message.
extern fn failed_to_continue_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, activity_type: id, error: id) {
app::<T>(this).failed_to_continue_user_activity(
NSString::retain(activity_type).to_str(),
Error::new(error)
);
extern "C" fn failed_to_continue_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, activity_type: id, error: id) {
app::<T>(this).failed_to_continue_user_activity(NSString::retain(activity_type).to_str(), Error::new(error));
}
/// Fires when the application receives a `application:didUpdateUserActivity:` message.
extern fn did_update_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, activity: id) {
extern "C" fn did_update_user_activity<T: AppDelegate>(this: &Object, _: Sel, _: id, activity: id) {
let activity = UserActivity::with_inner(activity);
app::<T>(this).updated_user_activity(activity);
}
/// Fires when the application receives a `application:didRegisterForRemoteNotificationsWithDeviceToken:` message.
extern fn registered_for_remote_notifications<T: AppDelegate>(_this: &Object, _: Sel, _: id, _: id) {
}
extern "C" fn registered_for_remote_notifications<T: AppDelegate>(_this: &Object, _: Sel, _: id, _: id) {}
/// Fires when the application receives a `application:didFailToRegisterForRemoteNotificationsWithError:` message.
extern fn failed_to_register_for_remote_notifications<T: AppDelegate>(this: &Object, _: Sel, _: id, error: id) {
extern "C" fn failed_to_register_for_remote_notifications<T: AppDelegate>(this: &Object, _: Sel, _: id, error: id) {
app::<T>(this).failed_to_register_for_remote_notifications(Error::new(error));
}
/// Fires when the application receives a `application:didReceiveRemoteNotification:` message.
extern fn did_receive_remote_notification<T: AppDelegate>(_this: &Object, _: Sel, _: id, _: id) {
}
extern "C" fn did_receive_remote_notification<T: AppDelegate>(_this: &Object, _: Sel, _: id, _: id) {}
/// Fires when the application receives a `application:userDidAcceptCloudKitShareWithMetadata:`
/// message.
#[cfg(feature = "cloudkit")]
extern fn accepted_cloudkit_share<T: AppDelegate>(this: &Object, _: Sel, _: id, metadata: id) {
extern "C" fn accepted_cloudkit_share<T: AppDelegate>(this: &Object, _: Sel, _: id, metadata: id) {
let share = CKShareMetaData::with_inner(metadata);
app::<T>(this).user_accepted_cloudkit_share(share);
}
/// Fires when the application receives an `application:openURLs` message.
extern fn open_urls<T: AppDelegate>(this: &Object, _: Sel, _: id, file_urls: id) {
let urls = NSArray::retain(file_urls).map(|url| {
let uri = NSString::retain(unsafe {
msg_send![url, absoluteString]
});
extern "C" fn open_urls<T: AppDelegate>(this: &Object, _: Sel, _: id, file_urls: id) {
let urls = NSArray::retain(file_urls)
.map(|url| {
let uri = NSString::retain(unsafe { msg_send![url, absoluteString] });
Url::parse(uri.to_str())
}).into_iter().filter_map(|url| url.ok()).collect();
})
.into_iter()
.filter_map(|url| url.ok())
.collect();
app::<T>(this).open_urls(urls);
}
/// Fires when the application receives an `application:openFileWithoutUI:` message.
extern fn open_file_without_ui<T: AppDelegate>(this: &Object, _: Sel, _: id, file: id) -> BOOL {
extern "C" fn open_file_without_ui<T: AppDelegate>(this: &Object, _: Sel, _: id, file: id) -> BOOL {
let filename = NSString::retain(file);
match app::<T>(this).open_file_without_ui(filename.to_str()) {
@ -220,7 +215,7 @@ extern fn open_file_without_ui<T: AppDelegate>(this: &Object, _: Sel, _: id, fil
}
/// Fired when the application receives an `applicationShouldOpenUntitledFile:` message.
extern fn should_open_untitled_file<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
extern "C" fn should_open_untitled_file<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
match app::<T>(this).should_open_untitled_file() {
true => YES,
false => NO
@ -228,7 +223,7 @@ extern fn should_open_untitled_file<T: AppDelegate>(this: &Object, _: Sel, _: id
}
/// Fired when the application receives an `applicationShouldTerminateAfterLastWindowClosed:` message.
extern fn should_terminate_after_last_window_closed<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
extern "C" fn should_terminate_after_last_window_closed<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
match app::<T>(this).should_terminate_after_last_window_closed() {
true => YES,
false => NO
@ -236,7 +231,7 @@ extern fn should_terminate_after_last_window_closed<T: AppDelegate>(this: &Objec
}
/// Fired when the application receives an `applicationOpenUntitledFile:` message.
extern fn open_untitled_file<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
extern "C" fn open_untitled_file<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
match app::<T>(this).open_untitled_file() {
true => YES,
false => NO
@ -244,7 +239,7 @@ extern fn open_untitled_file<T: AppDelegate>(this: &Object, _: Sel, _: id) -> BO
}
/// Fired when the application receives an `application:openTempFile:` message.
extern fn open_temp_file<T: AppDelegate>(this: &Object, _: Sel, _: id, filename: id) -> BOOL {
extern "C" fn open_temp_file<T: AppDelegate>(this: &Object, _: Sel, _: id, filename: id) -> BOOL {
let filename = NSString::retain(filename);
match app::<T>(this).open_temp_file(filename.to_str()) {
@ -254,7 +249,7 @@ extern fn open_temp_file<T: AppDelegate>(this: &Object, _: Sel, _: id, filename:
}
/// Fired when the application receives an `application:printFile:` message.
extern fn print_file<T: AppDelegate>(this: &Object, _: Sel, _: id, file: id) -> BOOL {
extern "C" fn print_file<T: AppDelegate>(this: &Object, _: Sel, _: id, file: id) -> BOOL {
let filename = NSString::retain(file);
match app::<T>(this).print_file(filename.to_str()) {
@ -265,10 +260,15 @@ extern fn print_file<T: AppDelegate>(this: &Object, _: Sel, _: id, file: id) ->
/// Fired when the application receives an `application:printFiles:withSettings:showPrintPanels:`
/// message.
extern fn print_files<T: AppDelegate>(this: &Object, _: Sel, _: id, files: id, settings: id, show_print_panels: BOOL) -> NSUInteger {
let files = NSArray::retain(files).map(|file| {
NSString::retain(file).to_str().to_string()
});
extern "C" fn print_files<T: AppDelegate>(
this: &Object,
_: Sel,
_: id,
files: id,
settings: id,
show_print_panels: BOOL
) -> NSUInteger {
let files = NSArray::retain(files).map(|file| NSString::retain(file).to_str().to_string());
let settings = PrintSettings::with_inner(settings);
@ -276,14 +276,14 @@ extern fn print_files<T: AppDelegate>(this: &Object, _: Sel, _: id, files: id, s
}
/// Called when the application's occlusion state has changed.
extern fn did_change_occlusion_state<T: AppDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_change_occlusion_state<T: AppDelegate>(this: &Object, _: Sel, _: id) {
app::<T>(this).occlusion_state_changed();
}
/// Called when the application receives an `application:delegateHandlesKey:` message.
/// Note: this may not fire in sandboxed applications. Apple's documentation is unclear on the
/// matter.
extern fn delegate_handles_key<T: AppDelegate>(this: &Object, _: Sel, _: id, key: id) -> BOOL {
extern "C" fn delegate_handles_key<T: AppDelegate>(this: &Object, _: Sel, _: id, key: id) -> BOOL {
let key = NSString::retain(key);
match app::<T>(this).delegate_handles_key(key.to_str()) {
@ -305,77 +305,165 @@ pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *co
decl.add_ivar::<usize>(APP_PTR);
// Launching Applications
decl.add_method(sel!(applicationWillFinishLaunching:), will_finish_launching::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidFinishLaunching:), did_finish_launching::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(applicationWillFinishLaunching:),
will_finish_launching::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidFinishLaunching:),
did_finish_launching::<T> as extern "C" fn(&Object, _, _)
);
// Managing Active Status
decl.add_method(sel!(applicationWillBecomeActive:), will_become_active::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidBecomeActive:), did_become_active::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationWillResignActive:), will_resign_active::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidResignActive:), did_resign_active::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(applicationWillBecomeActive:),
will_become_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidBecomeActive:),
did_become_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationWillResignActive:),
will_resign_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidResignActive:),
did_resign_active::<T> as extern "C" fn(&Object, _, _)
);
// Terminating Applications
decl.add_method(sel!(applicationShouldTerminate:), should_terminate::<T> as extern fn(&Object, _, _) -> NSUInteger);
decl.add_method(sel!(applicationWillTerminate:), will_terminate::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationShouldTerminateAfterLastWindowClosed:), should_terminate_after_last_window_closed::<T> as extern fn(&Object, _, _) -> BOOL);
decl.add_method(
sel!(applicationShouldTerminate:),
should_terminate::<T> as extern "C" fn(&Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(applicationWillTerminate:),
will_terminate::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationShouldTerminateAfterLastWindowClosed:),
should_terminate_after_last_window_closed::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
// Hiding Applications
decl.add_method(sel!(applicationWillHide:), will_hide::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidHide:), did_hide::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationWillUnhide:), will_unhide::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidUnhide:), did_unhide::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationWillHide:), will_hide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidHide:), did_hide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationWillUnhide:), will_unhide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidUnhide:), did_unhide::<T> as extern "C" fn(&Object, _, _));
// Managing Windows
decl.add_method(sel!(applicationWillUpdate:), will_update::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidUpdate:), did_update::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationShouldHandleReopen:hasVisibleWindows:), should_handle_reopen::<T> as extern fn(&Object, _, _, BOOL) -> BOOL);
decl.add_method(sel!(applicationWillUpdate:), will_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidUpdate:), did_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(
sel!(applicationShouldHandleReopen:hasVisibleWindows:),
should_handle_reopen::<T> as extern "C" fn(&Object, _, _, BOOL) -> BOOL
);
// Dock Menu
decl.add_method(sel!(applicationDockMenu:), dock_menu::<T> as extern fn(&Object, _, _) -> id);
decl.add_method(
sel!(applicationDockMenu:),
dock_menu::<T> as extern "C" fn(&Object, _, _) -> id
);
// Displaying Errors
decl.add_method(sel!(application:willPresentError:), will_present_error::<T> as extern fn(&Object, _, _, id) -> id);
decl.add_method(
sel!(application:willPresentError:),
will_present_error::<T> as extern "C" fn(&Object, _, _, id) -> id
);
// Managing the Screen
decl.add_method(sel!(applicationDidChangeScreenParameters:), did_change_screen_parameters::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(applicationDidChangeOcclusionState:), did_change_occlusion_state::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(applicationDidChangeScreenParameters:),
did_change_screen_parameters::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidChangeOcclusionState:),
did_change_occlusion_state::<T> as extern "C" fn(&Object, _, _)
);
// User Activities
decl.add_method(sel!(application:willContinueUserActivityWithType:), will_continue_user_activity_with_type::<T> as extern fn(&Object, _, _, id) -> BOOL);
decl.add_method(sel!(application:continueUserActivity:restorationHandler:), continue_user_activity::<T> as extern fn(&Object, _, _, id, id) -> BOOL);
decl.add_method(sel!(application:didFailToContinueUserActivityWithType:error:), failed_to_continue_user_activity::<T> as extern fn(&Object, _, _, id, id));
decl.add_method(sel!(application:didUpdateUserActivity:), did_update_user_activity::<T> as extern fn(&Object, _, _, id));
decl.add_method(
sel!(application:willContinueUserActivityWithType:),
will_continue_user_activity_with_type::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:continueUserActivity:restorationHandler:),
continue_user_activity::<T> as extern "C" fn(&Object, _, _, id, id) -> BOOL
);
decl.add_method(
sel!(application:didFailToContinueUserActivityWithType:error:),
failed_to_continue_user_activity::<T> as extern "C" fn(&Object, _, _, id, id)
);
decl.add_method(
sel!(application:didUpdateUserActivity:),
did_update_user_activity::<T> as extern "C" fn(&Object, _, _, id)
);
// Handling push notifications
decl.add_method(sel!(application:didRegisterForRemoteNotificationsWithDeviceToken:), registered_for_remote_notifications::<T> as extern fn(&Object, _, _, id));
decl.add_method(sel!(application:didFailToRegisterForRemoteNotificationsWithError:), failed_to_register_for_remote_notifications::<T> as extern fn(&Object, _, _, id));
decl.add_method(sel!(application:didReceiveRemoteNotification:), did_receive_remote_notification::<T> as extern fn(&Object, _, _, id));
decl.add_method(
sel!(application:didRegisterForRemoteNotificationsWithDeviceToken:),
registered_for_remote_notifications::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:didFailToRegisterForRemoteNotificationsWithError:),
failed_to_register_for_remote_notifications::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:didReceiveRemoteNotification:),
did_receive_remote_notification::<T> as extern "C" fn(&Object, _, _, id)
);
// CloudKit
#[cfg(feature = "cloudkit")]
decl.add_method(sel!(application:userDidAcceptCloudKitShareWithMetadata:), accepted_cloudkit_share::<T> as extern fn(&Object, _, _, id));
decl.add_method(
sel!(application:userDidAcceptCloudKitShareWithMetadata:),
accepted_cloudkit_share::<T> as extern "C" fn(&Object, _, _, id)
);
// Opening Files
decl.add_method(sel!(application:openURLs:), open_urls::<T> as extern fn(&Object, _, _, id));
decl.add_method(sel!(application:openFileWithoutUI:), open_file_without_ui::<T> as extern fn(&Object, _, _, id) -> BOOL);
decl.add_method(sel!(applicationShouldOpenUntitledFile:), should_open_untitled_file::<T> as extern fn(&Object, _, _) -> BOOL);
decl.add_method(sel!(applicationOpenUntitledFile:), open_untitled_file::<T> as extern fn(&Object, _, _) -> BOOL);
decl.add_method(sel!(application:openTempFile:), open_temp_file::<T> as extern fn(&Object, _, _, id) -> BOOL);
decl.add_method(
sel!(application:openURLs:),
open_urls::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:openFileWithoutUI:),
open_file_without_ui::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(applicationShouldOpenUntitledFile:),
should_open_untitled_file::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(
sel!(applicationOpenUntitledFile:),
open_untitled_file::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(
sel!(application:openTempFile:),
open_temp_file::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
// Printing
decl.add_method(sel!(application:printFile:), print_file::<T> as extern fn(&Object, _, _, id) -> BOOL);
decl.add_method(sel!(application:printFiles:withSettings:showPrintPanels:), print_files::<T> as extern fn(&Object, _, id, id, id, BOOL) -> NSUInteger);
decl.add_method(
sel!(application:printFile:),
print_file::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:printFiles:withSettings:showPrintPanels:),
print_files::<T> as extern "C" fn(&Object, _, id, id, id, BOOL) -> NSUInteger
);
// @TODO: Restoring Application State
// Depends on NSCoder support, which is... welp.
// Scripting
decl.add_method(sel!(application:delegateHandlesKey:), delegate_handles_key::<T> as extern fn(&Object, _, _, id) -> BOOL);
decl.add_method(
sel!(application:delegateHandlesKey:),
delegate_handles_key::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
DELEGATE_CLASS = decl.register();
});
unsafe {
DELEGATE_CLASS
}
unsafe { DELEGATE_CLASS }
}

View file

@ -39,13 +39,13 @@ use std::sync::{Arc, Mutex};
use lazy_static::lazy_static;
use objc_id::Id;
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, nil, YES, NO, NSUInteger, AutoReleasePool};
use crate::invoker::TargetActionHandler;
use crate::appkit::menu::Menu;
use crate::foundation::{id, nil, AutoReleasePool, NSUInteger, NO, YES};
use crate::invoker::TargetActionHandler;
use crate::notification_center::Dispatcher;
use crate::utils::activate_cocoa_multithreading;
@ -128,7 +128,10 @@ impl<T> App<T> {
}
}
impl<T> App<T> where T: AppDelegate + 'static {
impl<T> App<T>
where
T: AppDelegate + 'static
{
/// Creates an NSAutoReleasePool, configures various NSApplication properties (e.g, activation
/// policies), injects an `NSObject` delegate wrapper, and retains everything on the
/// Objective-C side of things.
@ -180,7 +183,11 @@ impl<T> App<T> where T: AppDelegate + 'static {
// ObjC and such is fast enough that for a large class of applications this is workable.
//
// tl;dr: This is all a bit of a hack, and should go away eventually. :)
impl<T, M> App<T, M> where M: Send + Sync + 'static, T: AppDelegate + Dispatcher<Message = M> {
impl<T, M> App<T, M>
where
M: Send + Sync + 'static,
T: AppDelegate + Dispatcher<Message = M>
{
/// Dispatches a message by grabbing the `sharedApplication`, getting ahold of the delegate,
/// and passing back through there.
pub fn dispatch_main(message: M) {

View file

@ -35,12 +35,16 @@ pub trait AppDelegate {
fn will_resign_active(&self) {}
/// Fired when the user is going to continue an activity.
fn will_continue_user_activity(&self, _activity_type: &str) -> bool { false }
fn will_continue_user_activity(&self, _activity_type: &str) -> bool {
false
}
/// Fired when data for continuing an activity is available. Currently, the
/// `restoration_handler` is not used, but there to communicate intent with what this API will
/// eventually be doing.
fn continue_user_activity<F: Fn()>(&self, _activity: UserActivity, _restoration_handler: F) -> bool { false }
fn continue_user_activity<F: Fn()>(&self, _activity: UserActivity, _restoration_handler: F) -> bool {
false
}
/// Fired when the activity could not be continued.
fn failed_to_continue_user_activity(&self, _activity_type: &str, _error: Error) {}
@ -96,11 +100,15 @@ pub trait AppDelegate {
/// though, you can cancel the termination via `TerminateResponse::Cancel` to continue something essential. If
/// you do this, you'll need to be sure to call `App::reply_to_termination_request()` to circle
/// back.
fn should_terminate(&self) -> TerminateResponse { TerminateResponse::Now }
fn should_terminate(&self) -> TerminateResponse {
TerminateResponse::Now
}
/// Called after closing the last open window. Return `true` here if you want
/// the application to terminate.
fn should_terminate_after_last_window_closed(&self) -> bool { false }
fn should_terminate_after_last_window_closed(&self) -> bool {
false
}
/// Sent by the application to the delegate prior to default behavior to reopen AppleEvents.
///
@ -119,16 +127,22 @@ pub trait AppDelegate {
///
/// [Read more
/// here](https://developer.apple.com/documentation/appkit/nsapplicationdelegate/1428638-applicationshouldhandlereopen?language=objc)
fn should_handle_reopen(&self, _has_visible_windows: bool) -> bool { true }
fn should_handle_reopen(&self, _has_visible_windows: bool) -> bool {
true
}
/// Supply a dock menu for the application dynamically. The default implementation for this
/// method returns `None`, for no menu.
fn dock_menu(&self) -> Option<Menu> { None }
fn dock_menu(&self) -> Option<Menu> {
None
}
/// Fired before the application presents an error message to the user. If you find the error
/// to be... not what you want, you can take it, alter it, and return it anew. The default
/// implementation of this method simply returns the error as-is.
fn will_present_error(&self, error: Error) -> Error { error }
fn will_present_error(&self, error: Error) -> Error {
error
}
/// Fired when the screen parameters for the application have changed (e.g, the user changed
/// something in their settings).
@ -156,28 +170,38 @@ pub trait AppDelegate {
/// work with the file is under programmatic control of sender, rather than under keyboard control of the user."_
///
/// It's unclear how supported this is in sandbox environments, so use at your own risk.
fn open_file_without_ui(&self, _filename: &str) -> bool { false }
fn open_file_without_ui(&self, _filename: &str) -> bool {
false
}
/// Fired when the application is ready and able to open a temporary file.
/// Return `true` or `false` here depending on whether the operation was successful.
///
/// It's your responsibility to remove the temp file.
fn open_temp_file(&self, _filename: &str) -> bool { false }
fn open_temp_file(&self, _filename: &str) -> bool {
false
}
/// Fired before attempting to open an untitled file. Return `true` here if you want
/// `open_untitled_file` to be called by the system.
fn should_open_untitled_file(&self) -> bool { false }
fn should_open_untitled_file(&self) -> bool {
false
}
/// Called when the application has asked you to open a new, untitled file.
/// Returns a `bool` indicating whether the file was successfully opened or not.
fn open_untitled_file(&self) -> bool { true }
fn open_untitled_file(&self) -> bool {
true
}
/// Sent when the user starts up the application on the command line with the -NSPrint option.
/// The application terminates immediately after this method returns. For more information,
/// cosnult the official Apple documentation.
///
/// (You probably never need to implement this, but we support it anyway)
fn print_file(&self, _filename: &str) -> bool { false }
fn print_file(&self, _filename: &str) -> bool {
false
}
/// Called when the user has requested to print some files.
///
@ -203,5 +227,7 @@ pub trait AppDelegate {
/// Fired when the system wants to know whether your application, via scripting, can handle the
/// key specifying operations.
fn delegate_handles_key(&self, _key: &str) -> bool { false }
fn delegate_handles_key(&self, _key: &str) -> bool {
false
}
}

View file

@ -1,6 +1,6 @@
use objc::{class, msg_send, sel, sel_impl};
use crate::foundation::{id, YES, NO};
use crate::foundation::{id, NO, YES};
/// Represents a type of cursor that you can associate with mouse movement.
/// @TODO: Loading?

View file

@ -1,6 +1,6 @@
//! Generic enums that don't fit anywhere else yet.
use crate::foundation::{NSUInteger};
use crate::foundation::NSUInteger;
/// Used to set whether and/or how a view or cell draws a focus ring.
#[derive(Debug)]

View file

@ -1,9 +1,8 @@
use block::ConcreteBlock;
use objc::runtime::Object;
use objc_id::Id;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, nil, NSString};
@ -23,18 +22,14 @@ pub struct Event(pub Id<Object>);
impl Event {
pub(crate) fn new(objc: id) -> Self {
Event(unsafe {
Id::from_ptr(objc)
})
Event(unsafe { Id::from_ptr(objc) })
}
pub fn characters(&self) -> String {
// @TODO: Check here if key event, invalid otherwise.
// @TODO: Figure out if we can just return &str here, since the Objective-C side
// should... make it work, I think.
let characters = NSString::retain(unsafe {
msg_send![&*self.0, characters]
});
let characters = NSString::retain(unsafe { msg_send![&*self.0, characters] });
characters.to_string()
}

View file

@ -6,13 +6,13 @@ use std::fmt;
use std::sync::Once;
use block::ConcreteBlock;
use objc::{class, msg_send, sel, sel_impl};
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, nil, NSString, NSUInteger};
use crate::events::EventModifierFlag;
use crate::foundation::{id, nil, NSString, NSUInteger};
static BLOCK_PTR: &'static str = "cacaoMenuItemBlockPtr";
@ -30,9 +30,7 @@ impl fmt::Debug for Action {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ptr = format!("{:p}", self.0);
f.debug_struct("Action")
.field("fn", &ptr)
.finish()
f.debug_struct("Action").field("fn", &ptr).finish()
}
}
@ -287,7 +285,7 @@ impl MenuItem {
/// On the Objective-C side, we need to ensure our handler is dropped when this subclass
/// is deallocated. Note that NSMenuItem is seemingly odd outside of ARC contexts, and we
/// need to do some extra logic to ensure release calls are properly sent.
extern fn dealloc_cacao_menuitem(this: &Object, _: Sel) {
extern "C" fn dealloc_cacao_menuitem(this: &Object, _: Sel) {
unsafe {
let ptr: usize = *this.get_ivar(BLOCK_PTR);
let obj = ptr as *mut Action;
@ -305,7 +303,7 @@ extern fn dealloc_cacao_menuitem(this: &Object, _: Sel) {
}
/// Called when our custom item needs to fire.
extern fn fire_block_action(this: &Object, _: Sel, _item: id) {
extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) {
let action = crate::utils::load::<Action>(this, BLOCK_PTR);
(action.0)();
}
@ -324,13 +322,11 @@ pub(crate) fn register_menu_item_class() -> *const Class {
let mut decl = ClassDecl::new("CacaoMenuItem", superclass).unwrap();
decl.add_ivar::<usize>(BLOCK_PTR);
decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern fn(&Object, _));
decl.add_method(sel!(fireBlockAction:), fire_block_action as extern fn(&Object, _, id));
decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(&Object, _));
decl.add_method(sel!(fireBlockAction:), fire_block_action as extern "C" fn(&Object, _, id));
APP_CLASS = decl.register();
});
unsafe {
APP_CLASS
}
unsafe { APP_CLASS }
}

View file

@ -2,12 +2,12 @@
use std::sync::{Arc, Mutex};
use objc_id::{Id, ShareId};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::{Id, ShareId};
use crate::foundation::{id, NSInteger, NSString};
use crate::appkit::menu::item::MenuItem;
use crate::foundation::{id, NSInteger, NSString};
/// A struct that represents an `NSMenu`. It takes ownership of items, and handles instrumenting
/// them throughout the application lifecycle.
@ -82,13 +82,9 @@ impl Menu {
MenuItem::HideOthers,
MenuItem::ShowAll,
MenuItem::Separator,
MenuItem::Quit
MenuItem::Quit,
]),
Menu::new("File", vec![
MenuItem::CloseWindow
]),
Menu::new("File", vec![MenuItem::CloseWindow]),
Menu::new("Edit", vec![
MenuItem::Undo,
MenuItem::Redo,
@ -97,19 +93,15 @@ impl Menu {
MenuItem::Copy,
MenuItem::Paste,
MenuItem::Separator,
MenuItem::SelectAll
MenuItem::SelectAll,
]),
Menu::new("View", vec![
MenuItem::EnterFullScreen
]),
Menu::new("View", vec![MenuItem::EnterFullScreen]),
Menu::new("Window", vec![
MenuItem::Minimize,
MenuItem::Zoom,
MenuItem::Separator,
MenuItem::new("Bring All to Front")
])
MenuItem::new("Bring All to Front"),
]),
]
}
}

View file

@ -4,28 +4,18 @@ use std::sync::Once;
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, sel, sel_impl, msg_send};
use objc::{class, msg_send, sel, sel_impl};
use crate::foundation::{load_or_register_class, id, BOOL, NSArray, NSString};
use crate::appkit::toolbar::{TOOLBAR_PTR, ToolbarDelegate};
use crate::appkit::toolbar::{ToolbarDelegate, TOOLBAR_PTR};
use crate::foundation::{id, load_or_register_class, NSArray, NSString, BOOL};
use crate::utils::load;
/// Retrieves and passes the allowed item identifiers for this toolbar.
extern fn allowed_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
extern "C" fn allowed_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar.allowed_item_identifiers().iter().map(|identifier| {
identifier.to_nsstring()
}).collect::<Vec<id>>().into();
identifiers.into()
}
/// Retrieves and passes the default item identifiers for this toolbar.
extern fn default_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar.default_item_identifiers()
let identifiers: NSArray = toolbar
.allowed_item_identifiers()
.iter()
.map(|identifier| identifier.to_nsstring())
.collect::<Vec<id>>()
@ -35,10 +25,25 @@ extern fn default_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _:
}
/// Retrieves and passes the default item identifiers for this toolbar.
extern fn selectable_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
extern "C" fn default_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar.selectable_item_identifiers()
let identifiers: NSArray = toolbar
.default_item_identifiers()
.iter()
.map(|identifier| identifier.to_nsstring())
.collect::<Vec<id>>()
.into();
identifiers.into()
}
/// Retrieves and passes the default item identifiers for this toolbar.
extern "C" fn selectable_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel, _: id) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifiers: NSArray = toolbar
.selectable_item_identifiers()
.iter()
.map(|identifier| identifier.to_nsstring())
.collect::<Vec<id>>()
@ -49,20 +54,12 @@ extern fn selectable_item_identifiers<T: ToolbarDelegate>(this: &Object, _: Sel,
/// Loads the controller, grabs whatever item is for this identifier, and returns what the
/// Objective-C runtime needs.
extern fn item_for_identifier<T: ToolbarDelegate>(
this: &Object,
_: Sel,
_: id,
identifier: id,
_: BOOL
) -> id {
extern "C" fn item_for_identifier<T: ToolbarDelegate>(this: &Object, _: Sel, _: id, identifier: id, _: BOOL) -> id {
let toolbar = load::<T>(this, TOOLBAR_PTR);
let identifier = NSString::from_retained(identifier);
let item = toolbar.item_for(identifier.to_str());
unsafe {
msg_send![&*item.objc, self]
}
unsafe { msg_send![&*item.objc, self] }
//&mut *item.objc
}
@ -76,19 +73,19 @@ pub(crate) fn register_toolbar_class<T: ToolbarDelegate>(instance: &T) -> *const
// Add callback methods
decl.add_method(
sel!(toolbarAllowedItemIdentifiers:),
allowed_item_identifiers::<T> as extern fn(&Object, _, _) -> id
allowed_item_identifiers::<T> as extern "C" fn(&Object, _, _) -> id
);
decl.add_method(
sel!(toolbarDefaultItemIdentifiers:),
default_item_identifiers::<T> as extern fn(&Object, _, _) -> id
default_item_identifiers::<T> as extern "C" fn(&Object, _, _) -> id
);
decl.add_method(
sel!(toolbarSelectableItemIdentifiers:),
selectable_item_identifiers::<T> as extern fn(&Object, _, _) -> id
selectable_item_identifiers::<T> as extern "C" fn(&Object, _, _) -> id
);
decl.add_method(
sel!(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:),
item_for_identifier::<T> as extern fn(&Object, _, _, _, _) -> id
item_for_identifier::<T> as extern "C" fn(&Object, _, _, _, _) -> id
);
})
}

View file

@ -3,17 +3,17 @@
//!
//! UNFORTUNATELY, this is a very old and janky API. So... yeah.
use std::fmt;
use core_graphics::geometry::CGSize;
use std::fmt;
use objc_id::{Id, ShareId};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::{Id, ShareId};
use crate::foundation::{id, YES, NO, NSString};
use crate::invoker::TargetActionHandler;
use crate::button::{Button, BezelStyle};
use crate::button::{BezelStyle, Button};
use crate::foundation::{id, NSString, NO, YES};
use crate::image::Image;
use crate::invoker::TargetActionHandler;
/// Wraps `NSToolbarItem`. Enables configuring things like size, view, and so on.
#[derive(Debug)]

View file

@ -5,11 +5,11 @@
use std::fmt;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, YES, NO, NSString, NSUInteger};
use crate::foundation::{id, nil, NSString, NSUInteger, NO, YES};
mod class;
use class::register_toolbar_class;
@ -21,7 +21,7 @@ mod traits;
pub use traits::ToolbarDelegate;
mod enums;
pub use enums::{ToolbarDisplayMode, ToolbarSizeMode, ItemIdentifier};
pub use enums::{ItemIdentifier, ToolbarDisplayMode, ToolbarSizeMode};
pub(crate) static TOOLBAR_PTR: &str = "cacaoToolbarPtr";
@ -41,7 +41,10 @@ pub struct Toolbar<T = ()> {
pub delegate: Option<Box<T>>
}
impl<T> Toolbar<T> where T: ToolbarDelegate + 'static {
impl<T> Toolbar<T>
where
T: ToolbarDelegate + 'static
{
/// Creates a new `NSToolbar` instance, configures it appropriately, sets up the delegate
/// chain, and retains it all.
pub fn new<S: Into<String>>(identifier: S, delegate: T) -> Self {
@ -73,7 +76,7 @@ impl<T> Toolbar<T> where T: ToolbarDelegate + 'static {
identifier,
objc,
objc_delegate,
delegate: Some(delegate),
delegate: Some(delegate)
}
}
}

View file

@ -2,7 +2,7 @@
//! go. Currently a bit incomplete in that we don't support the customizing workflow, but feel free
//! to pull request it.
use crate::appkit::toolbar::{Toolbar, ToolbarItem, ItemIdentifier};
use crate::appkit::toolbar::{ItemIdentifier, Toolbar, ToolbarItem};
/// A trait that you can implement to have your struct/etc act as an `NSToolbarDelegate`.
pub trait ToolbarDelegate {
@ -30,7 +30,9 @@ pub trait ToolbarDelegate {
/// The default items in this toolbar. This defaults to a blank `Vec`, and is an optional
/// method - mostly useful for Preferences windows.
fn selectable_item_identifiers(&self) -> Vec<ItemIdentifier> { vec![] }
fn selectable_item_identifiers(&self) -> Vec<ItemIdentifier> {
vec![]
}
/// For a given `identifier`, return the `ToolbarItem` that should be displayed.
fn item_for(&self, _identifier: &str) -> &ToolbarItem;

View file

@ -9,13 +9,13 @@ use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, sel, sel_impl};
use crate::foundation::{load_or_register_class, id, BOOL, YES, NO, NSUInteger};
use crate::utils::{load, CGSize};
use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR};
use crate::foundation::{id, load_or_register_class, NSUInteger, BOOL, NO, YES};
use crate::utils::{load, CGSize};
/// Called when an `NSWindowDelegate` receives a `windowWillClose:` event.
/// Good place to clean up memory and what not.
extern fn should_close<T: WindowDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
extern "C" fn should_close<T: WindowDelegate>(this: &Object, _: Sel, _: id) -> BOOL {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
match window.should_close() {
@ -26,37 +26,37 @@ extern fn should_close<T: WindowDelegate>(this: &Object, _: Sel, _: id) -> BOOL
/// Called when an `NSWindowDelegate` receives a `windowWillClose:` event.
/// Good place to clean up memory and what not.
extern fn will_close<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_close<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.will_close();
}
/// Called when an `NSWindowDelegate` receives a `windowWillMove:` event.
extern fn will_move<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_move<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.will_move();
}
/// Called when an `NSWindowDelegate` receives a `windowDidMove:` event.
extern fn did_move<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_move<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_move();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn did_change_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_change_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_change_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn did_change_screen_profile<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_change_screen_profile<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_change_screen_profile();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn will_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id, size: CGSize) -> CGSize {
extern "C" fn will_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id, size: CGSize) -> CGSize {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
let s = window.will_resize(size.width as f64, size.height as f64);
@ -67,61 +67,58 @@ extern fn will_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id, size: CGS
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn did_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_resize();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn will_start_live_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_start_live_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.will_start_live_resize();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn did_end_live_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_end_live_resize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_end_live_resize();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn will_miniaturize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_miniaturize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.will_miniaturize();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn did_miniaturize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_miniaturize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_miniaturize();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreen:` event.
extern fn did_deminiaturize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_deminiaturize<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_deminiaturize();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn will_enter_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_enter_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.will_enter_full_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn did_enter_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_enter_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_enter_full_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn content_size_for_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id, size: CGSize) -> CGSize {
extern "C" fn content_size_for_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id, size: CGSize) -> CGSize {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
let (width, height) = window.content_size_for_full_screen(
size.width as f64,
size.height as f64
);
let (width, height) = window.content_size_for_full_screen(size.width as f64, size.height as f64);
CGSize {
width: width as CGFloat,
@ -130,7 +127,7 @@ extern fn content_size_for_full_screen<T: WindowDelegate>(this: &Object, _: Sel,
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn options_for_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id, options: NSUInteger) -> NSUInteger {
extern "C" fn options_for_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id, options: NSUInteger) -> NSUInteger {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
let desired_opts = window.presentation_options_for_full_screen();
@ -148,73 +145,73 @@ extern fn options_for_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: i
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn will_exit_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn will_exit_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.will_exit_full_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn did_exit_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_exit_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_exit_full_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn did_fail_to_enter_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_fail_to_enter_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_fail_to_enter_full_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeScreenProfile:` event.
extern fn did_fail_to_exit_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_fail_to_exit_full_screen<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_fail_to_exit_full_screen();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeBackingProperties:` event.
extern fn did_change_backing_properties<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_change_backing_properties<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_change_backing_properties();
}
/// Called when an `NSWindowDelegate` receives a `windowDidChangeBackingProperties:` event.
extern fn did_change_occlusion_state<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_change_occlusion_state<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_change_occlusion_state();
}
/// Called when an `NSWindowDelegate` receives a `windowDidUpdate:` event.
extern fn did_update<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_update<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_update();
}
/// Called when an `NSWindowDelegate` receives a `windowDidExpose:` event.
extern fn did_become_main<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_become_main<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_become_main();
}
/// Called when an `NSWindowDelegate` receives a `windowDidExpose:` event.
extern fn did_resign_main<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_resign_main<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_resign_main();
}
/// Called when an `NSWindowDelegate` receives a `windowDidExpose:` event.
extern fn did_become_key<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_become_key<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_become_key();
}
/// Called when an `NSWindowDelegate` receives a `windowDidExpose:` event.
extern fn did_resign_key<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_resign_key<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_resign_key();
}
/// Called when an `NSWindowDelegate` receives a `windowDidExpose:` event.
extern fn did_expose<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn did_expose<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.did_expose();
}
@ -223,7 +220,7 @@ extern fn did_expose<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
/// delegate returns `true` in `should_cancel_on_esc`, then this will allow your
/// window to close when the Esc key is hit. This is mostly useful for Sheet-presented
/// windows, and so the default response from delegates is `false` and must be opted in to.
extern fn cancel<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
extern "C" fn cancel<T: WindowDelegate>(this: &Object, _: Sel, _: id) {
let window = load::<T>(this, WINDOW_DELEGATE_PTR);
window.cancel();
}
@ -235,49 +232,112 @@ pub(crate) fn register_window_class_with_delegate<T: WindowDelegate>(instance: &
decl.add_ivar::<usize>(WINDOW_DELEGATE_PTR);
// NSWindowDelegate methods
decl.add_method(sel!(windowShouldClose:), should_close::<T> as extern fn(&Object, _, _) -> BOOL);
decl.add_method(sel!(windowWillClose:), will_close::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(windowShouldClose:),
should_close::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(sel!(windowWillClose:), will_close::<T> as extern "C" fn(&Object, _, _));
// Sizing
decl.add_method(sel!(windowWillResize:toSize:), will_resize::<T> as extern fn(&Object, _, _, CGSize) -> CGSize);
decl.add_method(sel!(windowDidResize:), did_resize::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowWillStartLiveResize:), will_start_live_resize::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidEndLiveResize:), did_end_live_resize::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(windowWillResize:toSize:),
will_resize::<T> as extern "C" fn(&Object, _, _, CGSize) -> CGSize
);
decl.add_method(sel!(windowDidResize:), did_resize::<T> as extern "C" fn(&Object, _, _));
decl.add_method(
sel!(windowWillStartLiveResize:),
will_start_live_resize::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidEndLiveResize:),
did_end_live_resize::<T> as extern "C" fn(&Object, _, _)
);
// Minimizing
decl.add_method(sel!(windowWillMiniaturize:), will_miniaturize::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidMiniaturize:), did_miniaturize::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidDeminiaturize:), did_deminiaturize::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(windowWillMiniaturize:),
will_miniaturize::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidMiniaturize:),
did_miniaturize::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidDeminiaturize:),
did_deminiaturize::<T> as extern "C" fn(&Object, _, _)
);
// Full Screen
decl.add_method(sel!(window:willUseFullScreenContentSize:), content_size_for_full_screen::<T> as extern fn(&Object, _, _, CGSize) -> CGSize);
decl.add_method(sel!(window:willUseFullScreenPresentationOptions:), options_for_full_screen::<T> as extern fn(&Object, _, _, NSUInteger) -> NSUInteger);
decl.add_method(sel!(windowWillEnterFullScreen:), will_enter_full_screen::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidEnterFullScreen:), did_enter_full_screen::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowWillExitFullScreen:), will_exit_full_screen::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidExitFullScreen:), did_exit_full_screen::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidFailToEnterFullScreen:), did_fail_to_enter_full_screen::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidFailToExitFullScreen:), did_fail_to_exit_full_screen::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(window:willUseFullScreenContentSize:),
content_size_for_full_screen::<T> as extern "C" fn(&Object, _, _, CGSize) -> CGSize
);
decl.add_method(
sel!(window:willUseFullScreenPresentationOptions:),
options_for_full_screen::<T> as extern "C" fn(&Object, _, _, NSUInteger) -> NSUInteger
);
decl.add_method(
sel!(windowWillEnterFullScreen:),
will_enter_full_screen::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidEnterFullScreen:),
did_enter_full_screen::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowWillExitFullScreen:),
will_exit_full_screen::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidExitFullScreen:),
did_exit_full_screen::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidFailToEnterFullScreen:),
did_fail_to_enter_full_screen::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidFailToExitFullScreen:),
did_fail_to_exit_full_screen::<T> as extern "C" fn(&Object, _, _)
);
// Key status
decl.add_method(sel!(windowDidBecomeKey:), did_become_key::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidResignKey:), did_resign_key::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidBecomeKey:), did_become_key::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(windowDidResignKey:), did_resign_key::<T> as extern "C" fn(&Object, _, _));
// Main status
decl.add_method(sel!(windowDidBecomeMain:), did_become_main::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidResignMain:), did_resign_main::<T> as extern fn(&Object, _, _));
decl.add_method(
sel!(windowDidBecomeMain:),
did_become_main::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidResignMain:),
did_resign_main::<T> as extern "C" fn(&Object, _, _)
);
// Moving Windows
decl.add_method(sel!(windowWillMove:), will_move::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidMove:), did_move::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidChangeScreen:), did_change_screen::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidChangeScreenProfile:), did_change_screen_profile::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidChangeBackingProperties:), did_change_backing_properties::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowWillMove:), will_move::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(windowDidMove:), did_move::<T> as extern "C" fn(&Object, _, _));
decl.add_method(
sel!(windowDidChangeScreen:),
did_change_screen::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidChangeScreenProfile:),
did_change_screen_profile::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(windowDidChangeBackingProperties:),
did_change_backing_properties::<T> as extern "C" fn(&Object, _, _)
);
// Random
decl.add_method(sel!(windowDidChangeOcclusionState:), did_change_occlusion_state::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidExpose:), did_expose::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(windowDidUpdate:), did_update::<T> as extern fn(&Object, _, _));
decl.add_method(sel!(cancelOperation:), cancel::<T> as extern fn (&Object, _, _));
decl.add_method(
sel!(windowDidChangeOcclusionState:),
did_change_occlusion_state::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(sel!(windowDidExpose:), did_expose::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(windowDidUpdate:), did_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(cancelOperation:), cancel::<T> as extern "C" fn(&Object, _, _));
})
}

View file

@ -2,9 +2,9 @@
//! mask). This configuration object acts as a way to orchestrate enabling customization before the
//! window object is created - it's returned in your `WindowDelegate` object.
use crate::appkit::window::enums::{WindowStyle, WindowToolbarStyle};
use crate::foundation::NSUInteger;
use crate::geometry::Rect;
use crate::appkit::window::enums::{WindowStyle, WindowToolbarStyle};
#[derive(Debug)]
pub struct WindowConfig {
@ -45,8 +45,12 @@ impl Default for WindowConfig {
};
config.set_styles(&[
WindowStyle::Resizable, WindowStyle::Miniaturizable, WindowStyle::UnifiedTitleAndToolbar,
WindowStyle::Closable, WindowStyle::Titled, WindowStyle::FullSizeContentView
WindowStyle::Resizable,
WindowStyle::Miniaturizable,
WindowStyle::UnifiedTitleAndToolbar,
WindowStyle::Closable,
WindowStyle::Titled,
WindowStyle::FullSizeContentView
]);
config

View file

@ -3,9 +3,9 @@
use std::sync::Once;
use objc::class;
use objc::declare::ClassDecl;
use objc::runtime::Class;
use objc::class;
use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR};
@ -22,7 +22,5 @@ pub(crate) fn register_window_controller_class<T: WindowDelegate>() -> *const Cl
DELEGATE_CLASS = decl.register();
});
unsafe {
DELEGATE_CLASS
}
unsafe { DELEGATE_CLASS }
}

View file

@ -33,9 +33,9 @@ use objc::runtime::Object;
use objc::{msg_send, sel, sel_impl};
use objc_id::Id;
use crate::appkit::window::{Window, WindowConfig, WindowDelegate, WINDOW_DELEGATE_PTR};
use crate::foundation::{id, nil};
use crate::utils::Controller;
use crate::appkit::window::{Window, WindowConfig, WindowDelegate, WINDOW_DELEGATE_PTR};
mod class;
use class::register_window_controller_class;
@ -50,7 +50,10 @@ pub struct WindowController<T> {
pub window: Window<T>
}
impl<T> WindowController<T> where T: WindowDelegate + 'static {
impl<T> WindowController<T>
where
T: WindowDelegate + 'static
{
/// Allocates and configures an `NSWindowController` in the Objective-C/Cocoa runtime that maps over
/// to your supplied delegate.
pub fn with(config: WindowConfig, delegate: T) -> Self {
@ -98,8 +101,6 @@ impl<T> WindowController<T> where T: WindowDelegate + 'static {
impl<T> fmt::Debug for WindowController<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WindowController")
.field("objc", &self.objc)
.finish()
f.debug_struct("WindowController").field("objc", &self.objc).finish()
}
}

View file

@ -13,13 +13,13 @@ use block::ConcreteBlock;
use core_graphics::base::CGFloat;
use core_graphics::geometry::{CGRect, CGSize};
use objc::{msg_send, sel, sel_impl, class};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::appkit::toolbar::{Toolbar, ToolbarDelegate};
use crate::color::Color;
use crate::foundation::{id, nil, to_bool, YES, NO, NSString, NSInteger, NSUInteger};
use crate::foundation::{id, nil, to_bool, NSInteger, NSString, NSUInteger, NO, YES};
use crate::layout::Layout;
use crate::objc_access::ObjcAccess;
use crate::utils::{os, Controller};
@ -114,7 +114,10 @@ impl Window {
}
}
impl<T> Window<T> where T: WindowDelegate + 'static {
impl<T> Window<T>
where
T: WindowDelegate + 'static
{
/// Constructs a new Window with a `config` and `delegate`. Using a `WindowDelegate` enables
/// you to respond to window lifecycle events - visibility, movement, and so on. It also
/// enables easier structure of your codebase, and in a way simulates traditional class based
@ -339,16 +342,12 @@ impl<T> Window<T> {
/// Returns whether this window is opaque or not.
pub fn is_opaque(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, isOpaque]
})
to_bool(unsafe { msg_send![&*self.objc, isOpaque] })
}
/// Returns whether this window is miniaturized or not.
pub fn is_miniaturized(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, isMiniaturized]
})
to_bool(unsafe { msg_send![&*self.objc, isMiniaturized] })
}
/// Miniaturize this window.
@ -382,30 +381,22 @@ impl<T> Window<T> {
/// space. For nonvisible windows, it indicates whether ordering the window onscreen would cause it to
/// be on the active space._
pub fn is_on_active_space(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, isOnActiveSpace]
})
to_bool(unsafe { msg_send![&*self.objc, isOnActiveSpace] })
}
/// Returns whether this window is visible or not.
pub fn is_visible(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, isVisible]
})
to_bool(unsafe { msg_send![&*self.objc, isVisible] })
}
/// Returns whether this window is the key or not.
pub fn is_key(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, isKeyWindow]
})
to_bool(unsafe { msg_send![&*self.objc, isKeyWindow] })
}
/// Returns whether this window can become the key window.
pub fn can_become_key(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, canBecomeKeyWindow]
})
to_bool(unsafe { msg_send![&*self.objc, canBecomeKeyWindow] })
}
/// Make this window the key window.
@ -425,16 +416,12 @@ impl<T> Window<T> {
/// Returns if this is the main window or not.
pub fn is_main_window(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, isMainWindow]
})
to_bool(unsafe { msg_send![&*self.objc, isMainWindow] })
}
/// Returns if this can become the main window.
pub fn can_become_main_window(&self) -> bool {
to_bool(unsafe {
msg_send![&*self.objc, canBecomeMainWindow]
})
to_bool(unsafe { msg_send![&*self.objc, canBecomeMainWindow] })
}
/// Set whether this window should be excluded from the top-level "Windows" menu.

View file

@ -28,7 +28,9 @@ pub trait WindowDelegate {
/// Called when the user has attempted to close the window. NOT called when a user quits the
/// application. Return false here if you need to handle the edge case.
fn should_close(&self) -> bool { true }
fn should_close(&self) -> bool {
true
}
/// Fires when a window is going to close. You might opt to, say, clean up things here -
/// perhaps you have a long running task, or something that should be removed.
@ -46,7 +48,9 @@ pub trait WindowDelegate {
///
/// The default implementation of this method returns `None`, indicating the system should just
/// do its thing. If you implement it, you probably want that.
fn will_resize(&self, width: f64, height: f64) -> (f64, f64) { (width, height) }
fn will_resize(&self, width: f64, height: f64) -> (f64, f64) {
(width, height)
}
/// Fired after the window has resized.
fn did_resize(&self) {}
@ -100,7 +104,9 @@ pub trait WindowDelegate {
/// Specify options for when this window goes full screen.
/// By default, this returns `None`, which tells the system to proceed as it normally would
/// without customization.
fn presentation_options_for_full_screen(&self) -> Option<&[PresentationOption]> { None }
fn presentation_options_for_full_screen(&self) -> Option<&[PresentationOption]> {
None
}
/// Fires when this window is about to go full screen.
fn will_enter_full_screen(&self) {}

View file

@ -23,15 +23,15 @@ use std::sync::Once;
use std::cell::RefCell;
use std::rc::Rc;
use objc_id::ShareId;
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::color::Color;
use crate::control::Control;
use crate::foundation::{id, nil, NSString, NSUInteger, BOOL, NO, YES};
use crate::image::Image;
use crate::foundation::{id, nil, BOOL, YES, NO, NSString, NSUInteger};
use crate::invoker::TargetActionHandler;
use crate::keys::Key;
use crate::layout::Layout;
@ -40,7 +40,7 @@ use crate::text::{AttributedString, Font};
use crate::utils::{load, properties::ObjcProperty};
#[cfg(feature = "autolayout")]
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
#[cfg(feature = "appkit")]
use crate::appkit::FocusRingType;
@ -171,7 +171,7 @@ impl Button {
#[cfg(feature = "autolayout")]
center_y: LayoutAnchorY::center(view),
objc: ObjcProperty::retain(view),
objc: ObjcProperty::retain(view)
}
}

View file

@ -19,7 +19,7 @@ use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel, BOOL};
use objc::{class, msg_send, sel, sel_impl};
use crate::foundation::{id, nil, YES, NO, NSInteger, NSUInteger, NSString, NSArray};
use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger, NO, YES};
use crate::utils::os;
pub(crate) const AQUA_LIGHT_COLOR_NORMAL_CONTRAST: &'static str = "AQUA_LIGHT_COLOR_NORMAL_CONTRAST";
@ -82,162 +82,178 @@ fn get_effective_color(this: &Object) -> id {
}
}
extern fn color_space(this: &Object, _: Sel) -> id {
extern "C" fn color_space(this: &Object, _: Sel) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, colorSpace] }
}
extern fn color_using_color_space(this: &Object, _: Sel, color_space: id) -> id {
extern "C" fn color_using_color_space(this: &Object, _: Sel, color_space: id) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, colorUsingColorSpace: color_space] }
}
extern fn color_space_name(this: &Object, _: Sel) -> id {
extern "C" fn color_space_name(this: &Object, _: Sel) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, colorSpaceName] }
}
extern fn color_using_color_space_name(this: &Object, _: Sel, color_space_name: id) -> id {
extern "C" fn color_using_color_space_name(this: &Object, _: Sel, color_space_name: id) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, colorUsingColorSpaceName: color_space_name] }
}
extern fn number_of_components(this: &Object, _: Sel) -> NSInteger {
extern "C" fn number_of_components(this: &Object, _: Sel) -> NSInteger {
let color = get_effective_color(this);
unsafe { msg_send![color, numberOfComponents] }
}
// @TODO: Confirm this.
extern fn get_components(this: &Object, _: Sel, components: CGFloat) {
extern "C" fn get_components(this: &Object, _: Sel, components: CGFloat) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, getComponents:components]; }
unsafe {
let _: () = msg_send![color, getComponents: components];
}
}
// @TODO: Confirm this.
extern fn get_rgba(this: &Object, _: Sel, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
extern "C" fn get_rgba(this: &Object, _: Sel, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, getRed:red green:green blue:blue alpha:alpha]; }
unsafe {
let _: () = msg_send![color, getRed:red green:green blue:blue alpha:alpha];
}
}
extern fn red_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn red_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, redComponent] }
}
extern fn green_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn green_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, greenComponent] }
}
extern fn blue_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn blue_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, blueComponent] }
}
extern fn hue_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn hue_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, hueComponent] }
}
extern fn saturation_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn saturation_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, saturationComponent] }
}
extern fn brightness_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn brightness_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, brightnessComponent] }
}
// @TODO: Confirm this.
extern fn get_hsba(this: &Object, _: Sel, hue: CGFloat, sat: CGFloat, brit: CGFloat, alpha: CGFloat) {
extern "C" fn get_hsba(this: &Object, _: Sel, hue: CGFloat, sat: CGFloat, brit: CGFloat, alpha: CGFloat) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, getHue:hue saturation:sat brightness:brit alpha:alpha]; }
unsafe {
let _: () = msg_send![color, getHue:hue saturation:sat brightness:brit alpha:alpha];
}
}
extern fn white_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn white_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, whiteComponent] }
}
// @TODO: Confirm this.
extern fn get_white(this: &Object, _: Sel, white: CGFloat, alpha: CGFloat) {
extern "C" fn get_white(this: &Object, _: Sel, white: CGFloat, alpha: CGFloat) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, getWhite:white alpha:alpha]; }
unsafe {
let _: () = msg_send![color, getWhite:white alpha:alpha];
}
}
extern fn cyan_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn cyan_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, cyanComponent] }
}
extern fn magenta_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn magenta_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, magentaComponent] }
}
extern fn yellow_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn yellow_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, yellowComponent] }
}
extern fn black_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn black_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, blackComponent] }
}
// @TODO: Confirm this.
extern fn get_cmyk(this: &Object, _: Sel, c: CGFloat, m: CGFloat, y: CGFloat, k: CGFloat, a: CGFloat) {
extern "C" fn get_cmyk(this: &Object, _: Sel, c: CGFloat, m: CGFloat, y: CGFloat, k: CGFloat, a: CGFloat) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, getCyan:c magenta:m yellow:y black:k alpha:a]; }
unsafe {
let _: () = msg_send![color, getCyan:c magenta:m yellow:y black:k alpha:a];
}
}
extern fn alpha_component(this: &Object, _: Sel) -> CGFloat {
extern "C" fn alpha_component(this: &Object, _: Sel) -> CGFloat {
let color = get_effective_color(this);
unsafe { msg_send![color, alphaComponent] }
}
extern fn cg_color(this: &Object, _: Sel) -> id {
extern "C" fn cg_color(this: &Object, _: Sel) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, CGColor] }
}
extern fn set_stroke(this: &Object, _: Sel) {
extern "C" fn set_stroke(this: &Object, _: Sel) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, setStroke]; }
unsafe {
let _: () = msg_send![color, setStroke];
}
}
extern fn set_fill(this: &Object, _: Sel) {
extern "C" fn set_fill(this: &Object, _: Sel) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, setFill]; }
unsafe {
let _: () = msg_send![color, setFill];
}
}
extern fn call_set(this: &Object, _: Sel) {
extern "C" fn call_set(this: &Object, _: Sel) {
let color = get_effective_color(this);
unsafe { let _: () = msg_send![color, set]; }
unsafe {
let _: () = msg_send![color, set];
}
}
extern fn highlight_with_level(this: &Object, _: Sel, level: CGFloat) -> id {
extern "C" fn highlight_with_level(this: &Object, _: Sel, level: CGFloat) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, highlightWithLevel: level] }
}
extern fn shadow_with_level(this: &Object, _: Sel, level: CGFloat) -> id {
extern "C" fn shadow_with_level(this: &Object, _: Sel, level: CGFloat) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, shadowWithLevel: level] }
}
extern fn color_with_alpha_component(this: &Object, _: Sel, alpha: CGFloat) -> id {
extern "C" fn color_with_alpha_component(this: &Object, _: Sel, alpha: CGFloat) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, colorWithAlphaComponent: alpha] }
}
extern fn blended_color(this: &Object, _: Sel, fraction: CGFloat, with_color: id) -> id {
extern "C" fn blended_color(this: &Object, _: Sel, fraction: CGFloat, with_color: id) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, blendedColorWithFraction:fraction ofColor:with_color] }
}
extern fn color_with_system_effect(this: &Object, _: Sel, effect: NSInteger) -> id {
extern "C" fn color_with_system_effect(this: &Object, _: Sel, effect: NSInteger) -> id {
let color = get_effective_color(this);
unsafe { msg_send![color, colorWithSystemEffect: effect] }
}
@ -251,45 +267,93 @@ pub(crate) fn register_class() -> *const Class {
let mut decl = ClassDecl::new("CacaoDynamicColor", superclass).unwrap();
// These methods all need to be forwarded, so let's hook them up.
decl.add_method(sel!(colorSpace), color_space as extern fn(&Object, _) -> id);
decl.add_method(sel!(colorUsingColorSpace:), color_using_color_space as extern fn(&Object, _, id) -> id);
decl.add_method(sel!(colorSpaceName), color_space_name as extern fn(&Object, _) -> id);
decl.add_method(sel!(colorUsingColorSpaceName:), color_using_color_space_name as extern fn(&Object, _, id) -> id);
decl.add_method(sel!(numberOfComponents), number_of_components as extern fn(&Object, _) -> NSInteger);
decl.add_method(sel!(colorSpace), color_space as extern "C" fn(&Object, _) -> id);
decl.add_method(
sel!(colorUsingColorSpace:),
color_using_color_space as extern "C" fn(&Object, _, id) -> id
);
decl.add_method(sel!(colorSpaceName), color_space_name as extern "C" fn(&Object, _) -> id);
decl.add_method(
sel!(colorUsingColorSpaceName:),
color_using_color_space_name as extern "C" fn(&Object, _, id) -> id
);
decl.add_method(
sel!(numberOfComponents),
number_of_components as extern "C" fn(&Object, _) -> NSInteger
);
decl.add_method(sel!(getComponents:), get_components as extern fn(&Object, _, CGFloat));
decl.add_method(sel!(getRed:green:blue:alpha:), get_rgba as extern fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat));
decl.add_method(sel!(redComponent), red_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(greenComponent), green_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(blueComponent), blue_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(getComponents:), get_components as extern "C" fn(&Object, _, CGFloat));
decl.add_method(
sel!(getRed:green:blue:alpha:),
get_rgba as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat)
);
decl.add_method(sel!(redComponent), red_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(sel!(greenComponent), green_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(sel!(blueComponent), blue_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(sel!(hueComponent), hue_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(saturationComponent), saturation_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(brightnessComponent), brightness_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(getHue:saturation:brightness:alpha:), get_hsba as extern fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat));
decl.add_method(sel!(hueComponent), hue_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(
sel!(saturationComponent),
saturation_component as extern "C" fn(&Object, _) -> CGFloat
);
decl.add_method(
sel!(brightnessComponent),
brightness_component as extern "C" fn(&Object, _) -> CGFloat
);
decl.add_method(
sel!(getHue:saturation:brightness:alpha:),
get_hsba as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat)
);
decl.add_method(sel!(whiteComponent), white_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(getWhite:alpha:), get_white as extern fn(&Object, _, CGFloat, CGFloat));
decl.add_method(sel!(whiteComponent), white_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(
sel!(getWhite:alpha:),
get_white as extern "C" fn(&Object, _, CGFloat, CGFloat)
);
decl.add_method(sel!(cyanComponent), cyan_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(magentaComponent), magenta_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(yellowComponent), yellow_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(blackComponent), black_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(getCyan:magenta:yellow:black:alpha:), get_cmyk as extern fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat));
decl.add_method(sel!(cyanComponent), cyan_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(
sel!(magentaComponent),
magenta_component as extern "C" fn(&Object, _) -> CGFloat
);
decl.add_method(
sel!(yellowComponent),
yellow_component as extern "C" fn(&Object, _) -> CGFloat
);
decl.add_method(sel!(blackComponent), black_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(
sel!(getCyan:magenta:yellow:black:alpha:),
get_cmyk as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat)
);
decl.add_method(sel!(alphaComponent), alpha_component as extern fn(&Object, _) -> CGFloat);
decl.add_method(sel!(alphaComponent), alpha_component as extern "C" fn(&Object, _) -> CGFloat);
decl.add_method(sel!(CGColor), cg_color as extern fn(&Object, _) -> id);
decl.add_method(sel!(setStroke), set_stroke as extern fn(&Object, _));
decl.add_method(sel!(setFill), set_fill as extern fn(&Object, _));
decl.add_method(sel!(set), call_set as extern fn(&Object, _));
decl.add_method(sel!(CGColor), cg_color as extern "C" fn(&Object, _) -> id);
decl.add_method(sel!(setStroke), set_stroke as extern "C" fn(&Object, _));
decl.add_method(sel!(setFill), set_fill as extern "C" fn(&Object, _));
decl.add_method(sel!(set), call_set as extern "C" fn(&Object, _));
decl.add_method(sel!(highlightWithLevel:), highlight_with_level as extern fn(&Object, _, CGFloat) -> id);
decl.add_method(sel!(shadowWithLevel:), shadow_with_level as extern fn(&Object, _, CGFloat) -> id);
decl.add_method(
sel!(highlightWithLevel:),
highlight_with_level as extern "C" fn(&Object, _, CGFloat) -> id
);
decl.add_method(
sel!(shadowWithLevel:),
shadow_with_level as extern "C" fn(&Object, _, CGFloat) -> id
);
decl.add_method(sel!(colorWithAlphaComponent:), color_with_alpha_component as extern fn(&Object, _, CGFloat) -> id);
decl.add_method(sel!(blendedColorWithFraction:ofColor:), blended_color as extern fn(&Object, _, CGFloat, id) -> id);
decl.add_method(sel!(colorWithSystemEffect:), color_with_system_effect as extern fn(&Object, _, NSInteger) -> id);
decl.add_method(
sel!(colorWithAlphaComponent:),
color_with_alpha_component as extern "C" fn(&Object, _, CGFloat) -> id
);
decl.add_method(
sel!(blendedColorWithFraction:ofColor:),
blended_color as extern "C" fn(&Object, _, CGFloat, id) -> id
);
decl.add_method(
sel!(colorWithSystemEffect:),
color_with_system_effect as extern "C" fn(&Object, _, NSInteger) -> id
);
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_NORMAL_CONTRAST);
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_HIGH_CONTRAST);

View file

@ -13,14 +13,13 @@
/// fallbacks, specify the `color_fallbacks` target_os in your `Cargo.toml`.
///
/// @TODO: bundle iOS/tvOS support.
use std::sync::{Arc, RwLock};
use core_graphics::base::CGFloat;
use core_graphics::color::CGColor;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::id;
@ -31,8 +30,8 @@ mod appkit_dynamic_color;
#[cfg(feature = "appkit")]
use appkit_dynamic_color::{
AQUA_LIGHT_COLOR_NORMAL_CONTRAST, AQUA_LIGHT_COLOR_HIGH_CONTRAST,
AQUA_DARK_COLOR_NORMAL_CONTRAST, AQUA_DARK_COLOR_HIGH_CONTRAST
AQUA_DARK_COLOR_HIGH_CONTRAST, AQUA_DARK_COLOR_NORMAL_CONTRAST, AQUA_LIGHT_COLOR_HIGH_CONTRAST,
AQUA_LIGHT_COLOR_NORMAL_CONTRAST
};
/// Represents a rendering style - dark mode or light mode.
@ -250,10 +249,14 @@ impl Color {
Color::Custom(Arc::new(RwLock::new(unsafe {
#[cfg(feature = "appkit")]
{ Id::from_ptr(msg_send![class!(NSColor), colorWithCalibratedRed:r green:g blue:b alpha:a]) }
{
Id::from_ptr(msg_send![class!(NSColor), colorWithCalibratedRed:r green:g blue:b alpha:a])
}
#[cfg(feature = "uikit")]
{ Id::from_ptr(msg_send![class!(UIColor), colorWithRed:r green:g blue:b alpha:a]) }
{
Id::from_ptr(msg_send![class!(UIColor), colorWithRed:r green:g blue:b alpha:a])
}
})))
}
@ -273,10 +276,14 @@ impl Color {
Color::Custom(Arc::new(RwLock::new(unsafe {
#[cfg(feature = "appkit")]
{ Id::from_ptr(msg_send![class!(NSColor), colorWithCalibratedHue:h saturation:s brightness:b alpha:a]) }
{
Id::from_ptr(msg_send![class!(NSColor), colorWithCalibratedHue:h saturation:s brightness:b alpha:a])
}
#[cfg(feature = "uikit")]
{ Id::from_ptr(msg_send![class!(UIColor), colorWithHue:h saturation:s brightness:b alpha:a]) }
{
Id::from_ptr(msg_send![class!(UIColor), colorWithHue:h saturation:s brightness:b alpha:a])
}
})))
}
@ -291,10 +298,14 @@ impl Color {
pub fn white_alpha(level: CGFloat, alpha: CGFloat) -> Self {
Color::Custom(Arc::new(RwLock::new(unsafe {
#[cfg(feature = "appkit")]
{ Id::from_ptr(msg_send![class!(NSColor), colorWithCalibratedWhite:level alpha:alpha]) }
{
Id::from_ptr(msg_send![class!(NSColor), colorWithCalibratedWhite:level alpha:alpha])
}
#[cfg(feature = "uikit")]
{ Id::from_ptr(msg_send![class!(UIColor), colorWithWhite:level alpha:alpha]) }
{
Id::from_ptr(msg_send![class!(UIColor), colorWithWhite:level alpha:alpha])
}
})))
}
@ -346,7 +357,8 @@ impl Color {
let color: id = handler(Style {
theme: Theme::Light,
contrast: Contrast::Normal
}).into();
})
.into();
color
});
@ -355,7 +367,8 @@ impl Color {
let color: id = handler(Style {
theme: Theme::Light,
contrast: Contrast::High
}).into();
})
.into();
color
});
@ -364,7 +377,8 @@ impl Color {
let color: id = handler(Style {
theme: Theme::Dark,
contrast: Contrast::Normal
}).into();
})
.into();
color
});
@ -373,7 +387,8 @@ impl Color {
let color: id = handler(Style {
theme: Theme::Light,
contrast: Contrast::Normal
}).into();
})
.into();
color
});
@ -421,7 +436,7 @@ impl From<&Color> for id {
/// Handles color fallback for system-provided colors.
macro_rules! system_color_with_fallback {
($class:ident, $color:ident, $fallback:ident) => ({
($class:ident, $color:ident, $fallback:ident) => {{
#[cfg(feature = "appkit")]
{
#[cfg(feature = "color-fallbacks")]
@ -439,7 +454,7 @@ macro_rules! system_color_with_fallback {
{
msg_send![$class, $color]
}
})
}};
}
/// This function maps enum types to system-provided colors, or our stored NS/UIColor objects.
@ -508,6 +523,6 @@ unsafe fn to_objc(obj: &Color) -> id {
Color::MacOSWindowBackgroundColor => system_color_with_fallback!(color, windowBackgroundColor, clearColor),
#[cfg(feature = "appkit")]
Color::MacOSUnderPageBackgroundColor => system_color_with_fallback!(color, underPageBackgroundColor, clearColor),
Color::MacOSUnderPageBackgroundColor => system_color_with_fallback!(color, underPageBackgroundColor, clearColor)
}
}

View file

@ -1,8 +1,7 @@
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use crate::foundation::{id, YES, NO, NSUInteger};
use crate::foundation::{id, NSUInteger, NO, YES};
use crate::objc_access::ObjcAccess;
/// Use this enum for specifying NSControl size types.

View file

@ -33,14 +33,11 @@
use std::collections::HashMap;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{
id, nil, to_bool, YES, NO, BOOL,
NSData, NSString, NSMutableDictionary, NSNumber
};
use crate::foundation::{id, nil, to_bool, NSData, NSMutableDictionary, NSNumber, NSString, BOOL, NO, YES};
mod value;
pub use value::Value;
@ -73,9 +70,7 @@ impl UserDefaults {
/// let _ = defaults.get("test");
/// ```
pub fn standard() -> Self {
UserDefaults(unsafe {
Id::from_ptr(msg_send![class!(NSUserDefaults), standardUserDefaults])
})
UserDefaults(unsafe { Id::from_ptr(msg_send![class!(NSUserDefaults), standardUserDefaults]) })
}
/// Returns a user defaults instance for the given suite name. You typically use this to share
@ -177,9 +172,7 @@ impl UserDefaults {
pub fn get<K: AsRef<str>>(&self, key: K) -> Option<Value> {
let key = NSString::new(key.as_ref());
let result: id = unsafe {
msg_send![&*self.0, objectForKey:&*key]
};
let result: id = unsafe { msg_send![&*self.0, objectForKey:&*key] };
if result == nil {
return None;

View file

@ -1,6 +1,6 @@
use std::collections::HashMap;
use crate::foundation::{id, NSData, NSMutableDictionary, NSString, NSNumber};
use crate::foundation::{id, NSData, NSMutableDictionary, NSNumber, NSString};
/// Represents a Value that can be stored or queried with `UserDefaults`.
///

View file

@ -31,9 +31,7 @@ pub enum DragOperation {
Move,
/// The data can be deleted.
Delete,
// All of the above.
Delete // All of the above.
// @TODO: NSUIntegerMax, a tricky beast
// Every
}
@ -65,8 +63,6 @@ impl DragInfo {
///
/// Note: in general, you should not store pasteboards.
pub fn get_pasteboard(&self) -> Pasteboard {
unsafe {
Pasteboard::with(msg_send![&*self.info, draggingPasteboard])
}
unsafe { Pasteboard::with(msg_send![&*self.info, draggingPasteboard]) }
}
}

View file

@ -45,7 +45,9 @@ impl From<NSInteger> for ModalResponse {
// @TODO: Definitely don't panic here, wtf was I thinking?
// Probably make this a ModalResponse::Unknown or something so a user can
// gracefully handle.
e => { panic!("Unknown NSModalResponse sent back! {}", e); }
e => {
panic!("Unknown NSModalResponse sent back! {}", e);
}
}
}
}

View file

@ -4,14 +4,14 @@
use std::error::Error;
use std::sync::{Arc, RwLock};
use objc_id::Id;
use objc::runtime::{BOOL, Object};
use objc::runtime::{Object, BOOL};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use url::Url;
use crate::foundation::{id, nil, NO, NSString, NSUInteger};
use crate::error::Error as AppKitError;
use crate::filesystem::enums::{SearchPathDirectory, SearchPathDomainMask};
use crate::foundation::{id, nil, NSString, NSUInteger, NO};
/// A FileManager can be used for file operations (moving files, etc).
///
@ -45,11 +45,7 @@ impl FileManager {
/// Given a directory/domain combination, will attempt to get the directory that matches.
/// Returns a PathBuf that wraps the given location. If there's an error on the Objective-C
/// side, we attempt to catch it and bubble it up.
pub fn get_directory(
&self,
directory: SearchPathDirectory,
in_domain: SearchPathDomainMask
) -> Result<Url, Box<dyn Error>> {
pub fn get_directory(&self, directory: SearchPathDirectory, in_domain: SearchPathDomainMask) -> Result<Url, Box<dyn Error>> {
let dir: NSUInteger = directory.into();
let mask: NSUInteger = in_domain.into();

View file

@ -1,4 +1,3 @@
pub mod enums;
pub use enums::*;

View file

@ -4,11 +4,11 @@
use block::ConcreteBlock;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, YES, NO, NSInteger, NSString};
use crate::foundation::{id, nil, NSInteger, NSString, NO, YES};
#[derive(Debug)]
pub struct FileSavePanel {
@ -39,9 +39,7 @@ impl FileSavePanel {
ShareId::from_ptr(x)
},
delegate: unsafe {
ShareId::from_ptr(msg_send![class!(NSObject), new])
},
delegate: unsafe { ShareId::from_ptr(msg_send![class!(NSObject), new]) },
can_create_directories: true
}

View file

@ -6,12 +6,12 @@ use std::path::PathBuf;
use block::ConcreteBlock;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, YES, NO, NSInteger, NSString, NSURL};
use crate::filesystem::enums::ModalResponse;
use crate::foundation::{id, nil, NSInteger, NSString, NO, NSURL, YES};
#[cfg(feature = "appkit")]
use crate::appkit::window::{Window, WindowDelegate};
@ -58,9 +58,7 @@ impl FileSelectPanel {
ShareId::from_ptr(x)
},
delegate: unsafe {
ShareId::from_ptr(msg_send![class!(NSObject), new])
},
delegate: unsafe { ShareId::from_ptr(msg_send![class!(NSObject), new]) },
can_choose_files: true,
can_choose_directories: false,
@ -202,8 +200,8 @@ fn get_urls(panel: &Object) -> Vec<NSURL> {
let urls: id = msg_send![&*panel, URLs];
let count: usize = msg_send![urls, count];
(0..count).map(|index| {
NSURL::retain(msg_send![urls, objectAtIndex:index])
}).collect()
(0..count)
.map(|index| NSURL::retain(msg_send![urls, objectAtIndex: index]))
.collect()
}
}

View file

@ -16,12 +16,12 @@ pub trait OpenSaveController {
fn will_expand(&self, _expanding: bool) {}
/// Determine whether the specified URL should be enabled in the Open panel.
fn should_enable_url(&self, _url: &str) -> bool { true }
fn should_enable_url(&self, _url: &str) -> bool {
true
}
}
/// A trait you can implement for working with the underlying filesystem. This is important,
/// notably, because sandboxed applications have different working restrictions surrounding what
/// they can access.
pub trait FileManagerController {
}
pub trait FileManagerController {}

View file

@ -1,7 +1,7 @@
use std::ops::{Deref, DerefMut};
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::id;
@ -27,17 +27,13 @@ impl NSArray {
/// In some cases, we're vended an `NSArray` by the system that we need to call retain on.
/// This handles that case.
pub fn retain(array: id) -> Self {
NSArray(unsafe {
Id::from_ptr(array)
})
NSArray(unsafe { Id::from_ptr(array) })
}
/// In some cases, we're vended an `NSArray` by the system, and it's ideal to not retain that.
/// This handles that edge case.
pub fn from_retained(array: id) -> Self {
NSArray(unsafe {
Id::from_retained_ptr(array)
})
NSArray(unsafe { Id::from_retained_ptr(array) })
}
/// Returns the `count` (`len()` equivalent) for the backing `NSArray`.
@ -54,10 +50,12 @@ impl NSArray {
// I don't know if it's worth trying to get in with NSFastEnumeration here. I'm content to
// just rely on Rust, but someone is free to profile it if they want.
(0..count).map(|index| {
(0..count)
.map(|index| {
let item: id = unsafe { msg_send![objc, objectAtIndex: index] };
transform(item)
}).collect()
})
.collect()
}
}

View file

@ -1,5 +1,5 @@
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
/// A wrapper around `NSAutoReleasePool`. The core `App` structures create and manage one of these,
@ -14,9 +14,7 @@ impl AutoReleasePool {
/// Creates and returns a new `AutoReleasePool`. You need to take care to keep this alive for
/// as long as you need it.
pub fn new() -> Self {
AutoReleasePool(unsafe {
Id::from_retained_ptr(msg_send![class!(NSAutoreleasePool), new])
})
AutoReleasePool(unsafe { Id::from_retained_ptr(msg_send![class!(NSAutoreleasePool), new]) })
}
/// Drains the underlying AutoreleasePool.

View file

@ -48,11 +48,7 @@ impl ClassMap {
}
/// Attempts to load a previously registered subclass.
pub fn load_subclass(
&self,
subclass_name: &'static str,
superclass_name: &'static str
) -> Option<*const Class> {
pub fn load_subclass(&self, subclass_name: &'static str, superclass_name: &'static str) -> Option<*const Class> {
let reader = self.0.read().unwrap();
if let Some(inner) = (*reader).get(subclass_name) {
@ -65,12 +61,7 @@ impl ClassMap {
}
/// Store a newly created subclass type.
pub fn store_subclass(
&self,
subclass_name: &'static str,
superclass_name: &'static str,
class: *const Class,
) {
pub fn store_subclass(&self, subclass_name: &'static str, superclass_name: &'static str, class: *const Class) {
let mut writer = self.0.write().unwrap();
if let Some(map) = (*writer).get_mut(subclass_name) {
@ -96,9 +87,7 @@ impl ClassMap {
}
let objc_superclass_name = CString::new(name).unwrap();
let superclass = unsafe {
objc_getClass(objc_superclass_name.as_ptr() as *const _)
};
let superclass = unsafe { objc_getClass(objc_superclass_name.as_ptr() as *const _) };
// This should not happen, for our use-cases, but it's conceivable that this could actually
// be expected, so just return None and let the caller panic if so desired.
@ -131,11 +120,7 @@ impl ClassMap {
///
/// There's definitely room to optimize here, but it works for now.
#[inline(always)]
pub fn load_or_register_class<F>(
superclass_name: &'static str,
subclass_name: &'static str,
config: F
) -> *const Class
pub fn load_or_register_class<F>(superclass_name: &'static str, subclass_name: &'static str, config: F) -> *const Class
where
F: Fn(&mut ClassDecl) + 'static
{
@ -158,8 +143,7 @@ where
None => {
panic!(
"Subclass of type {}_{} could not be allocated.",
subclass_name,
superclass_name
subclass_name, superclass_name
);
}
}
@ -167,7 +151,6 @@ where
panic!(
"Attempted to create subclass for {}, but unable to load superclass of type {}.",
subclass_name,
superclass_name
subclass_name, superclass_name
);
}

View file

@ -5,11 +5,11 @@ use std::slice;
use block::{Block, ConcreteBlock};
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, to_bool, BOOL, YES, NO, NSUInteger};
use crate::foundation::{id, to_bool, NSUInteger, BOOL, NO, YES};
/// Wrapper for a retained `NSData` object.
///
@ -67,24 +67,18 @@ impl NSData {
/// Given a (presumably) `NSData`, wraps and retains it.
pub fn retain(data: id) -> Self {
NSData(unsafe {
Id::from_ptr(data)
})
NSData(unsafe { Id::from_ptr(data) })
}
/// If we're vended an NSData from a method (e.g, a push notification token) we might want to
/// wrap it while we figure out what to do with it. This does that.
pub fn from_retained(data: id) -> Self {
NSData(unsafe {
Id::from_retained_ptr(data)
})
NSData(unsafe { Id::from_retained_ptr(data) })
}
/// A helper method for determining if a given `NSObject` is an `NSData`.
pub fn is(obj: id) -> bool {
let result: BOOL = unsafe {
msg_send![obj, isKindOfClass:class!(NSData)]
};
let result: BOOL = unsafe { msg_send![obj, isKindOfClass: class!(NSData)] };
to_bool(result)
}
@ -112,9 +106,7 @@ impl NSData {
(ptr as *const u8, self.len())
};
unsafe {
slice::from_raw_parts(ptr, len)
}
unsafe { slice::from_raw_parts(ptr, len) }
}
/// Creates a new Vec, copies the NSData (safely, but quickly) bytes into that Vec, and

View file

@ -1,8 +1,8 @@
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, NSString};
@ -26,9 +26,7 @@ impl NSMutableDictionary {
/// object model. You can, of course, bypass it and `msg_send![]` yourself, but it'd require an
/// `unsafe {}` block... so you'll know you're in special territory then.
pub fn new() -> Self {
NSMutableDictionary(unsafe {
Id::from_ptr(msg_send![class!(NSMutableDictionary), new])
})
NSMutableDictionary(unsafe { Id::from_ptr(msg_send![class!(NSMutableDictionary), new]) })
}
/// Inserts an object into the backing NSMutablyDictionary.

View file

@ -44,7 +44,7 @@ pub use string::NSString;
// Separate named module to not conflict with the `url` crate. Go figure.
mod urls;
pub use urls::{NSURL, NSURLBookmarkCreationOption, NSURLBookmarkResolutionOption};
pub use urls::{NSURLBookmarkCreationOption, NSURLBookmarkResolutionOption, NSURL};
/// Bool mapping types differ between ARM and x64. There's a number of places that we need to check
/// against BOOL results throughout the framework, and this just simplifies some mismatches.
@ -56,7 +56,9 @@ pub fn to_bool(result: BOOL) -> bool {
//#[cfg(target_arch = "aarch64")]
#[cfg(not(target_arch = "aarch64"))]
_ => { std::unreachable!(); }
_ => {
std::unreachable!();
}
}
}

View file

@ -1,11 +1,11 @@
use std::ffi::CStr;
use std::os::raw::c_char;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, to_bool, BOOL, YES, NO, NSInteger};
use crate::foundation::{id, to_bool, NSInteger, BOOL, NO, YES};
/// Wrapper for a `NSNumber` object.
///
@ -18,17 +18,13 @@ impl NSNumber {
/// If we're vended an NSNumber from a method (e.g, `NSUserDefaults` querying) we might want to
/// wrap (and retain) it while we figure out what to do with it. This does that.
pub fn retain(data: id) -> Self {
NSNumber(unsafe {
Id::from_ptr(data)
})
NSNumber(unsafe { Id::from_ptr(data) })
}
/// If we're vended an NSNumber from a method (e.g, `NSUserDefaults` querying) we might want to
/// wrap it while we figure out what to do with it. This does that.
pub fn wrap(data: id) -> Self {
NSNumber(unsafe {
Id::from_retained_ptr(data)
})
NSNumber(unsafe { Id::from_retained_ptr(data) })
}
/// Constructs a `numberWithBool` instance of `NSNumber` and retains it.
@ -43,16 +39,12 @@ impl NSNumber {
/// Constructs a `numberWithInteger` instance of `NSNumber` and retains it.
pub fn integer(value: i64) -> Self {
NSNumber(unsafe {
Id::from_retained_ptr(msg_send![class!(NSNumber), numberWithInteger:value as NSInteger])
})
NSNumber(unsafe { Id::from_retained_ptr(msg_send![class!(NSNumber), numberWithInteger: value as NSInteger]) })
}
/// Constructs a `numberWithDouble` instance of `NSNumber` and retains it.
pub fn float(value: f64) -> Self {
NSNumber(unsafe {
Id::from_retained_ptr(msg_send![class!(NSNumber), numberWithDouble:value])
})
NSNumber(unsafe { Id::from_retained_ptr(msg_send![class!(NSNumber), numberWithDouble: value]) })
}
/// Returns the `objCType` of the underlying `NSNumber` as a Rust `&str`. This flag can be used
@ -84,9 +76,7 @@ impl NSNumber {
/// Note that this _does not check_ if the underlying type is actually this. You are
/// responsible for doing so via the `objc_type()` method.
pub fn as_f64(&self) -> f64 {
unsafe {
msg_send![&*self.0, doubleValue]
}
unsafe { msg_send![&*self.0, doubleValue] }
}
/// Pulls the underlying `BOOL` value out and passes it back as a `bool`.
@ -94,18 +84,14 @@ impl NSNumber {
/// Note that this _does not check_ if the underlying type is actually this. You are
/// responsible for doing so via the `objc_type()` method.
pub fn as_bool(&self) -> bool {
let result: BOOL = unsafe {
msg_send![&*self.0, boolValue]
};
let result: BOOL = unsafe { msg_send![&*self.0, boolValue] };
to_bool(result)
}
/// A helper method for determining if a given `NSObject` is an `NSNumber`.
pub fn is(obj: id) -> bool {
let result: BOOL = unsafe {
msg_send![obj, isKindOfClass:class!(NSNumber)]
};
let result: BOOL = unsafe { msg_send![obj, isKindOfClass: class!(NSNumber)] };
to_bool(result)
}

View file

@ -1,13 +1,13 @@
use std::{fmt, slice, str};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::os::raw::c_char;
use std::{fmt, slice, str};
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, to_bool, BOOL, YES, NO};
use crate::foundation::{id, to_bool, BOOL, NO, YES};
const UTF8_ENCODING: usize = 4;
@ -87,9 +87,7 @@ impl<'a> NSString<'a> {
/// Helper method for grabbing the proper byte length for this `NSString` (the UTF8 variant).
fn bytes_len(&self) -> usize {
unsafe {
msg_send![&*self.objc, lengthOfBytesUsingEncoding:UTF8_ENCODING]
}
unsafe { msg_send![&*self.objc, lengthOfBytesUsingEncoding: UTF8_ENCODING] }
}
/// A utility method for taking an `NSString` and bridging it to a Rust `&str`.

View file

@ -3,8 +3,8 @@ use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::path::PathBuf;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, NSData, NSString, NSUInteger};
@ -13,7 +13,7 @@ mod bookmark_options;
pub use bookmark_options::{NSURLBookmarkCreationOption, NSURLBookmarkResolutionOption};
mod resource_keys;
pub use resource_keys::{NSURLResourceKey, NSURLFileResource, NSUbiquitousItemDownloadingStatus};
pub use resource_keys::{NSURLFileResource, NSURLResourceKey, NSUbiquitousItemDownloadingStatus};
/// Wraps `NSURL` for use throughout the framework.
///
@ -58,9 +58,7 @@ impl<'a> NSURL<'a> {
let url = NSString::new(url);
Self {
objc: unsafe {
ShareId::from_ptr(msg_send![class!(NSURL), URLWithString:&*url])
},
objc: unsafe { ShareId::from_ptr(msg_send![class!(NSURL), URLWithString:&*url]) },
phantom: PhantomData
}
@ -71,9 +69,7 @@ impl<'a> NSURL<'a> {
/// Note that if the underlying file moved, this won't be accurate - you likely want to
/// research URL bookmarks.
pub fn absolute_string(&self) -> String {
let abs_str = NSString::retain(unsafe {
msg_send![&*self.objc, absoluteString]
});
let abs_str = NSString::retain(unsafe { msg_send![&*self.objc, absoluteString] });
abs_str.to_string()
}
@ -81,9 +77,7 @@ impl<'a> NSURL<'a> {
/// Creates and returns a Rust `PathBuf`, for users who don't need the extra pieces of NSURL
/// and just want to write Rust code.
pub fn pathbuf(&self) -> PathBuf {
let path = NSString::retain(unsafe {
msg_send![&*self.objc, path]
});
let path = NSString::retain(unsafe { msg_send![&*self.objc, path] });
path.to_str().into()
}

View file

@ -1,6 +1,6 @@
//! Wrapper methods for various geometry types (rects, sizes, ec).
use core_graphics::geometry::{CGRect, CGPoint, CGSize};
use core_graphics::geometry::{CGPoint, CGRect, CGSize};
/// A struct that represents a box - top, left, width and height. You might use this for, say,
/// setting the initial frame of a view.
@ -22,7 +22,12 @@ pub struct Rect {
impl Rect {
/// Returns a new `Rect` initialized with the values specified.
pub fn new(top: f64, left: f64, width: f64, height: f64) -> Self {
Rect { top: top, left: left, width: width, height: height }
Rect {
top: top,
left: left,
width: width,
height: height
}
}
/// Returns a zero'd out Rect, with f64 (32-bit is mostly dead on Cocoa, so... this is "okay").
@ -38,10 +43,7 @@ impl Rect {
impl From<Rect> for CGRect {
fn from(rect: Rect) -> CGRect {
CGRect::new(
&CGPoint::new(rect.left, rect.top),
&CGSize::new(rect.width, rect.height)
)
CGRect::new(&CGPoint::new(rect.left, rect.top), &CGSize::new(rect.width, rect.height))
}
}

View file

@ -14,10 +14,10 @@ use objc::runtime::{Class, Object, Sel, BOOL};
use objc::{class, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, YES, NO, NSUInteger};
use crate::dragdrop::DragInfo;
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
use crate::foundation::{id, NSUInteger, NO, YES};
use crate::utils::load;
use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
/// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we
/// have separate classes here since we don't want to waste cycles on methods that will never be

View file

@ -1,19 +1,19 @@
use objc_id::ShareId;
use objc::runtime::Object;
use objc_id::ShareId;
use objc::{class, msg_send, sel, sel_impl};
use block::ConcreteBlock;
use core_graphics::{
base::{CGFloat},
geometry::{CGRect, CGPoint, CGSize}
};
use core_graphics::context::{CGContext, CGContextRef};
use core_graphics::{
base::CGFloat,
geometry::{CGPoint, CGRect, CGSize}
};
use crate::foundation::{id, YES, NO, NSString, NSData};
use crate::utils::os;
use super::icons::*;
use crate::foundation::{id, NSData, NSString, NO, YES};
use crate::utils::os;
/// Specifies resizing behavior for image drawing.
#[derive(Copy, Clone, Debug)]
@ -32,7 +32,9 @@ pub enum ResizeBehavior {
}
fn max_cgfloat(x: CGFloat, y: CGFloat) -> CGFloat {
if x == y { return x; }
if x == y {
return x;
}
match x > y {
true => x,
@ -41,7 +43,9 @@ fn max_cgfloat(x: CGFloat, y: CGFloat) -> CGFloat {
}
fn min_cgfloat(x: CGFloat, y: CGFloat) -> CGFloat {
if x == y { return x; }
if x == y {
return x;
}
match x < y {
true => x,
@ -54,21 +58,15 @@ impl ResizeBehavior {
/// the resizing properties of this enum.
pub fn apply(&self, source: CGRect, target: CGRect) -> CGRect {
// if equal, just return source
if
source.origin.x == target.origin.x &&
source.origin.y == target.origin.y &&
source.size.width == target.size.width &&
source.size.height == target.size.height
if source.origin.x == target.origin.x
&& source.origin.y == target.origin.y
&& source.size.width == target.size.width
&& source.size.height == target.size.height
{
return source;
}
if
source.origin.x == 0. &&
source.origin.y == 0. &&
source.size.width == 0. &&
source.size.height == 0.
{
if source.origin.x == 0. && source.origin.y == 0. && source.size.width == 0. && source.size.height == 0. {
return source;
}
@ -126,9 +124,7 @@ pub struct Image(pub ShareId<Object>);
impl Image {
/// Wraps a system-returned image, e.g from QuickLook previews.
pub fn with(image: id) -> Self {
Image(unsafe {
ShareId::from_ptr(image)
})
Image(unsafe { ShareId::from_ptr(image) })
}
/// Loads an image from the specified path.
@ -221,15 +217,9 @@ impl Image {
where
F: Fn(CGRect, &CGContextRef) -> bool + 'static
{
let source_frame = CGRect::new(
&CGPoint::new(0., 0.),
&CGSize::new(config.source.0, config.source.1)
);
let source_frame = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(config.source.0, config.source.1));
let target_frame = CGRect::new(
&CGPoint::new(0., 0.),
&CGSize::new(config.target.0, config.target.1)
);
let target_frame = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(config.target.0, config.target.1));
let resized_frame = config.resize.apply(source_frame, target_frame);

View file

@ -1,15 +1,15 @@
use objc_id::ShareId;
use objc::runtime::{Class, Object};
use objc::{msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, YES, NO, NSArray, NSString};
use crate::color::Color;
use crate::foundation::{id, nil, NSArray, NSString, NO, YES};
use crate::layout::Layout;
use crate::objc_access::ObjcAccess;
use crate::utils::properties::ObjcProperty;
#[cfg(feature = "autolayout")]
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
#[cfg(feature = "appkit")]
mod appkit;
@ -24,7 +24,7 @@ use appkit::register_image_view_class;
//use uikit::register_image_view_class;
mod image;
pub use image::{Image, DrawConfig, ResizeBehavior};
pub use image::{DrawConfig, Image, ResizeBehavior};
mod icons;
pub use icons::*;
@ -135,7 +135,7 @@ impl ImageView {
#[cfg(feature = "autolayout")]
center_y: LayoutAnchorY::center(view),
objc: ObjcProperty::retain(view),
objc: ObjcProperty::retain(view)
}
}

View file

@ -6,7 +6,7 @@ use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::dragdrop::DragInfo;
use crate::foundation::{load_or_register_class, id, NSString, NSUInteger, NO, YES};
use crate::foundation::{id, load_or_register_class, NSString, NSUInteger, NO, YES};
use crate::input::{TextFieldDelegate, TEXTFIELD_DELEGATE_PTR};
use crate::utils::load;
@ -29,11 +29,7 @@ extern "C" fn text_did_change<T: TextFieldDelegate>(this: &mut Object, _: Sel, _
view.text_did_change(s.to_str());
}
extern "C" fn text_should_begin_editing<T: TextFieldDelegate>(
this: &mut Object,
_: Sel,
_info: id,
) -> BOOL {
extern "C" fn text_should_begin_editing<T: TextFieldDelegate>(this: &mut Object, _: Sel, _info: id) -> BOOL {
let view = load::<T>(this, TEXTFIELD_DELEGATE_PTR);
let s = NSString::retain(unsafe { msg_send![this, stringValue] });
@ -43,11 +39,7 @@ extern "C" fn text_should_begin_editing<T: TextFieldDelegate>(
}
}
extern "C" fn text_should_end_editing<T: TextFieldDelegate>(
this: &mut Object,
_: Sel,
_info: id,
) -> BOOL {
extern "C" fn text_should_end_editing<T: TextFieldDelegate>(this: &mut Object, _: Sel, _info: id) -> BOOL {
let view = load::<T>(this, TEXTFIELD_DELEGATE_PTR);
let s = NSString::retain(unsafe { msg_send![this, stringValue] });
match view.text_should_end_editing(s.to_str()) {
@ -82,23 +74,20 @@ pub(crate) fn register_view_class_with_delegate<T: TextFieldDelegate>(instance:
decl.add_method(
sel!(textDidEndEditing:),
text_did_end_editing::<T> as extern "C" fn(&mut Object, _, _),
text_did_end_editing::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(textDidBeginEditing:),
text_did_begin_editing::<T> as extern "C" fn(&mut Object, _, _),
);
decl.add_method(
sel!(textDidChange:),
text_did_change::<T> as extern "C" fn(&mut Object, _, _),
text_did_begin_editing::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(sel!(textDidChange:), text_did_change::<T> as extern "C" fn(&mut Object, _, _));
decl.add_method(
sel!(textShouldBeginEditing:),
text_should_begin_editing::<T> as extern "C" fn(&mut Object, Sel, id) -> BOOL,
text_should_begin_editing::<T> as extern "C" fn(&mut Object, Sel, id) -> BOOL
);
decl.add_method(
sel!(textShouldEndEditing:),
text_should_end_editing::<T> as extern "C" fn(&mut Object, Sel, id) -> BOOL,
text_should_end_editing::<T> as extern "C" fn(&mut Object, Sel, id) -> BOOL
);
})
}

View file

@ -135,7 +135,7 @@ pub struct TextField<T = ()> {
/// A pointer to the Objective-C runtime center Y layout constraint.
#[cfg(feature = "autolayout")]
pub center_y: LayoutAnchorY,
pub center_y: LayoutAnchorY
}
impl Default for TextField {
@ -189,7 +189,7 @@ impl TextField {
impl<T> TextField<T>
where
T: TextFieldDelegate + 'static,
T: TextFieldDelegate + 'static
{
/// Initializes a new TextField with a given `TextFieldDelegate`. This enables you to respond to events
/// and customize the view as a module, similar to class-based systems.
@ -235,7 +235,7 @@ where
center_x: LayoutAnchorX::center(label),
#[cfg(feature = "autolayout")]
center_y: LayoutAnchorY::center(label),
center_y: LayoutAnchorY::center(label)
};
(&mut delegate).did_load(label.clone_as_handle());
@ -282,15 +282,14 @@ impl<T> TextField<T> {
center_x: self.center_x.clone(),
#[cfg(feature = "autolayout")]
center_y: self.center_y.clone(),
center_y: self.center_y.clone()
}
}
/// Grabs the value from the textfield and returns it as an owned String.
pub fn get_value(&self) -> String {
self.objc.get(|obj| unsafe {
NSString::retain(msg_send![obj, stringValue]).to_string()
})
self.objc
.get(|obj| unsafe { NSString::retain(msg_send![obj, stringValue]).to_string() })
}
/// Call this to set the background color for the backing layer.

View file

@ -11,11 +11,11 @@
use std::fmt;
use std::sync::{Arc, Mutex, Once};
use objc_id::ShareId;
use block::{Block, ConcreteBlock, RcBlock};
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, msg_send, sel, sel_impl};
use block::{Block, ConcreteBlock, RcBlock};
use objc_id::ShareId;
use crate::foundation::{id, nil, NSString};
use crate::utils::load;
@ -34,8 +34,7 @@ pub struct Action(Box<dyn Fn() + Send + Sync + 'static>);
impl fmt::Debug for Action {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Action")
.finish()
f.debug_struct("Action").finish()
}
}
@ -78,7 +77,7 @@ impl TargetActionHandler {
}
/// This will fire for an NSButton callback.
extern fn perform<F: Fn() + 'static>(this: &mut Object, _: Sel, _sender: id) {
extern "C" fn perform<F: Fn() + 'static>(this: &mut Object, _: Sel, _sender: id) {
let action = load::<Action>(this, ACTION_CALLBACK_PTR);
(action.0)();
}
@ -104,7 +103,7 @@ pub(crate) fn register_invoker_class<F: Fn() + 'static>() -> *const Class {
let mut decl = ClassDecl::new("RSTTargetActionHandler", superclass).unwrap();
decl.add_ivar::<usize>(ACTION_CALLBACK_PTR);
decl.add_method(sel!(perform:), perform::<F> as extern fn (&mut Object, _, id));
decl.add_method(sel!(perform:), perform::<F> as extern "C" fn(&mut Object, _, id));
VIEW_CLASS = decl.register();
});

View file

@ -38,9 +38,7 @@ impl Layer {
/// Creates a new `CALayer` and retains it.
pub fn new() -> Self {
Layer {
objc: ObjcProperty::retain(unsafe {
msg_send![class!(CALayer), new]
})
objc: ObjcProperty::retain(unsafe { msg_send![class!(CALayer), new] })
}
}

View file

@ -1,7 +1,7 @@
use core_graphics::base::CGFloat;
use objc::{msg_send, sel, sel_impl};
use objc::runtime::{Class, Object};
use objc::{msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::id;
@ -13,9 +13,7 @@ pub struct LayoutConstraintAnimatorProxy(pub ShareId<Object>);
impl LayoutConstraintAnimatorProxy {
/// Wraps and returns a proxy for animation of layout constraint values.
pub fn new(proxy: id) -> Self {
Self(unsafe {
ShareId::from_ptr(msg_send![proxy, animator])
})
Self(unsafe { ShareId::from_ptr(msg_send![proxy, animator]) })
}
/// Sets the constant (usually referred to as `offset` in Cacao) value for the constraint being animated.

View file

@ -4,11 +4,11 @@
use core_graphics::base::CGFloat;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, YES, NO};
use crate::foundation::{id, NO, YES};
use super::LayoutConstraintAnimatorProxy;
@ -42,7 +42,7 @@ impl LayoutConstraint {
constraint: unsafe { ShareId::from_ptr(object) },
offset: 0.0,
multiplier: 0.0,
priority: 0.0,
priority: 0.0
}
}
@ -54,7 +54,6 @@ impl LayoutConstraint {
let _: () = msg_send![&*self.constraint, setConstant: o];
}
LayoutConstraint {
animator: self.animator,
constraint: self.constraint,
@ -96,9 +95,7 @@ impl LayoutConstraint {
// I regret nothing, lol. If you have a better solution I'm all ears.
pub fn activate(constraints: &[LayoutConstraint]) {
unsafe {
let ids: Vec<&Object> = constraints.into_iter().map(|constraint| {
&*constraint.constraint
}).collect();
let ids: Vec<&Object> = constraints.into_iter().map(|constraint| &*constraint.constraint).collect();
let constraints: id = msg_send![class!(NSArray), arrayWithObjects:ids.as_ptr() count:ids.len()];
let _: () = msg_send![class!(NSLayoutConstraint), activateConstraints: constraints];
@ -107,9 +104,7 @@ impl LayoutConstraint {
pub fn deactivate(constraints: &[LayoutConstraint]) {
unsafe {
let ids: Vec<&Object> = constraints.into_iter().map(|constraint| {
&*constraint.constraint
}).collect();
let ids: Vec<&Object> = constraints.into_iter().map(|constraint| &*constraint.constraint).collect();
let constraints: id = msg_send![class!(NSArray), arrayWithObjects:ids.as_ptr() count:ids.len()];
let _: () = msg_send![class!(NSLayoutConstraint), deactivateConstraints: constraints];

View file

@ -1,7 +1,7 @@
use core_graphics::base::CGFloat;
use objc::{class, msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, NSInteger};
@ -38,16 +38,12 @@ impl Default for LayoutAnchorDimension {
impl LayoutAnchorDimension {
/// Given a view, returns an anchor for the width anchor.
pub(crate) fn width(view: id) -> Self {
Self::Width(unsafe {
ShareId::from_ptr(msg_send![view, widthAnchor])
})
Self::Width(unsafe { ShareId::from_ptr(msg_send![view, widthAnchor]) })
}
/// Given a view, returns an anchor for the height anchor.
pub(crate) fn height(view: id) -> Self {
Self::Height(unsafe {
ShareId::from_ptr(msg_send![view, heightAnchor])
})
Self::Height(unsafe { ShareId::from_ptr(msg_send![view, heightAnchor]) })
}
/// Return a constraint equal to a constant value.
@ -94,12 +90,10 @@ impl LayoutAnchorDimension {
F: Fn(&ShareId<Object>, &ShareId<Object>) -> id
{
match (self, anchor_to) {
(Self::Width(from), Self::Width(to)) |
(Self::Width(from), Self::Height(to)) |
(Self::Height(from), Self::Width(to)) |
(Self::Height(from), Self::Height(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Width(from), Self::Width(to))
| (Self::Width(from), Self::Height(to))
| (Self::Height(from), Self::Width(to))
| (Self::Height(from), Self::Height(to)) => LayoutConstraint::new(handler(from, to)),
(Self::Uninitialized, Self::Uninitialized) => {
panic!("Attempted to create constraints with an uninitialized \"from\" and \"to\" dimension anchor.");
@ -109,7 +103,6 @@ impl LayoutAnchorDimension {
panic!("Attempted to create constraints with an uninitialized \"from\" dimension anchor.");
},
(_, Self::Uninitialized) => {
panic!("Attempted to create constraints with an uninitialized \"to\" dimension anchor.");
}

View file

@ -1,5 +1,5 @@
use objc::{msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::id;
@ -41,37 +41,27 @@ impl Default for LayoutAnchorX {
impl LayoutAnchorX {
/// Given a view, returns an anchor for the leading anchor.
pub(crate) fn leading(view: id) -> Self {
Self::Leading(unsafe {
ShareId::from_ptr(msg_send![view, leadingAnchor])
})
Self::Leading(unsafe { ShareId::from_ptr(msg_send![view, leadingAnchor]) })
}
/// Given a view, returns an anchor for the left anchor.
pub(crate) fn left(view: id) -> Self {
Self::Left(unsafe {
ShareId::from_ptr(msg_send![view, leftAnchor])
})
Self::Left(unsafe { ShareId::from_ptr(msg_send![view, leftAnchor]) })
}
/// Given a view, returns an anchor for the trailing anchor.
pub(crate) fn trailing(view: id) -> Self {
Self::Trailing(unsafe {
ShareId::from_ptr(msg_send![view, trailingAnchor])
})
Self::Trailing(unsafe { ShareId::from_ptr(msg_send![view, trailingAnchor]) })
}
/// Given a view, returns an anchor for the right anchor.
pub(crate) fn right(view: id) -> Self {
Self::Right(unsafe {
ShareId::from_ptr(msg_send![view, rightAnchor])
})
Self::Right(unsafe { ShareId::from_ptr(msg_send![view, rightAnchor]) })
}
/// Given a view, returns an anchor for the right anchor.
pub(crate) fn center(view: id) -> Self {
Self::Center(unsafe {
ShareId::from_ptr(msg_send![view, centerXAnchor])
})
Self::Center(unsafe { ShareId::from_ptr(msg_send![view, centerXAnchor]) })
}
/// Boilerplate for handling constraint construction and panic'ing with some more helpful
@ -84,68 +74,72 @@ impl LayoutAnchorX {
match (self, anchor_to) {
// The anchors that can connect to each other. These blocks could be condensed, but are
// kept separate for readability reasons.
(Self::Leading(from), Self::Leading(to)) | (Self::Leading(from), Self::Trailing(to)) |
(Self::Leading(from), Self::Center(to)) => {
(Self::Leading(from), Self::Leading(to))
| (Self::Leading(from), Self::Trailing(to))
| (Self::Leading(from), Self::Center(to)) => LayoutConstraint::new(handler(from, to)),
(Self::Trailing(from), Self::Trailing(to))
| (Self::Trailing(from), Self::Leading(to))
| (Self::Trailing(from), Self::Center(to)) => LayoutConstraint::new(handler(from, to)),
(Self::Left(from), Self::Left(to)) | (Self::Left(from), Self::Right(to)) | (Self::Left(from), Self::Center(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Trailing(from), Self::Trailing(to)) | (Self::Trailing(from), Self::Leading(to)) |
(Self::Trailing(from), Self::Center(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Right(from), Self::Right(to))
| (Self::Right(from), Self::Left(to))
| (Self::Right(from), Self::Center(to)) => LayoutConstraint::new(handler(from, to)),
(Self::Left(from), Self::Left(to)) | (Self::Left(from), Self::Right(to)) |
(Self::Left(from), Self::Center(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Right(from), Self::Right(to)) | (Self::Right(from), Self::Left(to)) |
(Self::Right(from), Self::Center(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Center(from), Self::Center(to)) | (Self::Center(from), Self::Leading(to)) |
(Self::Center(from), Self::Trailing(to)) | (Self::Center(from), Self::Left(to)) |
(Self::Center(from), Self::Right(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Center(from), Self::Center(to))
| (Self::Center(from), Self::Leading(to))
| (Self::Center(from), Self::Trailing(to))
| (Self::Center(from), Self::Left(to))
| (Self::Center(from), Self::Right(to)) => LayoutConstraint::new(handler(from, to)),
// These anchors explicitly cannot be attached to each other, as it results in
// undefined/unexpected layout behavior when a system has differing ltr/rtl setups.
(Self::Leading(_), Self::Left(_)) | (Self::Left(_), Self::Leading(_)) => {
panic!(r#"
panic!(
r#"
Attempted to attach a "leading" constraint to a "left" constraint. This will
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
Use either left/right or leading/trailing.
"#);
"#
);
},
(Self::Leading(_), Self::Right(_)) | (Self::Right(_), Self::Leading(_)) => {
panic!(r#"
panic!(
r#"
Attempted to attach a "leading" constraint to a "right" constraint. This will
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
Use either left/right or leading/trailing.
"#);
"#
);
},
(Self::Trailing(_), Self::Left(_)) | (Self::Left(_), Self::Trailing(_)) => {
panic!(r#"
panic!(
r#"
Attempted to attach a "trailing" constraint to a "left" constraint. This will
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
Use either left/right or leading/trailing.
"#);
"#
);
},
(Self::Trailing(_), Self::Right(_)) | (Self::Right(_), Self::Trailing(_)) => {
panic!(r#"
panic!(
r#"
Attempted to attach a "trailing" constraint to a "right" constraint. This will
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
Use either left/right or leading/trailing.
"#);
"#
);
},
// If anything is attempted with an uninitialized anchor, then block it.

View file

@ -1,7 +1,7 @@
use objc::{msg_send, sel, sel_impl};
use crate::foundation::id;
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
use crate::utils::os;
/// A SafeAreaLayoutGuide should exist on all view types, and ensures that there are anchor points

View file

@ -2,13 +2,13 @@
//! heirarchies.
use core_graphics::base::CGFloat;
use core_graphics::geometry::{CGRect, CGPoint, CGSize};
use core_graphics::geometry::{CGPoint, CGRect, CGSize};
use objc::{msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, to_bool, YES, NO, NSArray, NSString};
use crate::foundation::{id, nil, to_bool, NSArray, NSString, NO, YES};
use crate::geometry::Rect;
use crate::objc_access::ObjcAccess;
@ -93,21 +93,13 @@ pub trait Layout: ObjcAccess {
/// Note that this can report `false` if an ancestor widget is hidden, thus hiding this - to check in
/// that case, you may want `is_hidden_or_ancestor_is_hidden()`.
fn is_hidden(&self) -> bool {
self.get_from_backing_obj(|obj| {
to_bool(unsafe {
msg_send![obj, isHidden]
})
})
self.get_from_backing_obj(|obj| to_bool(unsafe { msg_send![obj, isHidden] }))
}
/// Returns whether this is hidden, *or* whether an ancestor view is hidden.
#[cfg(feature = "appkit")]
fn is_hidden_or_ancestor_is_hidden(&self) -> bool {
self.get_from_backing_obj(|obj| {
to_bool(unsafe {
msg_send![obj, isHiddenOrHasHiddenAncestor]
})
})
self.get_from_backing_obj(|obj| to_bool(unsafe { msg_send![obj, isHiddenOrHasHiddenAncestor] }))
}
/// Register this view for drag and drop operations.
@ -116,10 +108,14 @@ pub trait Layout: ObjcAccess {
/// currently to avoid compile issues.
#[cfg(feature = "appkit")]
fn register_for_dragged_types(&self, types: &[PasteboardType]) {
let types: NSArray = types.into_iter().map(|t| {
let types: NSArray = types
.into_iter()
.map(|t| {
let x: NSString = (*t).into();
x.into()
}).collect::<Vec<id>>().into();
})
.collect::<Vec<id>>()
.into();
self.with_backing_obj_mut(|obj| unsafe {
let _: () = msg_send![obj, registerForDraggedTypes:&*types];

View file

@ -1,5 +1,5 @@
use objc::{msg_send, sel, sel_impl};
use objc::runtime::Object;
use objc::{msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::id;
@ -31,23 +31,17 @@ impl Default for LayoutAnchorY {
impl LayoutAnchorY {
/// Given a view, returns an anchor for the top anchor.
pub(crate) fn top(view: id) -> Self {
Self::Top(unsafe {
ShareId::from_ptr(msg_send![view, topAnchor])
})
Self::Top(unsafe { ShareId::from_ptr(msg_send![view, topAnchor]) })
}
/// Given a view, returns an anchor for the bottom anchor.
pub(crate) fn bottom(view: id) -> Self {
Self::Bottom(unsafe {
ShareId::from_ptr(msg_send![view, bottomAnchor])
})
Self::Bottom(unsafe { ShareId::from_ptr(msg_send![view, bottomAnchor]) })
}
/// Given a view, returns an anchor for the center Y anchor.
pub(crate) fn center(view: id) -> Self {
Self::Center(unsafe {
ShareId::from_ptr(msg_send![view, centerYAnchor])
})
Self::Center(unsafe { ShareId::from_ptr(msg_send![view, centerYAnchor]) })
}
/// Boilerplate for handling constraint construction and panic'ing with some more helpful
@ -58,16 +52,15 @@ impl LayoutAnchorY {
F: Fn(&ShareId<Object>, &ShareId<Object>) -> id
{
match (self, anchor_to) {
(Self::Top(from), Self::Top(to)) | (Self::Top(from), Self::Bottom(to)) |
(Self::Top(from), Self::Center(to)) |
(Self::Bottom(from), Self::Bottom(to)) | (Self::Bottom(from), Self::Top(to)) |
(Self::Bottom(from), Self::Center(to)) |
(Self::Center(from), Self::Center(to)) | (Self::Center(from), Self::Top(to)) |
(Self::Center(from), Self::Bottom(to)) => {
LayoutConstraint::new(handler(from, to))
},
(Self::Top(from), Self::Top(to))
| (Self::Top(from), Self::Bottom(to))
| (Self::Top(from), Self::Center(to))
| (Self::Bottom(from), Self::Bottom(to))
| (Self::Bottom(from), Self::Top(to))
| (Self::Bottom(from), Self::Center(to))
| (Self::Center(from), Self::Center(to))
| (Self::Center(from), Self::Top(to))
| (Self::Center(from), Self::Bottom(to)) => LayoutConstraint::new(handler(from, to)),
(Self::Uninitialized, Self::Uninitialized) => {
panic!("Attempted to create constraints with uninitialized \"from\" and \"to\" y anchors.");

View file

@ -3,7 +3,6 @@
#![cfg_attr(debug_assertions, allow(dead_code, unused_imports))]
#![cfg_attr(docsrs, deny(rustdoc::broken_intra_doc_links))]
#![cfg_attr(docsrs, feature(doc_cfg))]
// Copyright 2019+, the Cacao developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Dual-licensed under an MIT/MPL-2.0 license, see the LICENSE files in this repository.
@ -93,9 +92,9 @@
pub use core_foundation;
pub use core_graphics;
pub use lazy_static;
pub use objc;
pub use url;
pub use lazy_static;
//#[cfg(all(feature = "appkit", feature = "uikit", not(feature = "doc_cfg")))]
//compile_error!("The \"appkit\" and \"uikit\" features cannot be enabled together. Pick one. :)");
@ -153,8 +152,8 @@ pub mod layout;
#[cfg(feature = "appkit")]
pub mod listview;
pub mod networking;
pub(crate) mod objc_access;
pub mod notification_center;
pub(crate) mod objc_access;
#[cfg(feature = "appkit")]
pub mod pasteboard;

View file

@ -1,6 +1,6 @@
use objc_id::Id;
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use block::ConcreteBlock;
@ -56,9 +56,7 @@ impl RowAction {
{
let title = NSString::new(title);
let block = ConcreteBlock::new(move |action: id, row: NSUInteger| {
let action = RowAction(unsafe {
Id::from_ptr(action)
});
let action = RowAction(unsafe { Id::from_ptr(action) });
handler(action, row as usize);
});

View file

@ -11,29 +11,22 @@ use std::sync::Once;
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel, BOOL};
use objc::{class, sel, sel_impl, msg_send};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::appkit::menu::{Menu, MenuItem};
use crate::foundation::{load_or_register_class, id, nil, YES, NO, NSArray, NSInteger, NSUInteger};
use crate::dragdrop::DragInfo;
use crate::listview::{
LISTVIEW_DELEGATE_PTR,
ListViewDelegate, RowEdge
};
use crate::foundation::{id, load_or_register_class, nil, NSArray, NSInteger, NSUInteger, NO, YES};
use crate::listview::{ListViewDelegate, RowEdge, LISTVIEW_DELEGATE_PTR};
use crate::utils::load;
/// Determines the number of items by way of the backing data source (the Rust struct).
extern fn number_of_items<T: ListViewDelegate>(
this: &Object,
_: Sel,
_: id
) -> NSInteger {
extern "C" fn number_of_items<T: ListViewDelegate>(this: &Object, _: Sel, _: id) -> NSInteger {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
view.number_of_items() as NSInteger
}
extern fn view_for_column<T: ListViewDelegate>(
extern "C" fn view_for_column<T: ListViewDelegate>(
this: &Object,
_: Sel,
_table_view: id,
@ -59,12 +52,10 @@ extern fn view_for_column<T: ListViewDelegate>(
//
// @TODO: Finish investing the `Rc` approach, might be able to just take
// ownership and rely on Rust being correct.
item.objc.get(|obj| unsafe {
msg_send![obj, self]
})
item.objc.get(|obj| unsafe { msg_send![obj, self] })
}
extern fn will_display_cell<T: ListViewDelegate>(
extern "C" fn will_display_cell<T: ListViewDelegate>(
this: &Object,
_: Sel,
_table_view: id,
@ -76,11 +67,7 @@ extern fn will_display_cell<T: ListViewDelegate>(
view.will_display_item(item as usize);
}
extern fn menu_needs_update<T: ListViewDelegate>(
this: &Object,
_: Sel,
menu: id
) {
extern "C" fn menu_needs_update<T: ListViewDelegate>(this: &Object, _: Sel, menu: id) {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
let items = view.context_menu();
let _ = Menu::append(menu, items);
@ -103,11 +90,7 @@ extern fn select_row<T: ListViewDelegate>(
YES
}*/
extern fn selection_did_change<T: ListViewDelegate>(
this: &Object,
_: Sel,
notification: id
) {
extern "C" fn selection_did_change<T: ListViewDelegate>(this: &Object, _: Sel, notification: id) {
let selected_row: NSInteger = unsafe {
let tableview: id = msg_send![notification, object];
msg_send![tableview, selectedRow]
@ -121,7 +104,7 @@ extern fn selection_did_change<T: ListViewDelegate>(
}
}
extern fn row_actions_for_row<T: ListViewDelegate>(
extern "C" fn row_actions_for_row<T: ListViewDelegate>(
this: &Object,
_: Sel,
_table_view: id,
@ -131,7 +114,8 @@ extern fn row_actions_for_row<T: ListViewDelegate>(
let edge: RowEdge = edge.into();
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
let mut ids: NSArray = view.actions_for(row as usize, edge)
let mut ids: NSArray = view
.actions_for(row as usize, edge)
.iter_mut()
.map(|action| &*action.0)
.collect::<Vec<&Object>>()
@ -141,20 +125,21 @@ extern fn row_actions_for_row<T: ListViewDelegate>(
}
/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though.
extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
extern "C" fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
return YES;
}
/// Called when a drag/drop operation has entered this view.
extern fn dragging_entered<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
extern "C" fn dragging_entered<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
view.dragging_entered(DragInfo {
info: unsafe { Id::from_ptr(info) }
}).into()
})
.into()
}
/// Called when a drag/drop operation has entered this view.
extern fn prepare_for_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
extern "C" fn prepare_for_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
match view.prepare_for_drag_operation(DragInfo {
@ -166,7 +151,7 @@ extern fn prepare_for_drag_operation<T: ListViewDelegate>(this: &mut Object, _:
}
/// Called when a drag/drop operation has entered this view.
extern fn perform_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
extern "C" fn perform_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
match view.perform_drag_operation(DragInfo {
@ -178,7 +163,7 @@ extern fn perform_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel,
}
/// Called when a drag/drop operation has entered this view.
extern fn conclude_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) {
extern "C" fn conclude_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
view.conclude_drag_operation(DragInfo {
@ -187,7 +172,7 @@ extern fn conclude_drag_operation<T: ListViewDelegate>(this: &mut Object, _: Sel
}
/// Called when a drag/drop operation has entered this view.
extern fn dragging_exited<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) {
extern "C" fn dragging_exited<T: ListViewDelegate>(this: &mut Object, _: Sel, info: id) {
let view = load::<T>(this, LISTVIEW_DELEGATE_PTR);
view.dragging_exited(DragInfo {
@ -209,9 +194,7 @@ pub(crate) fn register_listview_class() -> *const Class {
VIEW_CLASS = decl.register();
});
unsafe {
VIEW_CLASS
}
unsafe { VIEW_CLASS }
}
/// Injects an `NSTableView` subclass, with some callback and pointer ivars for what we
@ -222,25 +205,58 @@ pub(crate) fn register_listview_class_with_delegate<T: ListViewDelegate>(instanc
load_or_register_class("NSTableView", instance.subclass_name(), |decl| unsafe {
decl.add_ivar::<usize>(LISTVIEW_DELEGATE_PTR);
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
// Tableview-specific
decl.add_method(sel!(numberOfRowsInTableView:), number_of_items::<T> as extern fn(&Object, _, id) -> NSInteger);
decl.add_method(sel!(tableView:willDisplayCell:forTableColumn:row:), will_display_cell::<T> as extern fn(&Object, _, id, id, id, NSInteger));
decl.add_method(sel!(tableView:viewForTableColumn:row:), view_for_column::<T> as extern fn(&Object, _, id, id, NSInteger) -> id);
decl.add_method(sel!(tableViewSelectionDidChange:), selection_did_change::<T> as extern fn(&Object, _, id));
decl.add_method(sel!(tableView:rowActionsForRow:edge:), row_actions_for_row::<T> as extern fn(&Object, _, id, NSInteger, NSInteger) -> id);
decl.add_method(
sel!(numberOfRowsInTableView:),
number_of_items::<T> as extern "C" fn(&Object, _, id) -> NSInteger
);
decl.add_method(
sel!(tableView:willDisplayCell:forTableColumn:row:),
will_display_cell::<T> as extern "C" fn(&Object, _, id, id, id, NSInteger)
);
decl.add_method(
sel!(tableView:viewForTableColumn:row:),
view_for_column::<T> as extern "C" fn(&Object, _, id, id, NSInteger) -> id
);
decl.add_method(
sel!(tableViewSelectionDidChange:),
selection_did_change::<T> as extern "C" fn(&Object, _, id)
);
decl.add_method(
sel!(tableView:rowActionsForRow:edge:),
row_actions_for_row::<T> as extern "C" fn(&Object, _, id, NSInteger, NSInteger) -> id
);
// A slot for some menu handling; we just let it be done here for now rather than do the
// whole delegate run, since things are fast enough nowadays to just replace the entire
// menu.
decl.add_method(sel!(menuNeedsUpdate:), menu_needs_update::<T> as extern fn(&Object, _, id));
decl.add_method(
sel!(menuNeedsUpdate:),
menu_needs_update::<T> as extern "C" fn(&Object, _, id)
);
// Drag and drop operations (e.g, accepting files)
decl.add_method(sel!(draggingEntered:), dragging_entered::<T> as extern fn (&mut Object, _, _) -> NSUInteger);
decl.add_method(sel!(prepareForDragOperation:), prepare_for_drag_operation::<T> as extern fn (&mut Object, _, _) -> BOOL);
decl.add_method(sel!(performDragOperation:), perform_drag_operation::<T> as extern fn (&mut Object, _, _) -> BOOL);
decl.add_method(sel!(concludeDragOperation:), conclude_drag_operation::<T> as extern fn (&mut Object, _, _));
decl.add_method(sel!(draggingExited:), dragging_exited::<T> as extern fn (&mut Object, _, _));
decl.add_method(
sel!(draggingEntered:),
dragging_entered::<T> as extern "C" fn(&mut Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(performDragOperation:),
perform_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(concludeDragOperation:),
conclude_drag_operation::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(draggingExited:),
dragging_exited::<T> as extern "C" fn(&mut Object, _, _)
);
})
}

View file

@ -63,7 +63,9 @@ impl Into<RowEdge> for NSInteger {
// @TODO: This *should* be unreachable, provided macOS doesn't start
// letting people swipe from vertical directions to reveal stuff. Have to
// feel like there's a better way to do this, though...
_ => { unreachable!(); }
_ => {
unreachable!();
}
}
}
}

View file

@ -44,21 +44,21 @@
use std::collections::HashMap;
use core_graphics::base::CGFloat;
use objc_id::ShareId;
use objc::runtime::{Class, Object};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::ShareId;
use crate::foundation::{id, nil, YES, NO, NSArray, NSString, NSInteger, NSUInteger};
use crate::color::Color;
use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger, NO, YES};
use crate::layout::Layout;
#[cfg(feature = "autolayout")]
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
use crate::objc_access::ObjcAccess;
use crate::scrollview::ScrollView;
use crate::utils::{os, CellFactory, CGSize};
use crate::utils::properties::{ObjcProperty, PropertyNullable};
use crate::utils::{os, CGSize, CellFactory};
use crate::view::{ViewAnimatorProxy, ViewDelegate};
#[cfg(feature = "appkit")]
@ -93,8 +93,8 @@ pub(crate) static LISTVIEW_DELEGATE_PTR: &str = "rstListViewDelegatePtr";
use std::any::Any;
use std::sync::{Arc, RwLock};
use std::rc::Rc;
use std::cell::RefCell;
use std::rc::Rc;
/// A helper method for instantiating view classes and applying default settings to them.
fn common_init(class: *const Class) -> id {
@ -222,9 +222,7 @@ impl ListView {
// For AppKit, we need to use the NSScrollView anchor points, not the NSTableView.
// @TODO: Fix this with proper mutable access.
#[cfg(all(feature = "appkit", feature = "autolayout"))]
let anchor_view: id = scrollview.objc.get(|obj| unsafe {
msg_send![obj, self]
});
let anchor_view: id = scrollview.objc.get(|obj| unsafe { msg_send![obj, self] });
//#[cfg(all(feature = "uikit", feature = "autolayout"))]
//let anchor_view: id = view;
@ -276,7 +274,10 @@ impl ListView {
}
}
impl<T> ListView<T> where T: ListViewDelegate + 'static {
impl<T> ListView<T>
where
T: ListViewDelegate + 'static
{
/// Initializes a new View with a given `ViewDelegate`. This enables you to respond to events
/// and customize the view as a module, similar to class-based systems.
pub fn with(delegate: T) -> ListView<T> {
@ -305,9 +306,7 @@ impl<T> ListView<T> where T: ListViewDelegate + 'static {
// For AppKit, we need to use the NSScrollView anchor points, not the NSTableView.
#[cfg(all(feature = "appkit", feature = "autolayout"))]
let anchor_view: id = scrollview.objc.get(|obj| unsafe {
msg_send![obj, self]
});
let anchor_view: id = scrollview.objc.get(|obj| unsafe { msg_send![obj, self] });
//#[cfg(feature = "uikit")]
//let anchor_view = view;
@ -420,9 +419,9 @@ impl<T> ListView<T> {
#[cfg(feature = "appkit")]
{
let key = NSString::new(identifier);
let cell: id = self.objc.get(|obj| unsafe {
msg_send![obj, makeViewWithIdentifier:&*key owner:nil]
});
let cell: id = self
.objc
.get(|obj| unsafe { msg_send![obj, makeViewWithIdentifier:&*key owner:nil] });
if cell != nil {
ListViewRow::from_cached(cell)

View file

@ -14,26 +14,27 @@ use objc::runtime::{Class, Object, Sel, BOOL};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
use crate::foundation::{id, nil, YES, NO, NSUInteger};
use crate::dragdrop::DragInfo;
use crate::listview::row::{LISTVIEW_ROW_DELEGATE_PTR, BACKGROUND_COLOR, ViewDelegate};
use crate::foundation::{id, nil, NSUInteger, NO, YES};
use crate::listview::row::{ViewDelegate, BACKGROUND_COLOR, LISTVIEW_ROW_DELEGATE_PTR};
use crate::utils::load;
/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though.
extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
extern "C" fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
return YES;
}
/// Called when a drag/drop operation has entered this view.
extern fn dragging_entered<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
extern "C" fn dragging_entered<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
let view = load::<T>(this, LISTVIEW_ROW_DELEGATE_PTR);
view.dragging_entered(DragInfo {
info: unsafe { Id::from_ptr(info) }
}).into()
})
.into()
}
/// Called when a drag/drop operation has entered this view.
extern fn prepare_for_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
extern "C" fn prepare_for_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
let view = load::<T>(this, LISTVIEW_ROW_DELEGATE_PTR);
match view.prepare_for_drag_operation(DragInfo {
@ -45,7 +46,7 @@ extern fn prepare_for_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel,
}
/// Called when a drag/drop operation has entered this view.
extern fn perform_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
extern "C" fn perform_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> BOOL {
let view = load::<T>(this, LISTVIEW_ROW_DELEGATE_PTR);
match view.perform_drag_operation(DragInfo {
@ -57,7 +58,7 @@ extern fn perform_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, inf
}
/// Called when a drag/drop operation has entered this view.
extern fn conclude_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) {
extern "C" fn conclude_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) {
let view = load::<T>(this, LISTVIEW_ROW_DELEGATE_PTR);
view.conclude_drag_operation(DragInfo {
@ -66,7 +67,7 @@ extern fn conclude_drag_operation<T: ViewDelegate>(this: &mut Object, _: Sel, in
}
/// Called when a drag/drop operation has entered this view.
extern fn dragging_exited<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) {
extern "C" fn dragging_exited<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) {
let view = load::<T>(this, LISTVIEW_ROW_DELEGATE_PTR);
view.dragging_exited(DragInfo {
@ -75,7 +76,7 @@ extern fn dragging_exited<T: ViewDelegate>(this: &mut Object, _: Sel, info: id)
}
/// Called for layer updates.
extern fn update_layer(this: &Object, _: Sel) {
extern "C" fn update_layer(this: &Object, _: Sel) {
unsafe {
let background_color: id = *this.get_ivar(BACKGROUND_COLOR);
@ -91,7 +92,7 @@ extern fn update_layer(this: &Object, _: Sel) {
/// tricky - since we "forget" them when we give them to the system, we need to make sure to do
/// proper cleanup then the backing (cached) version is deallocated on the Objective-C side. Since
/// we know
extern fn dealloc<T: ViewDelegate>(this: &Object, _: Sel) {
extern "C" fn dealloc<T: ViewDelegate>(this: &Object, _: Sel) {
// Load the Box pointer here, and just let it drop normally.
unsafe {
let ptr: usize = *(&*this).get_ivar(LISTVIEW_ROW_DELEGATE_PTR);
@ -113,7 +114,7 @@ pub(crate) fn register_listview_row_class() -> *const Class {
let superclass = class!(NSView);
let mut decl = ClassDecl::new("RSTTableViewRow", superclass).unwrap();
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
VIEW_CLASS = decl.register();
});
@ -136,23 +137,36 @@ pub(crate) fn register_listview_row_class_with_delegate<T: ViewDelegate>() -> *c
decl.add_ivar::<usize>(LISTVIEW_ROW_DELEGATE_PTR);
decl.add_ivar::<id>(BACKGROUND_COLOR);
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
decl.add_method(sel!(updateLayer), update_layer as extern fn(&Object, _));
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
decl.add_method(sel!(updateLayer), update_layer as extern "C" fn(&Object, _));
// Drag and drop operations (e.g, accepting files)
decl.add_method(sel!(draggingEntered:), dragging_entered::<T> as extern fn (&mut Object, _, _) -> NSUInteger);
decl.add_method(sel!(prepareForDragOperation:), prepare_for_drag_operation::<T> as extern fn (&mut Object, _, _) -> BOOL);
decl.add_method(sel!(performDragOperation:), perform_drag_operation::<T> as extern fn (&mut Object, _, _) -> BOOL);
decl.add_method(sel!(concludeDragOperation:), conclude_drag_operation::<T> as extern fn (&mut Object, _, _));
decl.add_method(sel!(draggingExited:), dragging_exited::<T> as extern fn (&mut Object, _, _));
decl.add_method(
sel!(draggingEntered:),
dragging_entered::<T> as extern "C" fn(&mut Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(performDragOperation:),
perform_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(concludeDragOperation:),
conclude_drag_operation::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(draggingExited:),
dragging_exited::<T> as extern "C" fn(&mut Object, _, _)
);
// Cleanup
decl.add_method(sel!(dealloc), dealloc::<T> as extern fn (&Object, _));
decl.add_method(sel!(dealloc), dealloc::<T> as extern "C" fn(&Object, _));
VIEW_CLASS = decl.register();
});
unsafe {
VIEW_CLASS
}
unsafe { VIEW_CLASS }
}

View file

@ -41,23 +41,23 @@
//!
//! For more information on Autolayout, view the module or check out the examples folder.
use std::rc::Rc;
use std::cell::RefCell;
use std::rc::Rc;
use objc_id::{Id, ShareId};
use objc::runtime::{Class, Object};
use objc::{class, msg_send, sel, sel_impl};
use objc_id::{Id, ShareId};
use crate::foundation::{id, nil, YES, NO, NSArray, NSString};
use crate::color::Color;
use crate::foundation::{id, nil, NSArray, NSString, NO, YES};
use crate::layer::Layer;
use crate::layout::Layout;
use crate::objc_access::ObjcAccess;
use crate::view::{ViewAnimatorProxy, ViewDelegate};
use crate::utils::properties::ObjcProperty;
use crate::view::{ViewAnimatorProxy, ViewDelegate};
#[cfg(feature = "autolayout")]
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension, SafeAreaLayoutGuide};
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY, SafeAreaLayoutGuide};
#[cfg(feature = "appkit")]
mod appkit;
@ -195,12 +195,15 @@ impl ListViewRow {
center_x: LayoutAnchorX::center(view),
#[cfg(feature = "autolayout")]
center_y: LayoutAnchorY::center(view),
center_y: LayoutAnchorY::center(view)
}
}
}
impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
impl<T> ListViewRow<T>
where
T: ViewDelegate + 'static
{
/// When we're able to retrieve a reusable view cell from the backing table view, we can check
/// for the pointer and attempt to reconstruct the ListViewRow<T> that corresponds to this.
///
@ -256,7 +259,7 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
center_x: LayoutAnchorX::center(view),
#[cfg(feature = "autolayout")]
center_y: LayoutAnchorY::center(view),
center_y: LayoutAnchorY::center(view)
};
view
@ -312,7 +315,7 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
center_x: LayoutAnchorX::center(view),
#[cfg(feature = "autolayout")]
center_y: LayoutAnchorY::center(view),
center_y: LayoutAnchorY::center(view)
};
(&mut delegate).did_load(view.clone_as_handle());
@ -364,7 +367,7 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
center_x: self.center_x.clone(),
#[cfg(feature = "autolayout")]
center_y: self.center_y.clone(),
center_y: self.center_y.clone()
}
}
}
@ -413,7 +416,7 @@ impl<T> ListViewRow<T> {
center_x: self.center_x.clone(),
#[cfg(feature = "autolayout")]
center_y: self.center_y.clone(),
center_y: self.center_y.clone()
}
}
@ -449,6 +452,5 @@ impl<T> ObjcAccess for ListViewRow<T> {
impl<T> Layout for ListViewRow<T> {}
impl<T> Drop for ListViewRow<T> {
fn drop(&mut self) {
}
fn drop(&mut self) {}
}

View file

@ -2,8 +2,8 @@
use crate::appkit::menu::MenuItem;
use crate::dragdrop::{DragInfo, DragOperation};
use crate::listview::{ListView, ListViewRow, RowAction, RowEdge};
use crate::layout::Layout;
use crate::listview::{ListView, ListViewRow, RowAction, RowEdge};
use crate::view::View;
#[allow(unused_variables)]
@ -43,11 +43,15 @@ pub trait ListViewDelegate {
/// Called when the menu for the tableview is about to be shown. You can update the menu here
/// depending on, say, what the user has context-clicked on. You should avoid any expensive
/// work in here and return the menu as fast as possible.
fn context_menu(&self) -> Vec<MenuItem> { vec![] }
fn context_menu(&self) -> Vec<MenuItem> {
vec![]
}
/// An optional delegate method; implement this if you'd like swipe-to-reveal to be
/// supported for a given row by returning a vector of actions to show.
fn actions_for(&self, row: usize, edge: RowEdge) -> Vec<RowAction> { Vec::new() }
fn actions_for(&self, row: usize, edge: RowEdge) -> Vec<RowAction> {
Vec::new()
}
/// Called when this is about to be added to the view heirarchy.
fn will_appear(&self, animated: bool) {}
@ -62,13 +66,19 @@ pub trait ListViewDelegate {
fn did_disappear(&self, animated: bool) {}
/// Invoked when the dragged image enters destination bounds or frame; returns dragging operation to perform.
fn dragging_entered(&self, info: DragInfo) -> DragOperation { DragOperation::None }
fn dragging_entered(&self, info: DragInfo) -> DragOperation {
DragOperation::None
}
/// Invoked when the image is released, allowing the receiver to agree to or refuse drag operation.
fn prepare_for_drag_operation(&self, info: DragInfo) -> bool { false }
fn prepare_for_drag_operation(&self, info: DragInfo) -> bool {
false
}
/// Invoked after the released image has been removed from the screen, signaling the receiver to import the pasteboard data.
fn perform_drag_operation(&self, info: DragInfo) -> bool { false }
fn perform_drag_operation(&self, info: DragInfo) -> bool {
false
}
/// Invoked when the dragging operation is complete, signaling the receiver to perform any necessary clean-up.
fn conclude_drag_operation(&self, info: DragInfo) {}

Some files were not shown because too many files have changed in this diff Show more