Refactor to use load_or_register_class
This commit is contained in:
parent
2803922f3a
commit
718c831bc4
|
@ -2,27 +2,11 @@
|
|||
//! creates a custom `NSApplication` subclass that currently does nothing; this is meant as a hook
|
||||
//! for potential future use.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::class;
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::Class;
|
||||
|
||||
use crate::foundation::load_or_register_class;
|
||||
|
||||
/// Used for injecting a custom NSApplication. Currently does nothing.
|
||||
pub(crate) fn register_app_class() -> *const Class {
|
||||
static mut APP_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTApplication";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { APP_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSApplication);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
APP_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { APP_CLASS }
|
||||
load_or_register_class("NSApplication", "RSTApplication", |decl| unsafe {})
|
||||
}
|
||||
|
|
|
@ -3,24 +3,19 @@
|
|||
//! for potential future use.
|
||||
|
||||
use std::ffi::c_void;
|
||||
use std::sync::Once;
|
||||
|
||||
use block::Block;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use url::Url;
|
||||
|
||||
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")]
|
||||
use crate::cloudkit::share::CKShareMetaData;
|
||||
use crate::error::Error;
|
||||
use crate::foundation::{id, load_or_register_class, nil, to_bool, NSArray, NSString, NSUInteger, BOOL, NO, YES};
|
||||
use crate::user_activity::UserActivity;
|
||||
|
||||
/// A handy method for grabbing our `AppDelegate` from the pointer. This is different from our
|
||||
/// standard `utils` version as this doesn't require `RefCell` backing.
|
||||
|
@ -295,180 +290,165 @@ extern "C" fn delegate_handles_key<T: AppDelegate>(this: &Object, _: Sel, _: id,
|
|||
/// Registers an `NSObject` application delegate, and configures it for the various callbacks and
|
||||
/// pointers we need to have.
|
||||
pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *const Class {
|
||||
static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTAppDelegate";
|
||||
load_or_register_class("NSObject", "RSTAppDelegate", |decl| unsafe {
|
||||
decl.add_ivar::<usize>(APP_PTR);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { DELEGATE_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSObject);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
// Launching Applications
|
||||
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, _, _)
|
||||
);
|
||||
|
||||
decl.add_ivar::<usize>(APP_PTR);
|
||||
// Managing Active Status
|
||||
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, _, _)
|
||||
);
|
||||
|
||||
// Launching Applications
|
||||
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, _, _)
|
||||
);
|
||||
// Terminating Applications
|
||||
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
|
||||
);
|
||||
|
||||
// Managing Active Status
|
||||
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, _, _)
|
||||
);
|
||||
// Hiding Applications
|
||||
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, _, _));
|
||||
|
||||
// Terminating Applications
|
||||
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
|
||||
);
|
||||
// Managing Windows
|
||||
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
|
||||
);
|
||||
|
||||
// Hiding Applications
|
||||
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, _, _));
|
||||
// Dock Menu
|
||||
decl.add_method(
|
||||
sel!(applicationDockMenu:),
|
||||
dock_menu::<T> as extern "C" fn(&Object, _, _) -> id
|
||||
);
|
||||
|
||||
// Managing Windows
|
||||
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
|
||||
);
|
||||
// Displaying Errors
|
||||
decl.add_method(
|
||||
sel!(application:willPresentError:),
|
||||
will_present_error::<T> as extern "C" fn(&Object, _, _, id) -> id
|
||||
);
|
||||
|
||||
// Dock Menu
|
||||
decl.add_method(
|
||||
sel!(applicationDockMenu:),
|
||||
dock_menu::<T> as extern "C" fn(&Object, _, _) -> id
|
||||
);
|
||||
// Managing the Screen
|
||||
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, _, _)
|
||||
);
|
||||
|
||||
// Displaying Errors
|
||||
decl.add_method(
|
||||
sel!(application:willPresentError:),
|
||||
will_present_error::<T> as extern "C" fn(&Object, _, _, id) -> id
|
||||
);
|
||||
// User Activities
|
||||
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)
|
||||
);
|
||||
|
||||
// Managing the Screen
|
||||
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, _, _)
|
||||
);
|
||||
// Handling push notifications
|
||||
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)
|
||||
);
|
||||
|
||||
// User Activities
|
||||
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)
|
||||
);
|
||||
// CloudKit
|
||||
#[cfg(feature = "cloudkit")]
|
||||
decl.add_method(
|
||||
sel!(application:userDidAcceptCloudKitShareWithMetadata:),
|
||||
accepted_cloudkit_share::<T> as extern "C" fn(&Object, _, _, id)
|
||||
);
|
||||
|
||||
// Handling push notifications
|
||||
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)
|
||||
);
|
||||
// Opening Files
|
||||
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
|
||||
);
|
||||
|
||||
// CloudKit
|
||||
#[cfg(feature = "cloudkit")]
|
||||
decl.add_method(
|
||||
sel!(application:userDidAcceptCloudKitShareWithMetadata:),
|
||||
accepted_cloudkit_share::<T> as extern "C" fn(&Object, _, _, id)
|
||||
);
|
||||
// Printing
|
||||
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
|
||||
);
|
||||
|
||||
// Opening Files
|
||||
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
|
||||
);
|
||||
// @TODO: Restoring Application State
|
||||
// Depends on NSCoder support, which is... welp.
|
||||
|
||||
// Printing
|
||||
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 "C" fn(&Object, _, _, id) -> BOOL
|
||||
);
|
||||
|
||||
DELEGATE_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { DELEGATE_CLASS }
|
||||
// Scripting
|
||||
decl.add_method(
|
||||
sel!(application:delegateHandlesKey:),
|
||||
delegate_handles_key::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
|
||||
);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -3,16 +3,13 @@
|
|||
//! now.
|
||||
|
||||
use std::fmt;
|
||||
use std::sync::Once;
|
||||
|
||||
use block::ConcreteBlock;
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::events::EventModifierFlag;
|
||||
use crate::foundation::{id, nil, NSString, NSUInteger};
|
||||
use crate::foundation::{id, load_or_register_class, NSString, NSUInteger};
|
||||
|
||||
static BLOCK_PTR: &'static str = "cacaoMenuItemBlockPtr";
|
||||
|
||||
|
@ -314,24 +311,10 @@ extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) {
|
|||
/// In general, we do not want to do more than we need to here - menus are one of the last areas
|
||||
/// where Carbon still lurks, and subclassing things can get weird.
|
||||
pub(crate) fn register_menu_item_class() -> *const Class {
|
||||
static mut APP_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "CacaoMenuItem";
|
||||
load_or_register_class("NSMenuItem", "CacaoMenuItem", |decl| unsafe {
|
||||
decl.add_ivar::<usize>(BLOCK_PTR);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { APP_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSMenuItem);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
decl.add_ivar::<usize>(BLOCK_PTR);
|
||||
|
||||
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 }
|
||||
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));
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,31 +1,15 @@
|
|||
//! Everything useful for the `WindowController`. Handles injecting an `NSWindowController` subclass
|
||||
//! into the Objective C runtime, which loops back to give us lifecycle methods.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::class;
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::Class;
|
||||
|
||||
use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR};
|
||||
use crate::foundation::load_or_register_class;
|
||||
|
||||
/// Injects an `NSWindowController` subclass, with some callback and pointer ivars for what we
|
||||
/// need to do.
|
||||
pub(crate) fn register_window_controller_class<T: WindowDelegate>() -> *const Class {
|
||||
static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTWindowController";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { DELEGATE_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSWindowController);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
decl.add_ivar::<usize>(WINDOW_DELEGATE_PTR);
|
||||
DELEGATE_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { DELEGATE_CLASS }
|
||||
load_or_register_class("NSWindowController", "RSTWindowController", |decl| unsafe {
|
||||
decl.add_ivar::<usize>(WINDOW_DELEGATE_PTR);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -21,36 +21,28 @@
|
|||
//! my_view.add_subview(&button);
|
||||
//! ```
|
||||
|
||||
use std::fmt;
|
||||
use std::sync::Once;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc::runtime::{Class, Object};
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc_id::ShareId;
|
||||
|
||||
pub use enums::*;
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
use crate::appkit::FocusRingType;
|
||||
use crate::color::Color;
|
||||
use crate::control::Control;
|
||||
use crate::foundation::{id, nil, NSString, NSUInteger, BOOL, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, nil, NSString, NSUInteger, NO, YES};
|
||||
use crate::image::Image;
|
||||
use crate::invoker::TargetActionHandler;
|
||||
use crate::keys::Key;
|
||||
use crate::layout::Layout;
|
||||
use crate::objc_access::ObjcAccess;
|
||||
use crate::text::{AttributedString, Font};
|
||||
use crate::utils::{load, properties::ObjcProperty};
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
use crate::appkit::FocusRingType;
|
||||
use crate::objc_access::ObjcAccess;
|
||||
use crate::text::{AttributedString, Font};
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
mod enums;
|
||||
pub use enums::*;
|
||||
|
||||
/// Wraps `NSButton` on appkit, and `UIButton` on iOS and tvOS.
|
||||
///
|
||||
|
@ -343,20 +335,5 @@ impl Drop for Button {
|
|||
/// Registers an `NSButton` subclass, and configures it to hold some ivars
|
||||
/// for various things we need to store.
|
||||
fn register_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTButton";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe {
|
||||
VIEW_CLASS = c;
|
||||
}
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSButton);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSButton", "RSTButton", |decl| unsafe {})
|
||||
}
|
||||
|
|
|
@ -10,16 +10,11 @@
|
|||
//! that enables this functionality, we want to be able to provide this with some level of
|
||||
//! backwards compatibility for Mojave, as that's still a supported OS.
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::Once;
|
||||
|
||||
use core_graphics::base::CGFloat;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
|
||||
use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NSUInteger, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, nil, NSArray, NSInteger};
|
||||
use crate::utils::os;
|
||||
|
||||
pub(crate) const AQUA_LIGHT_COLOR_NORMAL_CONTRAST: &'static str = "AQUA_LIGHT_COLOR_NORMAL_CONTRAST";
|
||||
|
@ -259,114 +254,99 @@ extern "C" fn color_with_system_effect(this: &Object, _: Sel, effect: NSInteger)
|
|||
}
|
||||
|
||||
pub(crate) fn register_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "CacaoDynamicColor";
|
||||
load_or_register_class("NSColor", "CacaoDynamicColor", |decl| unsafe {
|
||||
// These methods all need to be forwarded, so let's hook them up.
|
||||
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
|
||||
);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSColor);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
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);
|
||||
|
||||
// These methods all need to be forwarded, so let's hook them up.
|
||||
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!(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!(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!(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!(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!(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!(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!(alphaComponent), alpha_component as extern "C" fn(&Object, _) -> 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!(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!(alphaComponent), alpha_component as extern "C" fn(&Object, _) -> CGFloat);
|
||||
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!(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!(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_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 "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);
|
||||
decl.add_ivar::<id>(AQUA_DARK_COLOR_NORMAL_CONTRAST);
|
||||
decl.add_ivar::<id>(AQUA_DARK_COLOR_HIGH_CONTRAST);
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_NORMAL_CONTRAST);
|
||||
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_HIGH_CONTRAST);
|
||||
decl.add_ivar::<id>(AQUA_DARK_COLOR_NORMAL_CONTRAST);
|
||||
decl.add_ivar::<id>(AQUA_DARK_COLOR_HIGH_CONTRAST);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,38 +7,15 @@
|
|||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||
//! color, and enforcing layer backing by default.
|
||||
|
||||
use std::sync::Once;
|
||||
use objc::runtime::Class;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::foundation::{id, NSUInteger, NO, YES};
|
||||
use crate::utils::load;
|
||||
use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
|
||||
use crate::foundation::load_or_register_class;
|
||||
|
||||
/// 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
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_image_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTImageView";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSImageView);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
//decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSImageView", "RSTImageView", |decl| unsafe {
|
||||
//decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,31 +1,10 @@
|
|||
use std::sync::Once;
|
||||
use objc::runtime::Class;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::foundation::{id, NSUInteger, NO, YES};
|
||||
use crate::utils::load;
|
||||
use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
|
||||
use crate::foundation::load_or_register_class;
|
||||
|
||||
/// 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
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_image_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTImageView";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIImageView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).expect("Failed to get RSTVIEW");
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("UIImageView", "RSTImageView", |decl| unsafe {})
|
||||
}
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::foundation::{id, load_or_register_class, NSString, NSUInteger, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, NSString, NO, YES};
|
||||
use crate::input::{TextFieldDelegate, TEXTFIELD_DELEGATE_PTR};
|
||||
use crate::utils::load;
|
||||
|
||||
|
@ -52,21 +47,7 @@ extern "C" fn text_should_end_editing<T: TextFieldDelegate>(this: &mut Object, _
|
|||
/// have separate classes here since we don't want to waste cycles on methods that will never be
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTTextInputField";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSTextField);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSTextField", "RSTTextInputField", |decl| unsafe {})
|
||||
}
|
||||
|
||||
/// Injects an `NSTextField` subclass, with some callback and pointer ivars for what we
|
||||
|
|
|
@ -9,15 +9,12 @@
|
|||
//! is going away.
|
||||
|
||||
use std::fmt;
|
||||
use std::sync::{Arc, Mutex, Once};
|
||||
|
||||
use block::{Block, ConcreteBlock, RcBlock};
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc_id::ShareId;
|
||||
|
||||
use crate::foundation::{id, nil, NSString};
|
||||
use crate::foundation::{id, load_or_register_class};
|
||||
use crate::utils::load;
|
||||
|
||||
pub static ACTION_CALLBACK_PTR: &str = "rstTargetActionPtr";
|
||||
|
@ -95,25 +92,8 @@ extern "C" fn perform<F: Fn() + 'static>(this: &mut Object, _: Sel, _sender: id)
|
|||
/// on drop. We handle the heap copy on the Rust side, so setting the block
|
||||
/// is just an ivar.
|
||||
pub(crate) fn register_invoker_class<F: Fn() + 'static>() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTTargetActionHandler";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe {
|
||||
VIEW_CLASS = c;
|
||||
}
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSObject);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
decl.add_ivar::<usize>(ACTION_CALLBACK_PTR);
|
||||
decl.add_method(sel!(perform:), perform::<F> as extern "C" fn(&mut Object, _, id));
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSObject", "RSTTargetActionHandler", |decl| unsafe {
|
||||
decl.add_ivar::<usize>(ACTION_CALLBACK_PTR);
|
||||
decl.add_method(sel!(perform:), perform::<F> as extern "C" fn(&mut Object, _, id));
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,16 +7,13 @@
|
|||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||
//! color, and enforcing layer backing by default.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::appkit::menu::{Menu, MenuItem};
|
||||
use crate::appkit::menu::Menu;
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::foundation::{id, load_or_register_class, nil, NSArray, NSInteger, NSUInteger, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, NSArray, NSInteger, NSUInteger, NO, YES};
|
||||
use crate::listview::{ListViewDelegate, RowEdge, LISTVIEW_DELEGATE_PTR};
|
||||
use crate::utils::load;
|
||||
|
||||
|
@ -185,21 +182,7 @@ extern "C" fn dragging_exited<T: ListViewDelegate>(this: &mut Object, _: Sel, in
|
|||
/// `UITableView` semantics; if `NSTableView`'s multi column behavior is needed, then it can
|
||||
/// be added in.
|
||||
pub(crate) fn register_listview_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &'static str = "RSTListView";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSTableView);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSTableView", "RSTListView", |decl| unsafe {})
|
||||
}
|
||||
|
||||
/// Injects an `NSTableView` subclass, with some callback and pointer ivars for what we
|
||||
|
|
|
@ -7,15 +7,12 @@
|
|||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||
//! color, and enforcing layer backing by default.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::foundation::{id, nil, NSUInteger, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, nil, NSUInteger, NO, YES};
|
||||
use crate::listview::row::{ViewDelegate, BACKGROUND_COLOR, LISTVIEW_ROW_DELEGATE_PTR};
|
||||
use crate::utils::load;
|
||||
|
||||
|
@ -107,76 +104,46 @@ extern "C" fn dealloc<T: ViewDelegate>(this: &Object, _: Sel) {
|
|||
/// have separate classes here since we don't want to waste cycles on methods that will never be
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_listview_row_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTTableViewRow";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSView", "RSTTableViewRow", |decl| unsafe {
|
||||
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
})
|
||||
}
|
||||
|
||||
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||
/// need to do.
|
||||
pub(crate) fn register_listview_row_class_with_delegate<T: ViewDelegate>() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTableViewRowWithDelegate";
|
||||
load_or_register_class("NSView", "RSTableViewRowWithDelegate", |decl| unsafe {
|
||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||
// move.
|
||||
decl.add_ivar::<usize>(LISTVIEW_ROW_DELEGATE_PTR);
|
||||
decl.add_ivar::<id>(BACKGROUND_COLOR);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
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, _));
|
||||
|
||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||
// move.
|
||||
decl.add_ivar::<usize>(LISTVIEW_ROW_DELEGATE_PTR);
|
||||
decl.add_ivar::<id>(BACKGROUND_COLOR);
|
||||
// Drag and drop operations (e.g, accepting files)
|
||||
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, _, _)
|
||||
);
|
||||
|
||||
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 "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 "C" fn(&Object, _));
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
// Cleanup
|
||||
decl.add_method(sel!(dealloc), dealloc::<T> as extern "C" fn(&Object, _));
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,53 +1,24 @@
|
|||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
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
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTView";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("UIView", "RSTView", |decl| unsafe {})
|
||||
}
|
||||
|
||||
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||
/// need to do.
|
||||
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTViewWithDelegate";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("UIView", "RSTViewWithDelegate", |decl| unsafe {
|
||||
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,15 +7,12 @@
|
|||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||
//! color, and enforcing layer backing by default.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, sel, sel_impl};
|
||||
use objc::{sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::foundation::{id, NSUInteger, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, NSUInteger, NO, YES};
|
||||
use crate::scrollview::{ScrollViewDelegate, SCROLLVIEW_DELEGATE_PTR};
|
||||
use crate::utils::load;
|
||||
|
||||
|
@ -77,68 +74,39 @@ extern "C" fn dragging_exited<T: ScrollViewDelegate>(this: &mut Object, _: Sel,
|
|||
|
||||
/// Injects an `NSScrollView` subclass.
|
||||
pub(crate) fn register_scrollview_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &'static str = "RSTScrollView";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSScrollView);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSScrollView", "RSTScrollView", |decl| unsafe {})
|
||||
}
|
||||
|
||||
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||
/// need to do.
|
||||
pub(crate) fn register_scrollview_class_with_delegate<T: ScrollViewDelegate>() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &'static str = "RSTScrollViewWithDelegate";
|
||||
load_or_register_class("NSScrollView", "RSTScrollViewWithDelegate", |decl| unsafe {
|
||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||
// move.
|
||||
decl.add_ivar::<usize>(SCROLLVIEW_DELEGATE_PTR);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSScrollView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
|
||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||
// move.
|
||||
decl.add_ivar::<usize>(SCROLLVIEW_DELEGATE_PTR);
|
||||
|
||||
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
|
||||
// Drag and drop operations (e.g, accepting files)
|
||||
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_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
// Drag and drop operations (e.g, accepting files)
|
||||
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, _, _)
|
||||
);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,24 +1,19 @@
|
|||
//! Implements a Select-style dropdown. By default this uses NSPopupSelect on macOS.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use core_graphics::geometry::CGRect;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
use objc::runtime::{Class, Object};
|
||||
use objc::{msg_send, sel, sel_impl};
|
||||
use objc_id::ShareId;
|
||||
|
||||
use crate::control::Control;
|
||||
use crate::foundation::{id, nil, NSInteger, NSString, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, nil, NSInteger, NSString, NO, YES};
|
||||
use crate::geometry::Rect;
|
||||
use crate::invoker::TargetActionHandler;
|
||||
use crate::layout::Layout;
|
||||
use crate::objc_access::ObjcAccess;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
|
||||
use crate::objc_access::ObjcAccess;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
/// Wraps `NSPopUpSelect` on AppKit. Not currently implemented for iOS.
|
||||
///
|
||||
|
@ -268,19 +263,5 @@ impl Drop for Select {
|
|||
/// Registers an `NSSelect` subclass, and configures it to hold some ivars
|
||||
/// for various things we need to store.
|
||||
fn register_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "CacaoSelect";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSPopUpButton);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSPopUpButton", "CacaoSelect", |decl| unsafe {})
|
||||
}
|
||||
|
|
|
@ -1,22 +1,17 @@
|
|||
//! A wrapper for NSSwitch. Currently the epitome of jank - if you're poking around here, expect
|
||||
//! that this will change at some point.
|
||||
|
||||
use std::fmt;
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, 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, nil, NSString, BOOL, NO, YES};
|
||||
use crate::foundation::{id, load_or_register_class, nil, NSString, NO};
|
||||
use crate::invoker::TargetActionHandler;
|
||||
use crate::layout::Layout;
|
||||
use crate::objc_access::ObjcAccess;
|
||||
use crate::utils::{load, properties::ObjcProperty};
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
|
||||
use crate::objc_access::ObjcAccess;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
/// A wrapper for `NSSwitch`. Holds (retains) pointers for the Objective-C runtime
|
||||
/// where our `NSSwitch` lives.
|
||||
|
@ -178,21 +173,5 @@ impl Drop for Switch {
|
|||
/// Registers an `NSButton` subclass, and configures it to hold some ivars
|
||||
/// for various things we need to store.
|
||||
fn register_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTSwitch";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe {
|
||||
VIEW_CLASS = c;
|
||||
}
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSButton);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSButton", "RSTSwitch", |decl| unsafe {})
|
||||
}
|
||||
|
|
|
@ -7,60 +7,24 @@
|
|||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||
//! color, and enforcing layer backing by default.
|
||||
|
||||
use std::sync::Once;
|
||||
use objc::runtime::Class;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, sel, sel_impl};
|
||||
use objc_id::Id;
|
||||
|
||||
use crate::dragdrop::DragInfo;
|
||||
use crate::foundation::{id, NSUInteger, NO, YES};
|
||||
use crate::foundation::load_or_register_class;
|
||||
use crate::text::label::{LabelDelegate, LABEL_DELEGATE_PTR};
|
||||
use crate::utils::load;
|
||||
|
||||
/// Injects an `NSTextField` 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
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTTextField";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSTextField);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSTextField", "RSTTextField", |decl| unsafe {})
|
||||
}
|
||||
|
||||
/// Injects an `NSTextField` subclass, with some callback and pointer ivars for what we
|
||||
/// need to do.
|
||||
pub(crate) fn register_view_class_with_delegate<T: LabelDelegate>() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTTextFieldWithDelegate";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||
// move.
|
||||
decl.add_ivar::<usize>(LABEL_DELEGATE_PTR);
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("NSView", "RSTTextFieldWithDelegate", |decl| unsafe {
|
||||
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
|
||||
// move.
|
||||
decl.add_ivar::<usize>(LABEL_DELEGATE_PTR);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,27 +2,11 @@
|
|||
//! creates a custom `UIApplication` subclass that currently does nothing; this is meant as a hook
|
||||
//! for potential future use.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::class;
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::Class;
|
||||
|
||||
use crate::foundation::load_or_register_class;
|
||||
|
||||
/// Used for injecting a custom UIApplication. Currently does nothing.
|
||||
pub(crate) fn register_app_class() -> *const Class {
|
||||
static mut APP_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTApplication";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { APP_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIApplication);
|
||||
let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
APP_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { APP_CLASS }
|
||||
load_or_register_class("UIApplication", "RSTApplication", |decl| unsafe {})
|
||||
}
|
||||
|
|
|
@ -2,28 +2,20 @@
|
|||
//! creates a custom `UIApplication` subclass that currently does nothing; this is meant as a hook
|
||||
//! for potential future use.
|
||||
|
||||
//use std::ffi::c_void;
|
||||
use std::sync::Once;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{sel, sel_impl};
|
||||
|
||||
//use crate::error::Error;
|
||||
use crate::foundation::{id, load_or_register_class, BOOL, YES};
|
||||
use crate::uikit::app::{AppDelegate, APP_DELEGATE};
|
||||
use crate::uikit::scene::{SceneConnectionOptions, SceneSession};
|
||||
|
||||
//use std::unreachable;
|
||||
|
||||
//use block::Block;
|
||||
|
||||
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, NSArray, NSString, NSUInteger, BOOL, NO, YES};
|
||||
//use crate::user_activity::UserActivity;
|
||||
|
||||
use crate::uikit::app::{AppDelegate, APP_DELEGATE};
|
||||
use crate::uikit::scene::{SceneConfig, SceneConnectionOptions, SceneSession};
|
||||
|
||||
#[cfg(feature = "cloudkit")]
|
||||
use crate::cloudkit::share::CKShareMetaData;
|
||||
|
||||
/// A handy method for grabbing our `AppDelegate` from the pointer. This is different from our
|
||||
/// standard `utils` version as this doesn't require `RefCell` backing.
|
||||
fn app<T>(this: &Object) -> &T {
|
||||
|
@ -49,36 +41,21 @@ extern "C" fn configuration_for_scene_session<T: AppDelegate>(this: &Object, _:
|
|||
/// Registers an `NSObject` application delegate, and configures it for the various callbacks and
|
||||
/// pointers we need to have.
|
||||
pub(crate) fn register_app_delegate_class<T: AppDelegate>() -> *const Class {
|
||||
static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTAppDelegate";
|
||||
load_or_register_class("NSObject", "RSTAppDelegate", |decl| unsafe {
|
||||
// Launching Applications
|
||||
decl.add_method(
|
||||
sel!(application:didFinishLaunchingWithOptions:),
|
||||
did_finish_launching::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
|
||||
);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { DELEGATE_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSObject);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
// Launching Applications
|
||||
decl.add_method(
|
||||
sel!(application:didFinishLaunchingWithOptions:),
|
||||
did_finish_launching::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
|
||||
);
|
||||
|
||||
// Scenes
|
||||
decl.add_method(
|
||||
sel!(application:configurationForConnectingSceneSession:options:),
|
||||
configuration_for_scene_session::<T> as extern "C" fn(&Object, _, _, id, id) -> id
|
||||
);
|
||||
/*decl.add_method(
|
||||
sel!(application:didDiscardSceneSessions:),
|
||||
did_discard_scene_sessions::<T> as extern "C" fn(&Object, _, _, id)
|
||||
);*/
|
||||
|
||||
DELEGATE_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { DELEGATE_CLASS }
|
||||
// Scenes
|
||||
decl.add_method(
|
||||
sel!(application:configurationForConnectingSceneSession:options:),
|
||||
configuration_for_scene_session::<T> as extern "C" fn(&Object, _, _, id, id) -> id
|
||||
);
|
||||
/*decl.add_method(
|
||||
sel!(application:didDiscardSceneSessions:),
|
||||
did_discard_scene_sessions::<T> as extern "C" fn(&Object, _, _, id)
|
||||
);*/
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,25 +1,10 @@
|
|||
use std::ffi::c_void;
|
||||
use std::sync::Once;
|
||||
use std::unreachable;
|
||||
|
||||
use block::Block;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::runtime::{Class, Object, Protocol, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
|
||||
use url::Url;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::foundation::{id, nil, NSArray, NSString, NSUInteger, BOOL, NO, YES};
|
||||
use crate::user_activity::UserActivity;
|
||||
use crate::utils::load;
|
||||
|
||||
use crate::foundation::{id, load_or_register_class};
|
||||
use crate::uikit::app::SCENE_DELEGATE_VENDOR;
|
||||
use crate::uikit::scene::{Scene, SceneConfig, SceneConnectionOptions, SceneSession, WindowSceneDelegate};
|
||||
|
||||
#[cfg(feature = "cloudkit")]
|
||||
use crate::cloudkit::share::CKShareMetaData;
|
||||
use crate::uikit::scene::{Scene, SceneConnectionOptions, SceneSession, WindowSceneDelegate};
|
||||
use crate::utils::load;
|
||||
|
||||
pub(crate) static WINDOW_SCENE_PTR: &str = "rstWindowSceneDelegatePtr";
|
||||
|
||||
|
@ -60,37 +45,20 @@ extern "C" fn scene_will_connect_to_session_with_options<T: WindowSceneDelegate>
|
|||
/// Registers an `NSObject` application delegate, and configures it for the various callbacks and
|
||||
/// pointers we need to have.
|
||||
pub(crate) fn register_window_scene_delegate_class<T: WindowSceneDelegate, F: Fn() -> Box<T>>() -> *const Class {
|
||||
static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTWindowSceneDelegate";
|
||||
load_or_register_class("UIResponder", "RSTWindowSceneDelegate", |decl| unsafe {
|
||||
let p = Protocol::get("UIWindowSceneDelegate").unwrap();
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { DELEGATE_CLASS = c };
|
||||
} else {
|
||||
use objc::runtime::Protocol;
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIResponder);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
// A spot to hold a pointer to
|
||||
decl.add_ivar::<usize>(WINDOW_SCENE_PTR);
|
||||
decl.add_protocol(p);
|
||||
|
||||
let p = Protocol::get("UIWindowSceneDelegate").unwrap();
|
||||
// Override the `init` call to handle creating and attaching a WindowSceneDelegate.
|
||||
decl.add_method(sel!(init), init::<T, F> as extern "C" fn(&mut Object, _) -> id);
|
||||
|
||||
// A spot to hold a pointer to
|
||||
decl.add_ivar::<usize>(WINDOW_SCENE_PTR);
|
||||
decl.add_protocol(p);
|
||||
|
||||
// Override the `init` call to handle creating and attaching a WindowSceneDelegate.
|
||||
decl.add_method(sel!(init), init::<T, F> as extern "C" fn(&mut Object, _) -> id);
|
||||
|
||||
// UIWindowSceneDelegate API
|
||||
decl.add_method(
|
||||
sel!(scene:willConnectToSession:options:),
|
||||
scene_will_connect_to_session_with_options::<T> as extern "C" fn(&Object, _, _, _, _)
|
||||
);
|
||||
|
||||
// Launching Applications
|
||||
DELEGATE_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { DELEGATE_CLASS }
|
||||
// UIWindowSceneDelegate API
|
||||
decl.add_method(
|
||||
sel!(scene:willConnectToSession:options:),
|
||||
scene_will_connect_to_session_with_options::<T> as extern "C" fn(&Object, _, _, _, _)
|
||||
);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
//! for in the modern era. It also implements a few helpers for things like setting a background
|
||||
//! color, and enforcing layer backing by default.
|
||||
|
||||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
|
@ -92,28 +90,13 @@ extern "C" fn update_layer(this: &Object, _: Sel) {
|
|||
/// have separate classes here since we don't want to waste cycles on methods that will never be
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTView";
|
||||
load_or_register_class("NSView", "RSTView", |decl| unsafe {
|
||||
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, _));
|
||||
decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(NSView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
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, _));
|
||||
decl.add_method(sel!(wantsUpdateLayer), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
|
||||
|
||||
decl.add_ivar::<id>(BACKGROUND_COLOR);
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
decl.add_ivar::<id>(BACKGROUND_COLOR);
|
||||
})
|
||||
}
|
||||
|
||||
/// Injects an `NSView` subclass, with some callback and pointer ivars for what we
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
use std::sync::Once;
|
||||
use std::unreachable;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel};
|
||||
use objc::{class, msg_send, sel, sel_impl};
|
||||
|
||||
use crate::foundation::{BOOL};
|
||||
use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate};
|
||||
use crate::utils::{load, as_bool};
|
||||
use crate::foundation::BOOL;
|
||||
use crate::utils::{as_bool, load};
|
||||
use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
|
||||
|
||||
/// Called when the view controller receives a `viewWillAppear:` message.
|
||||
extern "C" fn will_appear<T: ViewDelegate>(this: &mut Object, _: Sel, animated: BOOL) {
|
||||
|
@ -51,32 +48,18 @@ extern "C" fn did_disappear<T: ViewDelegate>(this: &mut Object, _: Sel, animated
|
|||
|
||||
/// Registers an `NSViewDelegate`.
|
||||
pub(crate) fn register_view_controller_class<T: ViewDelegate + 'static>() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTViewController";
|
||||
load_or_register_class("UIViewController", "RSTViewController", |decl| unsafe {
|
||||
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIViewController);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
|
||||
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
|
||||
|
||||
decl.add_method(sel!(viewWillAppear:), will_appear::<T> as extern "C" fn(&mut Object, _, BOOL));
|
||||
decl.add_method(sel!(viewDidAppear:), did_appear::<T> as extern "C" fn(&mut Object, _, BOOL));
|
||||
decl.add_method(
|
||||
sel!(viewWillDisappear:),
|
||||
will_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(viewDidDisappear:),
|
||||
did_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)
|
||||
);
|
||||
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
unsafe { VIEW_CLASS }
|
||||
decl.add_method(sel!(viewWillAppear:), will_appear::<T> as extern "C" fn(&mut Object, _, BOOL));
|
||||
decl.add_method(sel!(viewDidAppear:), did_appear::<T> as extern "C" fn(&mut Object, _, BOOL));
|
||||
decl.add_method(
|
||||
sel!(viewWillDisappear:),
|
||||
will_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(viewDidDisappear:),
|
||||
did_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)
|
||||
);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use std::sync::Once;
|
||||
|
||||
use objc::declare::ClassDecl;
|
||||
use objc::runtime::{Class, Object, Sel, BOOL};
|
||||
use objc::{class, sel, sel_impl};
|
||||
|
@ -14,21 +12,7 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
|
|||
/// have separate classes here since we don't want to waste cycles on methods that will never be
|
||||
/// used if there's no delegates.
|
||||
pub(crate) fn register_view_class() -> *const Class {
|
||||
static mut VIEW_CLASS: *const Class = 0 as *const Class;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTView";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { VIEW_CLASS = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = class!(UIView);
|
||||
let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
|
||||
VIEW_CLASS = decl.register();
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { VIEW_CLASS }
|
||||
load_or_register_class("UIView", "RSTView", |decl| unsafe {})
|
||||
}
|
||||
|
||||
/// Injects a `UIView` subclass, with some callback and pointer ivars for what we
|
||||
|
|
|
@ -4,46 +4,23 @@
|
|||
//!
|
||||
//! If you use that feature, there are no guarantees you'll be accepted into the App Store.
|
||||
|
||||
use std::sync::Once;
|
||||
use std::ffi::c_void;
|
||||
|
||||
use block::Block;
|
||||
|
||||
use cocoa::foundation::{NSRect, NSPoint, NSSize, NSString, NSArray, NSInteger};
|
||||
|
||||
use cocoa::foundation::{NSArray, NSInteger, NSPoint, NSRect, NSSize, NSString};
|
||||
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};
|
||||
use crate::foundation::{id, nil, NO, YES};
|
||||
use crate::webview::traits::WebViewController;
|
||||
|
||||
extern "C" fn download_delegate(this: &Object, _: Sel) -> id {
|
||||
println!("YO!");
|
||||
unsafe {
|
||||
NSString::alloc(nil).init_str("")
|
||||
}
|
||||
unsafe { NSString::alloc(nil).init_str("") }
|
||||
}
|
||||
|
||||
pub fn register_process_pool() -> *const Object {
|
||||
static mut PROCESS_POOL: *const Object = 0 as *const Object;
|
||||
static INIT: Once = Once::new();
|
||||
const CLASS_NAME: &str = "RSTWebViewProcessPool";
|
||||
|
||||
if let Some(c) = Class::get(CLASS_NAME) {
|
||||
unsafe { PROCESS_POOL = c };
|
||||
} else {
|
||||
INIT.call_once(|| unsafe {
|
||||
let superclass = Class::get("WKProcessPool").unwrap();
|
||||
let mut decl = ClassDecl::new("RSTWebViewProcessPool", superclass).unwrap();
|
||||
|
||||
//decl.add_ivar::<id>(DOWNLOAD_DELEGATE_PTR);
|
||||
decl.add_method(sel!(_downloadDelegate), download_delegate as extern "C" fn(&Object, _) -> id);
|
||||
|
||||
//PROCESS_POOL = decl.register();
|
||||
PROCESS_POOL = msg_send![decl.register(), new];
|
||||
});
|
||||
}
|
||||
|
||||
unsafe { PROCESS_POOL }
|
||||
load_or_register_class("WKProcessPool", "RSTWebViewProcessPool", |decl| unsafe {
|
||||
//decl.add_ivar::<id>(DOWNLOAD_DELEGATE_PTR);
|
||||
decl.add_method(sel!(_downloadDelegate), download_delegate as extern "C" fn(&Object, _) -> id);
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue