General cleanup, implementing an NSPasteboard wrapper, support for setting background colors on views
This commit is contained in:
parent
0446227a8d
commit
6c12a8fa29
|
@ -11,12 +11,12 @@ use objc::declare::ClassDecl;
|
||||||
use objc::runtime::{Class, Object, Sel};
|
use objc::runtime::{Class, Object, Sel};
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::constants::APP_PTR;
|
||||||
use crate::menu::Menu;
|
use crate::menu::Menu;
|
||||||
|
|
||||||
mod events;
|
mod events;
|
||||||
use events::register_app_class;
|
use events::register_app_class;
|
||||||
|
|
||||||
static APP_PTR: &str = "rstAppPtr";
|
|
||||||
|
|
||||||
pub trait AppDelegate {
|
pub trait AppDelegate {
|
||||||
type Message: Send + Sync;
|
type Message: Send + Sync;
|
||||||
|
|
128
appkit/src/color.rs
Normal file
128
appkit/src/color.rs
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
//! Implements `Color`. Heavily based on the `Color` module in Servo's CSS parser, but tweaked
|
||||||
|
//! for (what I believe) is a friendlier API, and to separate out the parsing into a separate
|
||||||
|
//! module.
|
||||||
|
|
||||||
|
use cocoa::base::id;
|
||||||
|
use core_graphics::base::CGFloat;
|
||||||
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
/// A color with red, green, blue, and alpha components, in a byte each.
|
||||||
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
|
pub struct Color {
|
||||||
|
/// The red component.
|
||||||
|
pub red: u8,
|
||||||
|
/// The green component.
|
||||||
|
pub green: u8,
|
||||||
|
/// The blue component.
|
||||||
|
pub blue: u8,
|
||||||
|
/// The alpha component.
|
||||||
|
pub alpha: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Color {
|
||||||
|
fn default() -> Color {
|
||||||
|
Color { red: 0, green: 0, blue: 0, alpha: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
/// Constructs a new Color value from float components. It expects the red,
|
||||||
|
/// green, blue and alpha channels in that order, and all values will be
|
||||||
|
/// clamped to the 0.0 ... 1.0 range.
|
||||||
|
#[inline]
|
||||||
|
pub fn new<T: Into<f32>>(red: T, green: T, blue: T, alpha: T) -> Self {
|
||||||
|
Self::from_u8s(
|
||||||
|
clamp_unit_f32(red.into()),
|
||||||
|
clamp_unit_f32(green.into()),
|
||||||
|
clamp_unit_f32(blue.into()),
|
||||||
|
clamp_unit_f32(alpha.into()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps to NS/UIColor.
|
||||||
|
pub fn into_platform_specific_color(&self) -> id {
|
||||||
|
let red = self.red as CGFloat / 255.0;
|
||||||
|
let green = self.green as CGFloat / 255.0;
|
||||||
|
let blue = self.blue as CGFloat / 255.0;
|
||||||
|
let alpha = self.alpha as CGFloat / 255.0;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
msg_send![class!(NSColor), colorWithRed:red green:green blue:blue alpha:alpha]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a transparent color.
|
||||||
|
#[inline]
|
||||||
|
pub fn transparent() -> Self {
|
||||||
|
Self::new(0., 0., 0., 0.)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Same thing, but with `u8` values instead of floats in the 0 to 1 range.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_u8s(red: u8, green: u8, blue: u8, alpha: u8) -> Self {
|
||||||
|
Color {
|
||||||
|
red: red,
|
||||||
|
green: green,
|
||||||
|
blue: blue,
|
||||||
|
alpha: alpha,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the red channel in a floating point number form, from 0 to 1.
|
||||||
|
#[inline]
|
||||||
|
pub fn red_f32(&self) -> f32 {
|
||||||
|
self.red as f32 / 255.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the green channel in a floating point number form, from 0 to 1.
|
||||||
|
#[inline]
|
||||||
|
pub fn green_f32(&self) -> f32 {
|
||||||
|
self.green as f32 / 255.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the blue channel in a floating point number form, from 0 to 1.
|
||||||
|
#[inline]
|
||||||
|
pub fn blue_f32(&self) -> f32 {
|
||||||
|
self.blue as f32 / 255.0
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the alpha channel in a floating point number form, from 0 to 1.
|
||||||
|
#[inline]
|
||||||
|
pub fn alpha_f32(&self) -> f32 {
|
||||||
|
self.alpha as f32 / 255.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A less-verbose way of specifying a generic color, without alpha.
|
||||||
|
#[inline]
|
||||||
|
pub fn rgb<T: Into<f32>>(red: T, green: T, blue: T) -> Color {
|
||||||
|
rgba(red.into(), green.into(), blue.into(), 1.)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A less-verbose way of specifying a generic color, with alpha.
|
||||||
|
#[inline]
|
||||||
|
pub fn rgba<T: Into<f32>>(red: T, green: T, blue: T, alpha: T) -> Color {
|
||||||
|
Color::new(red.into(), green.into(), blue.into(), alpha.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clamp_unit_f32(val: f32) -> u8 {
|
||||||
|
// Whilst scaling by 256 and flooring would provide
|
||||||
|
// an equal distribution of integers to percentage inputs,
|
||||||
|
// this is not what Gecko does so we instead multiply by 255
|
||||||
|
// and round (adding 0.5 and flooring is equivalent to rounding)
|
||||||
|
//
|
||||||
|
// Chrome does something similar for the alpha value, but not
|
||||||
|
// the rgb values.
|
||||||
|
//
|
||||||
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1340484
|
||||||
|
//
|
||||||
|
// Clamping to 256 and rounding after would let 1.0 map to 256, and
|
||||||
|
// `256.0_f32 as u8` is undefined behavior:
|
||||||
|
//
|
||||||
|
// https://github.com/rust-lang/rust/issues/10184
|
||||||
|
clamp_floor_256_f32(val * 255.)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clamp_floor_256_f32(val: f32) -> u8 {
|
||||||
|
val.round().max(0.).min(255.) as u8
|
||||||
|
}
|
10
appkit/src/constants.rs
Normal file
10
appkit/src/constants.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
//! Constants typically used for referencing around in the Objective-C runtime.
|
||||||
|
//! Specific to this crate.
|
||||||
|
|
||||||
|
pub(crate) static APP_PTR: &str = "rstAppPtr";
|
||||||
|
pub(crate) static BACKGROUND_COLOR: &str = "rstBackgroundColor";
|
||||||
|
pub(crate) static TOOLBAR_PTR: &str = "rstToolbarPtr";
|
||||||
|
pub(crate) static VIEW_CONTROLLER_PTR: &str = "rstViewControllerPtr";
|
||||||
|
pub(crate) static WEBVIEW_CONFIG_VAR: &str = "rstWebViewConfig";
|
||||||
|
pub(crate) static WEBVIEW_VAR: &str = "rstWebView";
|
||||||
|
pub(crate) static WEBVIEW_CONTROLLER_PTR: &str = "rstWebViewControllerPtr";
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
use cocoa::foundation::NSUInteger;
|
use cocoa::foundation::NSUInteger;
|
||||||
|
|
||||||
|
use objc::runtime::Object;
|
||||||
|
use objc_id::Id;
|
||||||
|
|
||||||
/// Represents operations that can happen for a given drag/drop scenario.
|
/// Represents operations that can happen for a given drag/drop scenario.
|
||||||
pub enum DragOperation {
|
pub enum DragOperation {
|
||||||
/// No drag operations are allowed.
|
/// No drag operations are allowed.
|
||||||
|
@ -45,3 +48,13 @@ impl From<DragOperation> for NSUInteger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A wrapper for `NSDraggingInfo`. As this is a protocol/type you should never create yourself,
|
||||||
|
/// this only provides getters - merely a Rust-y way to grab what you need.
|
||||||
|
pub struct DragInfo {
|
||||||
|
pub info: Id<Object>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DragInfo {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use cocoa::base::{id, nil, NO};
|
use cocoa::base::{id, nil, NO};
|
||||||
use cocoa::foundation::{NSInteger, NSUInteger};
|
use cocoa::foundation::NSUInteger;
|
||||||
|
|
||||||
use objc_id::Id;
|
use objc_id::Id;
|
||||||
use objc::runtime::Object;
|
use objc::runtime::Object;
|
||||||
|
|
|
@ -23,7 +23,9 @@ pub use cocoa::base::id;
|
||||||
pub mod alert;
|
pub mod alert;
|
||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod button;
|
pub mod button;
|
||||||
|
pub mod color;
|
||||||
pub mod collection_view;
|
pub mod collection_view;
|
||||||
|
pub mod constants;
|
||||||
pub mod dragdrop;
|
pub mod dragdrop;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod filesystem;
|
pub mod filesystem;
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
//! This module provides some basic wrappers for PasteBoard functionality. It's currently not an
|
|
||||||
//! exhaustive clone, but feel free to pull request accordingly!
|
|
||||||
|
|
||||||
use cocoa::base::{id, nil};
|
|
||||||
use cocoa::foundation::NSString;
|
|
||||||
|
|
||||||
/// Represents different PasteBoard types that can be referred to.
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub enum PasteBoardType {
|
|
||||||
/// URL data for one file or resource.
|
|
||||||
URL,
|
|
||||||
|
|
||||||
/// Color data.
|
|
||||||
Color,
|
|
||||||
|
|
||||||
/// A file URL.
|
|
||||||
FileURL,
|
|
||||||
|
|
||||||
/// Font and character information.
|
|
||||||
Font,
|
|
||||||
|
|
||||||
/// Type for HTML content.
|
|
||||||
HTML,
|
|
||||||
|
|
||||||
/// Multiple text selection.
|
|
||||||
MultipleTextSelection,
|
|
||||||
|
|
||||||
/// PDF data.
|
|
||||||
PDF,
|
|
||||||
|
|
||||||
/// PNG image data.
|
|
||||||
PNG,
|
|
||||||
|
|
||||||
/// Rich Text Format (RTF) data.
|
|
||||||
RTF,
|
|
||||||
|
|
||||||
/// RTFD formatted file contents.
|
|
||||||
RTFD,
|
|
||||||
|
|
||||||
/// Paragraph formatting information.
|
|
||||||
Ruler,
|
|
||||||
|
|
||||||
/// Sound data.
|
|
||||||
Sound,
|
|
||||||
|
|
||||||
/// String data.
|
|
||||||
String,
|
|
||||||
|
|
||||||
/// Tab-separated fields of text.
|
|
||||||
TabularText,
|
|
||||||
|
|
||||||
/// Tag Image File Format (TIFF) data.
|
|
||||||
TIFF
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PasteBoardType {
|
|
||||||
/// Creates an `NSString` out of the underlying type.
|
|
||||||
pub fn to_nsstring(&self) -> id {
|
|
||||||
unsafe {
|
|
||||||
NSString::alloc(nil).init_str(match self {
|
|
||||||
PasteBoardType::URL => "public.url",
|
|
||||||
PasteBoardType::Color => "com.apple.cocoa.pasteboard.color",
|
|
||||||
PasteBoardType::FileURL => "public.file-url",
|
|
||||||
PasteBoardType::Font => "com.apple.cocoa.pasteboard.character-formatting",
|
|
||||||
PasteBoardType::HTML => "public.html",
|
|
||||||
PasteBoardType::MultipleTextSelection => "com.apple.cocoa.pasteboard.multiple-text-selection",
|
|
||||||
PasteBoardType::PDF => "com.adobe.pdf",
|
|
||||||
PasteBoardType::PNG => "public.png",
|
|
||||||
PasteBoardType::RTF => "public.rtf",
|
|
||||||
PasteBoardType::RTFD => "com.apple.flat-rtfd",
|
|
||||||
PasteBoardType::Ruler => "com.apple.cocoa.pasteboard.paragraph-formatting",
|
|
||||||
PasteBoardType::Sound => "com.apple.cocoa.pasteboard.sound",
|
|
||||||
PasteBoardType::String => "public.utf8-plain-text",
|
|
||||||
PasteBoardType::TabularText => "public.utf8-tab-separated-values-text",
|
|
||||||
PasteBoardType::TIFF => "public.tiff",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
6
appkit/src/pasteboard/mod.rs
Normal file
6
appkit/src/pasteboard/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
pub mod types;
|
||||||
|
pub use types::*;
|
||||||
|
|
||||||
|
pub mod pasteboard;
|
||||||
|
pub use pasteboard::*;
|
67
appkit/src/pasteboard/pasteboard.rs
Normal file
67
appkit/src/pasteboard/pasteboard.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
//! A wrapper for NSPasteBoard, which is the interface for copy/paste and general transferring
|
||||||
|
//! (think: drag and drop between applications). It exposes a Rust interface that tries to be
|
||||||
|
//! complete, but might not cover everything 100% right now - feel free to pull request.
|
||||||
|
|
||||||
|
use cocoa::base::id;
|
||||||
|
|
||||||
|
use objc::runtime::Object;
|
||||||
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
use objc_id::Id;
|
||||||
|
|
||||||
|
use crate::pasteboard::types::PasteboardName;
|
||||||
|
|
||||||
|
/// Represents an `NSPasteboard`, enabling you to handle copy/paste/drag and drop.
|
||||||
|
pub struct Pasteboard {
|
||||||
|
/// The internal pointer to the Objective-C side.
|
||||||
|
pub inner: Id<Object>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Pasteboard {
|
||||||
|
fn default() -> Self {
|
||||||
|
Pasteboard {
|
||||||
|
inner: unsafe { Id::from_ptr(msg_send![class!(NSPasteboard), generalPasteboard]) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pasteboard {
|
||||||
|
/// Used internally for wrapping a Pasteboard returned from operations (say, drag and drop).
|
||||||
|
pub(crate) fn with(existing: id) -> Self {
|
||||||
|
Pasteboard {
|
||||||
|
inner: unsafe { Id::from_ptr(existing) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Should be pasteboardname enum!
|
||||||
|
pub fn named(name: PasteboardName) -> Self {
|
||||||
|
Pasteboard {
|
||||||
|
inner: unsafe {
|
||||||
|
let name = name.to_nsstring();
|
||||||
|
Id::from_ptr(msg_send![class!(NSPasteboard), pasteboardWithName:name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates and returns a new pasteboard with a name that is guaranteed to be unique with
|
||||||
|
/// respect to other pasteboards in the system.
|
||||||
|
pub fn unique() -> Self {
|
||||||
|
Pasteboard {
|
||||||
|
inner: unsafe { Id::from_ptr(msg_send![class!(NSPasteboard), pasteboardWithUniqueName]) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Releases the receiver’s resources in the pasteboard server. It's rare-ish to need to use
|
||||||
|
/// this, but considering this stuff happens on the Objective-C side you may need it.
|
||||||
|
pub fn release_globally(&self) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![&*self.inner, releaseGlobally];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears the existing contents of the pasteboard.
|
||||||
|
pub fn clear_contents(&self) {
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![&*self.inner, clearContents];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
appkit/src/pasteboard/types.rs
Normal file
104
appkit/src/pasteboard/types.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
//! This module provides some basic wrappers for Pasteboard functionality. It's currently not an
|
||||||
|
//! exhaustive clone, but feel free to pull request accordingly!
|
||||||
|
|
||||||
|
use cocoa::base::{id, nil};
|
||||||
|
use cocoa::foundation::NSString;
|
||||||
|
|
||||||
|
/// Constants for the standard system pasteboard names.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum PasteboardName {
|
||||||
|
Drag,
|
||||||
|
Find,
|
||||||
|
Font,
|
||||||
|
General,
|
||||||
|
Ruler
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PasteboardName {
|
||||||
|
/// Creates an `NSString` out of the underlying type.
|
||||||
|
pub fn to_nsstring(&self) -> id {
|
||||||
|
unsafe {
|
||||||
|
NSString::alloc(nil).init_str(match self {
|
||||||
|
PasteboardName::Drag => "",
|
||||||
|
PasteboardName::Find => "",
|
||||||
|
PasteboardName::Font => "",
|
||||||
|
PasteboardName::General => "",
|
||||||
|
PasteboardName::Ruler => ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents different Pasteboard types that can be referred to.
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub enum PasteboardType {
|
||||||
|
/// URL data for one file or resource.
|
||||||
|
URL,
|
||||||
|
|
||||||
|
/// Color data.
|
||||||
|
Color,
|
||||||
|
|
||||||
|
/// A file URL.
|
||||||
|
FileURL,
|
||||||
|
|
||||||
|
/// Font and character information.
|
||||||
|
Font,
|
||||||
|
|
||||||
|
/// Type for HTML content.
|
||||||
|
HTML,
|
||||||
|
|
||||||
|
/// Multiple text selection.
|
||||||
|
MultipleTextSelection,
|
||||||
|
|
||||||
|
/// PDF data.
|
||||||
|
PDF,
|
||||||
|
|
||||||
|
/// PNG image data.
|
||||||
|
PNG,
|
||||||
|
|
||||||
|
/// Rich Text Format (RTF) data.
|
||||||
|
RTF,
|
||||||
|
|
||||||
|
/// RTFD formatted file contents.
|
||||||
|
RTFD,
|
||||||
|
|
||||||
|
/// Paragraph formatting information.
|
||||||
|
Ruler,
|
||||||
|
|
||||||
|
/// Sound data.
|
||||||
|
Sound,
|
||||||
|
|
||||||
|
/// String data.
|
||||||
|
String,
|
||||||
|
|
||||||
|
/// Tab-separated fields of text.
|
||||||
|
TabularText,
|
||||||
|
|
||||||
|
/// Tag Image File Format (TIFF) data.
|
||||||
|
TIFF
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PasteboardType {
|
||||||
|
/// Creates an `NSString` out of the underlying type.
|
||||||
|
pub fn to_nsstring(&self) -> id {
|
||||||
|
unsafe {
|
||||||
|
NSString::alloc(nil).init_str(match self {
|
||||||
|
PasteboardType::URL => "public.url",
|
||||||
|
PasteboardType::Color => "com.apple.cocoa.pasteboard.color",
|
||||||
|
PasteboardType::FileURL => "public.file-url",
|
||||||
|
PasteboardType::Font => "com.apple.cocoa.pasteboard.character-formatting",
|
||||||
|
PasteboardType::HTML => "public.html",
|
||||||
|
PasteboardType::MultipleTextSelection => "com.apple.cocoa.pasteboard.multiple-text-selection",
|
||||||
|
PasteboardType::PDF => "com.adobe.pdf",
|
||||||
|
PasteboardType::PNG => "public.png",
|
||||||
|
PasteboardType::RTF => "public.rtf",
|
||||||
|
PasteboardType::RTFD => "com.apple.flat-rtfd",
|
||||||
|
PasteboardType::Ruler => "com.apple.cocoa.pasteboard.paragraph-formatting",
|
||||||
|
PasteboardType::Sound => "com.apple.cocoa.pasteboard.sound",
|
||||||
|
PasteboardType::String => "public.utf8-plain-text",
|
||||||
|
PasteboardType::TabularText => "public.utf8-tab-separated-values-text",
|
||||||
|
PasteboardType::TIFF => "public.tiff",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,13 +11,12 @@ use cocoa::foundation::{NSArray, NSString};
|
||||||
use objc_id::Id;
|
use objc_id::Id;
|
||||||
use objc::declare::ClassDecl;
|
use objc::declare::ClassDecl;
|
||||||
use objc::runtime::{Class, Object, Sel};
|
use objc::runtime::{Class, Object, Sel};
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::constants::TOOLBAR_PTR;
|
||||||
use crate::toolbar::item::ToolbarItem;
|
use crate::toolbar::item::ToolbarItem;
|
||||||
use crate::utils::str_from;
|
use crate::utils::str_from;
|
||||||
|
|
||||||
static TOOLBAR_PTR: &str = "rstToolbarPtr";
|
|
||||||
|
|
||||||
/// A trait that you can implement to have your struct/etc act as an `NSToolbarDelegate`.
|
/// A trait that you can implement to have your struct/etc act as an `NSToolbarDelegate`.
|
||||||
pub trait ToolbarDelegate {
|
pub trait ToolbarDelegate {
|
||||||
/// What items are allowed in this toolbar.
|
/// What items are allowed in this toolbar.
|
||||||
|
@ -30,8 +29,8 @@ pub trait ToolbarDelegate {
|
||||||
fn item_for(&self, _identifier: &str) -> ToolbarItem;
|
fn item_for(&self, _identifier: &str) -> ToolbarItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for `NSWindow`. Holds (retains) pointers for the Objective-C runtime
|
/// A wrapper for `NSToolbar`. Holds (retains) pointers for the Objective-C runtime
|
||||||
/// where our `NSWindow` and associated delegate live.
|
/// where our `NSToolbar` and associated delegate live.
|
||||||
pub struct Toolbar {
|
pub struct Toolbar {
|
||||||
pub inner: Id<Object>,
|
pub inner: Id<Object>,
|
||||||
pub objc_delegate: Id<Object>,
|
pub objc_delegate: Id<Object>,
|
||||||
|
@ -44,7 +43,7 @@ impl Toolbar {
|
||||||
pub fn new<D: ToolbarDelegate + 'static>(identifier: &str, delegate: D) -> Self {
|
pub fn new<D: ToolbarDelegate + 'static>(identifier: &str, delegate: D) -> Self {
|
||||||
let inner = unsafe {
|
let inner = unsafe {
|
||||||
let identifier = NSString::alloc(nil).init_str(identifier);
|
let identifier = NSString::alloc(nil).init_str(identifier);
|
||||||
let alloc: id = msg_send![Class::get("NSToolbar").unwrap(), alloc];
|
let alloc: id = msg_send![class!(NSToolbar), alloc];
|
||||||
let toolbar: id = msg_send![alloc, initWithIdentifier:identifier];
|
let toolbar: id = msg_send![alloc, initWithIdentifier:identifier];
|
||||||
Id::from_ptr(toolbar)
|
Id::from_ptr(toolbar)
|
||||||
};
|
};
|
||||||
|
@ -112,7 +111,7 @@ fn register_delegate_class<D: ToolbarDelegate>() -> *const Class {
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
INIT.call_once(|| unsafe {
|
INIT.call_once(|| unsafe {
|
||||||
let superclass = Class::get("NSObject").unwrap();
|
let superclass = class!(NSObject);
|
||||||
let mut decl = ClassDecl::new("RSTToolbarDelegate", superclass).unwrap();
|
let mut decl = ClassDecl::new("RSTToolbarDelegate", superclass).unwrap();
|
||||||
|
|
||||||
// For callbacks
|
// For callbacks
|
||||||
|
|
|
@ -14,9 +14,9 @@ use cocoa::foundation::{NSUInteger};
|
||||||
|
|
||||||
use objc::declare::ClassDecl;
|
use objc::declare::ClassDecl;
|
||||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
|
|
||||||
use crate::view::VIEW_CONTROLLER_PTR;
|
use crate::constants::{BACKGROUND_COLOR, VIEW_CONTROLLER_PTR};
|
||||||
use crate::view::traits::ViewController;
|
use crate::view::traits::ViewController;
|
||||||
|
|
||||||
/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though.
|
/// Enforces normalcy, or: a needlessly cruel method in terms of the name. You get the idea though.
|
||||||
|
@ -24,9 +24,10 @@ extern fn enforce_normalcy(_: &Object, _: Sel) -> BOOL {
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used for handling background colors in layer backed views (which is the default here).
|
||||||
extern fn update_layer(this: &Object, _: Sel) {
|
extern fn update_layer(this: &Object, _: Sel) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let background_color: id = msg_send![class!(NSColor), redColor];
|
let background_color: id = *this.get_ivar(BACKGROUND_COLOR);
|
||||||
if background_color != nil {
|
if background_color != nil {
|
||||||
let layer: id = msg_send![this, layer];
|
let layer: id = msg_send![this, layer];
|
||||||
let cg: id = msg_send![background_color, CGColor];
|
let cg: id = msg_send![background_color, CGColor];
|
||||||
|
@ -92,6 +93,7 @@ pub(crate) fn register_view_class<T: ViewController>() -> *const Class {
|
||||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||||
// move.
|
// move.
|
||||||
decl.add_ivar::<usize>(VIEW_CONTROLLER_PTR);
|
decl.add_ivar::<usize>(VIEW_CONTROLLER_PTR);
|
||||||
|
decl.add_ivar::<id>(BACKGROUND_COLOR);
|
||||||
|
|
||||||
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
|
decl.add_method(sel!(isFlipped), enforce_normalcy as extern fn(&Object, _) -> BOOL);
|
||||||
decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern fn(&Object, _) -> BOOL);
|
decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern fn(&Object, _) -> BOOL);
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|
||||||
use cocoa::base::{id, nil, YES, NO};
|
use cocoa::base::{id, nil, YES, NO};
|
||||||
use cocoa::foundation::{NSRect, NSUInteger};
|
use cocoa::foundation::{NSRect};
|
||||||
|
|
||||||
use objc::declare::ClassDecl;
|
use objc::declare::ClassDecl;
|
||||||
use objc::runtime::{Class, Object, Sel};
|
use objc::runtime::{Class, Object, Sel};
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::constants::VIEW_CONTROLLER_PTR;
|
||||||
use crate::geometry::Rect;
|
use crate::geometry::Rect;
|
||||||
use crate::view::{VIEW_CONTROLLER_PTR, ViewController};
|
use crate::view::ViewController;
|
||||||
use crate::view::class::register_view_class;
|
use crate::view::class::register_view_class;
|
||||||
|
|
||||||
/// Loads and configures ye old NSView for this controller.
|
/// Loads and configures ye old NSView for this controller.
|
||||||
|
@ -31,7 +32,7 @@ pub fn register_controller_class<T: ViewController + 'static>() -> *const Class
|
||||||
static INIT: Once = Once::new();
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
INIT.call_once(|| unsafe {
|
INIT.call_once(|| unsafe {
|
||||||
let superclass = Class::get("NSViewController").unwrap();
|
let superclass = class!(NSViewController);
|
||||||
let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap();
|
let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap();
|
||||||
|
|
||||||
decl.add_ivar::<usize>(VIEW_CONTROLLER_PTR);
|
decl.add_ivar::<usize>(VIEW_CONTROLLER_PTR);
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
|
|
||||||
pub(crate) static VIEW_CONTROLLER_PTR: &str = "rstViewControllerPtr";
|
|
||||||
|
|
||||||
pub(crate) mod class;
|
pub(crate) mod class;
|
||||||
pub(crate) mod controller;
|
pub(crate) mod controller;
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,16 @@ use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use cocoa::base::{id, nil, YES, NO};
|
use cocoa::base::{id, nil, YES, NO};
|
||||||
use cocoa::foundation::{NSString, NSArray};
|
use cocoa::foundation::NSArray;
|
||||||
|
|
||||||
use objc_id::ShareId;
|
use objc_id::ShareId;
|
||||||
use objc::runtime::Object;
|
use objc::runtime::Object;
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
|
|
||||||
use crate::pasteboard::PasteBoardType;
|
use crate::color::Color;
|
||||||
use crate::view::{VIEW_CONTROLLER_PTR, ViewController};
|
use crate::constants::{BACKGROUND_COLOR, VIEW_CONTROLLER_PTR};
|
||||||
|
use crate::pasteboard::PasteboardType;
|
||||||
|
use crate::view::traits::ViewController;
|
||||||
use crate::view::controller::register_controller_class;
|
use crate::view::controller::register_controller_class;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -32,7 +34,7 @@ impl ViewInner {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_for_dragged_types(&self, types: &[PasteBoardType]) {
|
pub fn register_for_dragged_types(&self, types: &[PasteboardType]) {
|
||||||
if let Some(controller) = &self.controller {
|
if let Some(controller) = &self.controller {
|
||||||
unsafe {
|
unsafe {
|
||||||
let types = NSArray::arrayWithObjects(nil, &types.iter().map(|t| {
|
let types = NSArray::arrayWithObjects(nil, &types.iter().map(|t| {
|
||||||
|
@ -44,6 +46,16 @@ impl ViewInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_background_color(&self, color: Color) {
|
||||||
|
if let Some(controller) = &self.controller {
|
||||||
|
unsafe {
|
||||||
|
let view: id = msg_send![*controller, view];
|
||||||
|
(*view).set_ivar(BACKGROUND_COLOR, color.into_platform_specific_color());
|
||||||
|
let _: () = msg_send![view, setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -64,8 +76,13 @@ impl View {
|
||||||
view.controller.clone()
|
view.controller.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_for_dragged_types(&self, types: &[PasteBoardType]) {
|
pub fn register_for_dragged_types(&self, types: &[PasteboardType]) {
|
||||||
let view = self.0.borrow();
|
let view = self.0.borrow();
|
||||||
view.register_for_dragged_types(types);
|
view.register_for_dragged_types(types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_background_color(&self, color: Color) {
|
||||||
|
let view = self.0.borrow();
|
||||||
|
view.set_background_color(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,9 @@ use objc::declare::ClassDecl;
|
||||||
use objc::runtime::{Class, Object, Sel};
|
use objc::runtime::{Class, Object, Sel};
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
use crate::view::ViewController;
|
use crate::constants::{WEBVIEW_VAR, WEBVIEW_CONFIG_VAR, WEBVIEW_CONTROLLER_PTR};
|
||||||
use crate::view::class::register_view_class;
|
use crate::view::traits::ViewController;
|
||||||
use crate::webview::action::{NavigationAction, NavigationResponse};
|
use crate::webview::action::{NavigationAction, NavigationResponse};
|
||||||
use crate::webview::{WEBVIEW_VAR, WEBVIEW_CONFIG_VAR, WEBVIEW_CONTROLLER_PTR};
|
|
||||||
use crate::webview::traits::WebViewController;
|
use crate::webview::traits::WebViewController;
|
||||||
use crate::utils::str_from;
|
use crate::utils::str_from;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
//! A wrapper for WKWebview and associated configurations and properties.
|
//! A wrapper for WKWebview and associated configurations and properties.
|
||||||
|
|
||||||
pub(crate) static WEBVIEW_CONFIG_VAR: &str = "rstWebViewConfig";
|
|
||||||
pub(crate) static WEBVIEW_VAR: &str = "rstWebView";
|
|
||||||
pub(crate) static WEBVIEW_CONTROLLER_PTR: &str = "rstWebViewControllerPtr";
|
|
||||||
|
|
||||||
pub mod action;
|
pub mod action;
|
||||||
|
|
||||||
pub(crate) mod controller;
|
pub(crate) mod controller;
|
||||||
|
|
|
@ -18,10 +18,11 @@ use objc_id::ShareId;
|
||||||
use objc::runtime::Object;
|
use objc::runtime::Object;
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
|
||||||
|
use crate::constants::{WEBVIEW_VAR, WEBVIEW_CONFIG_VAR, WEBVIEW_CONTROLLER_PTR};
|
||||||
use crate::view::ViewController;
|
use crate::view::ViewController;
|
||||||
use crate::webview::{WEBVIEW_VAR, WEBVIEW_CONFIG_VAR, WEBVIEW_CONTROLLER_PTR, WebViewController};
|
|
||||||
use crate::webview::controller::register_controller_class;
|
|
||||||
use crate::webview::config::{WebViewConfig, InjectAt};
|
use crate::webview::config::{WebViewConfig, InjectAt};
|
||||||
|
use crate::webview::controller::register_controller_class;
|
||||||
|
use crate::webview::traits::WebViewController;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct WebViewInner {
|
pub struct WebViewInner {
|
||||||
|
|
Loading…
Reference in a new issue