Throw autolayout behind a feature flag.
- AutoLayout is now behind a feature flag (that is defaulted) to enable building and running on platforms that do _not_ support AutoLayout. - Added a frame-based Layout example for platforms that don't have AutoLayout support. - Fixed a bug in geometry.rs where x/y coordinates would get swapped on conversion to `CGRect`. - Added a README to the examples directory to aid in first time users running examples.
This commit is contained in:
parent
c713194262
commit
93424f74c0
|
@ -38,7 +38,8 @@ eval = "0.4"
|
|||
[features]
|
||||
appkit = ["core-foundation/mac_os_10_8_features"]
|
||||
uikit = []
|
||||
default = ["appkit"]
|
||||
autolayout = []
|
||||
default = ["appkit", "autolayout"]
|
||||
cloudkit = []
|
||||
color_fallbacks = []
|
||||
quicklook = []
|
||||
|
|
115
examples/frame_layout.rs
Normal file
115
examples/frame_layout.rs
Normal file
|
@ -0,0 +1,115 @@
|
|||
//! This example showcases setting up a basic application and window, setting up some views to
|
||||
//! work with autolayout, and some basic ways to handle colors.
|
||||
|
||||
use cacao::color::Color;
|
||||
use cacao::geometry::Rect;
|
||||
use cacao::layout::Layout;
|
||||
use cacao::view::View;
|
||||
|
||||
use cacao::appkit::{App, AppDelegate};
|
||||
use cacao::appkit::menu::{Menu, MenuItem};
|
||||
use cacao::appkit::window::{Window, WindowConfig, WindowDelegate};
|
||||
|
||||
struct BasicApp {
|
||||
window: Window<AppWindow>
|
||||
}
|
||||
|
||||
impl AppDelegate for BasicApp {
|
||||
fn did_finish_launching(&self) {
|
||||
App::set_menu(vec![
|
||||
Menu::new("", vec![
|
||||
MenuItem::Services,
|
||||
MenuItem::Separator,
|
||||
MenuItem::Hide,
|
||||
MenuItem::HideOthers,
|
||||
MenuItem::ShowAll,
|
||||
MenuItem::Separator,
|
||||
MenuItem::Quit
|
||||
]),
|
||||
|
||||
Menu::new("File", vec![
|
||||
MenuItem::CloseWindow
|
||||
]),
|
||||
|
||||
Menu::new("View", vec![
|
||||
MenuItem::EnterFullScreen
|
||||
]),
|
||||
|
||||
Menu::new("Window", vec![
|
||||
MenuItem::Minimize,
|
||||
MenuItem::Zoom,
|
||||
MenuItem::Separator,
|
||||
MenuItem::new("Bring All to Front")
|
||||
])
|
||||
]);
|
||||
|
||||
App::activate();
|
||||
|
||||
self.window.show();
|
||||
}
|
||||
|
||||
fn should_terminate_after_last_window_closed(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct AppWindow {
|
||||
content: View,
|
||||
blue: View,
|
||||
red: View,
|
||||
green: View
|
||||
}
|
||||
|
||||
const CORNER_RADIUS: f64 = 16.;
|
||||
const SPACING: f64 = 10.;
|
||||
const TOP: f64 = 40.;
|
||||
const WIDTH: f64 = 100.;
|
||||
const HEIGHT: f64 = 100.;
|
||||
|
||||
impl WindowDelegate for AppWindow {
|
||||
const NAME: &'static str = "WindowDelegate";
|
||||
|
||||
fn did_load(&mut self, window: Window) {
|
||||
window.set_title("Frame Layout Example");
|
||||
window.set_minimum_content_size(300., 300.);
|
||||
|
||||
self.blue.set_background_color(Color::SystemBlue);
|
||||
self.blue.set_frame(Rect {
|
||||
top: TOP,
|
||||
left: SPACING,
|
||||
width: WIDTH,
|
||||
height: HEIGHT
|
||||
});
|
||||
self.blue.layer.set_corner_radius(CORNER_RADIUS);
|
||||
self.content.add_subview(&self.blue);
|
||||
|
||||
self.red.set_background_color(Color::SystemRed);
|
||||
self.red.set_frame(Rect {
|
||||
top: TOP,
|
||||
left: WIDTH + (SPACING * 2.),
|
||||
width: WIDTH,
|
||||
height: HEIGHT
|
||||
});
|
||||
self.red.layer.set_corner_radius(CORNER_RADIUS);
|
||||
self.content.add_subview(&self.red);
|
||||
|
||||
self.green.set_background_color(Color::SystemGreen);
|
||||
self.green.set_frame(Rect {
|
||||
top: TOP,
|
||||
left: (WIDTH * 2.) + (SPACING * 3.),
|
||||
width: WIDTH,
|
||||
height: HEIGHT
|
||||
});
|
||||
self.green.layer.set_corner_radius(CORNER_RADIUS);
|
||||
self.content.add_subview(&self.green);
|
||||
|
||||
window.set_content_view(&self.content);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
App::new("com.test.window", BasicApp {
|
||||
window: Window::with(WindowConfig::default(), AppWindow::default())
|
||||
}).run();
|
||||
}
|
|
@ -6,7 +6,7 @@ Since this needs to run in an iOS simulator or on a device, you can't run it lik
|
|||
|
||||
- Start a simulator (Simulator.app).
|
||||
- `cargo install cargo-bundle`
|
||||
- `cargo bundle --example ios-beta --target x86_64-apple-ios`
|
||||
- `cargo bundle --example ios-beta --no-default-features --features uikit,autolayout --target x86_64-apple-ios`
|
||||
- `xcrun simctl install booted target/x86_64-apple-ios/debug/examples/bundle/ios/cacao-ios-beta.app`
|
||||
- `xcrun simctl launch --console booted com.cacao.ios-test`
|
||||
|
||||
|
|
64
examples/readme.md
Normal file
64
examples/readme.md
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Cacao Examples
|
||||
This directory contains example code for apps written in cacao. To run an example, check out the list of commands below - some require certain features to be enabled.
|
||||
|
||||
## AutoLayout
|
||||
An example that showcases layout out a view with AutoLayout. This requires the feature flag `autolayout` to be enabled, but it's defaulted for ease of use so doesn't need to be specified here. Platforms where AutoLayout is not supported will likely not work with this example.
|
||||
|
||||
`cargo run --example autolayout`
|
||||
|
||||
## Frame Layout
|
||||
An example that showcases laying out with a more old school Frame-based approach. Platforms where AutoLayout are not supported will want to try this instead of the AutoLayout example.
|
||||
|
||||
**macOS:**
|
||||
`cargo run --example frame_layout`
|
||||
|
||||
**Platforms lacking AutoLayout:**
|
||||
`cargo run --example frame_layout --no-default-features --features appkit`
|
||||
|
||||
## Defaults
|
||||
This example isn't GUI-specific, but showcases accessing `NSUserDefaults` from Rust for persisting basic data.
|
||||
|
||||
`cargo run --example defaults`
|
||||
|
||||
## Window
|
||||
This example showcases creating a basic `Window`. This should run on all AppKit-supporting platforms.
|
||||
|
||||
`cargo run --example window`
|
||||
|
||||
## Window Controller
|
||||
This example showcases creating a basic `WindowController`. This may run on all AppKit-supporting platforms.
|
||||
|
||||
`cargo run --example window_controller`
|
||||
|
||||
## Window Delegate
|
||||
This example showcases creating a basic `WindowDelegate` to receive and handle events. This may run on all AppKit-supporting platforms.
|
||||
|
||||
`cargo run --example window_delegate`
|
||||
|
||||
## Text Input
|
||||
This example showcases text input, and logs it to the underlying console. It's mostly a testbed to ensure that the backing widget for input behaves as expected.
|
||||
|
||||
`cargo run --example text_input`
|
||||
|
||||
## Calculator
|
||||
A Rust-rendition of the macOS Calculator app.
|
||||
|
||||
`cargo run --example calculator`
|
||||
|
||||
## To-Do List
|
||||
A "kitchen sink" example that showcases how to do more advanced things, such as cached reusable ListView components.
|
||||
|
||||
`cargo run --example todos_list`
|
||||
|
||||
## Browser
|
||||
A _very_ basic web browser. Platforms that don't support WKWebView will likely not work with this example.
|
||||
|
||||
`cargo run --example browser --features webview`
|
||||
|
||||
## Webview Custom Protocol
|
||||
This example showcases a custom protocol for the webview feature. Platforms that don't support WKWebView will likely not work with this example.
|
||||
|
||||
`cargo run --example webview_custom_protocol --features webview`
|
||||
|
||||
## iOS (Beta)
|
||||
This example showcases how to build and run an iOS app in Rust. See the README in the `ios-beta` folder for instructions on how to run.
|
|
@ -32,10 +32,13 @@ use crate::color::Color;
|
|||
use crate::image::Image;
|
||||
use crate::foundation::{id, nil, BOOL, YES, NO, NSString, NSUInteger};
|
||||
use crate::invoker::TargetActionHandler;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::text::{AttributedString, Font};
|
||||
use crate::utils::{load, properties::ObjcProperty};
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
use crate::appkit::FocusRingType;
|
||||
|
||||
|
@ -71,33 +74,43 @@ pub struct Button {
|
|||
handler: Option<TargetActionHandler>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -114,23 +127,47 @@ impl Button {
|
|||
];
|
||||
|
||||
let _: () = msg_send![button, setWantsLayer:YES];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![button, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
button
|
||||
};
|
||||
|
||||
Button {
|
||||
handler: None,
|
||||
image: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ impl Rect {
|
|||
impl From<Rect> for CGRect {
|
||||
fn from(rect: Rect) -> CGRect {
|
||||
CGRect::new(
|
||||
&CGPoint::new(rect.top, rect.left),
|
||||
&CGPoint::new(rect.left, rect.top),
|
||||
&CGSize::new(rect.width, rect.height)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,9 +4,12 @@ use objc::{msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, YES, NO, NSArray, NSString};
|
||||
use crate::color::Color;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
mod appkit;
|
||||
|
||||
|
@ -29,6 +32,8 @@ pub use icons::*;
|
|||
fn allocate_view(registration_fn: fn() -> *const Class) -> id {
|
||||
unsafe {
|
||||
let view: id = msg_send![registration_fn(), new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -47,33 +52,43 @@ pub struct ImageView {
|
|||
pub objc: ObjcProperty,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -89,16 +104,36 @@ impl ImageView {
|
|||
let view = allocate_view(register_image_view_class);
|
||||
|
||||
ImageView {
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
}
|
||||
}
|
||||
|
|
136
src/input/mod.rs
136
src/input/mod.rs
|
@ -46,10 +46,13 @@ use objc_id::ShareId;
|
|||
|
||||
use crate::color::Color;
|
||||
use crate::foundation::{id, nil, NSArray, NSInteger, NSString, NO, YES};
|
||||
use crate::layout::{Layout, LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
|
||||
use crate::layout::Layout;
|
||||
use crate::text::{Font, TextAlign};
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorDimension, LayoutAnchorX, LayoutAnchorY};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
mod appkit;
|
||||
|
||||
|
@ -72,6 +75,7 @@ fn common_init(class: *const Class) -> id {
|
|||
unsafe {
|
||||
let view: id = msg_send![class, new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints: NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -92,33 +96,43 @@ pub struct TextField<T = ()> {
|
|||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY,
|
||||
}
|
||||
|
||||
|
@ -136,17 +150,37 @@ impl TextField {
|
|||
|
||||
TextField {
|
||||
delegate: None,
|
||||
top: LayoutAnchorY::top(view),
|
||||
left: LayoutAnchorX::left(view),
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
right: LayoutAnchorX::right(view),
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,17 +203,37 @@ where
|
|||
|
||||
let mut label = TextField {
|
||||
delegate: None,
|
||||
top: LayoutAnchorY::top(label),
|
||||
left: LayoutAnchorX::left(label),
|
||||
leading: LayoutAnchorX::leading(label),
|
||||
right: LayoutAnchorX::right(label),
|
||||
trailing: LayoutAnchorX::trailing(label),
|
||||
bottom: LayoutAnchorY::bottom(label),
|
||||
width: LayoutAnchorDimension::width(label),
|
||||
height: LayoutAnchorDimension::height(label),
|
||||
center_x: LayoutAnchorX::center(label),
|
||||
center_y: LayoutAnchorY::center(label),
|
||||
objc: ObjcProperty::retain(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(label),
|
||||
};
|
||||
|
||||
(&mut delegate).did_load(label.clone_as_handle());
|
||||
|
@ -196,17 +250,37 @@ impl<T> TextField<T> {
|
|||
pub(crate) fn clone_as_handle(&self) -> TextField {
|
||||
TextField {
|
||||
delegate: None,
|
||||
top: self.top.clone(),
|
||||
leading: self.leading.clone(),
|
||||
left: self.left.clone(),
|
||||
trailing: self.trailing.clone(),
|
||||
right: self.right.clone(),
|
||||
bottom: self.bottom.clone(),
|
||||
width: self.width.clone(),
|
||||
height: self.height.clone(),
|
||||
center_x: self.center_x.clone(),
|
||||
center_y: self.center_y.clone(),
|
||||
objc: self.objc.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,37 @@
|
|||
//! A wrapper for `NSLayoutConstraint`, enabling AutoLayout across views. This does a few things
|
||||
//! that might seem weird, but are generally good and rely on the idea that this is all written
|
||||
//! once and used often.
|
||||
//!
|
||||
//! Notably: there are 3 structs for wrapping layout constraints; in practice, you likely don't need to
|
||||
//! care. This is because we want to detect at compile time invalid layout items - i.e, you should
|
||||
//! not be able to attach a left-axis to a top-axis. In Rust this is a bit tricky, but by using
|
||||
//! some `impl Trait`'s in the right places we can mostly hide this detail away.
|
||||
|
||||
pub mod attributes;
|
||||
pub use attributes::*;
|
||||
//! This module contains traits and helpers for layout. By default, standard frame-based layouts
|
||||
//! are supported via the `Layout` trait, which all widgets implement. If you opt in to the
|
||||
//! `AutoLayout` feature, each widget will default to using AutoLayout, which can be beneficial in
|
||||
//! more complicated views that need to deal with differing screen sizes.
|
||||
|
||||
pub mod traits;
|
||||
pub use traits::Layout;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub mod attributes;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub use attributes::*;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub mod constraint;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub use constraint::LayoutConstraint;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub mod dimension;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub use dimension::LayoutAnchorDimension;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub mod horizontal;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub use horizontal::LayoutAnchorX;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub mod vertical;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub use vertical::LayoutAnchorY;
|
||||
|
|
|
@ -71,6 +71,7 @@ pub trait Layout {
|
|||
///
|
||||
/// Cacao defaults this to `false`; if you need to set frame-based layout pieces,
|
||||
/// then you should set this to `true` (or use an appropriate initializer that does it for you).
|
||||
#[cfg(feature = "autolayout")]
|
||||
fn set_translates_autoresizing_mask_into_constraints(&self, translates: bool) {
|
||||
self.with_backing_node(|backing_node| unsafe {
|
||||
let _: () = msg_send![backing_node, setTranslatesAutoresizingMaskIntoConstraints:match translates {
|
||||
|
|
|
@ -96,6 +96,9 @@ pub use objc;
|
|||
pub use url;
|
||||
pub use lazy_static;
|
||||
|
||||
#[cfg(all(feature = "appkit", feature = "uikit", not(feature = "no-intrinsics")))]
|
||||
compile_error!("The \"appkit\" and \"uikit\" features cannot be enabled together. Pick one. :)");
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
#[cfg_attr(docsrs, doc(cfg(target_os = "appkit")))]
|
||||
pub mod appkit;
|
||||
|
|
|
@ -50,7 +50,12 @@ use objc::{class, msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, YES, NO, NSArray, NSString, NSInteger, NSUInteger};
|
||||
use crate::color::Color;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
use crate::layout::Layout;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
use crate::scrollview::ScrollView;
|
||||
use crate::utils::{os, CellFactory, CGSize};
|
||||
use crate::utils::properties::{ObjcProperty, PropertyNullable};
|
||||
|
@ -95,6 +100,8 @@ use std::cell::RefCell;
|
|||
fn common_init(class: *const Class) -> id {
|
||||
unsafe {
|
||||
let tableview: id = msg_send![class, new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![tableview, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
// Let's... make NSTableView into UITableView-ish.
|
||||
|
@ -139,40 +146,51 @@ pub struct ListView<T = ()> {
|
|||
|
||||
/// In AppKit, we need to manage the NSScrollView ourselves. It's a bit
|
||||
/// more old school like that...
|
||||
#[cfg(feature = "appkit")]
|
||||
///
|
||||
/// In iOS, this is a pointer to the UITableView-owned UIScrollView.
|
||||
pub scrollview: ScrollView,
|
||||
|
||||
/// A pointer to the delegate for this view.
|
||||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -201,32 +219,52 @@ impl ListView {
|
|||
|
||||
// For AppKit, we need to use the NSScrollView anchor points, not the NSTableView.
|
||||
// @TODO: Fix this with proper mutable access.
|
||||
#[cfg(feature = "appkit")]
|
||||
#[cfg(all(feature = "appkit", feature = "autolayout"))]
|
||||
let anchor_view: id = scrollview.objc.get(|obj| unsafe {
|
||||
msg_send![obj, self]
|
||||
});
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
let anchor_view: id = view;
|
||||
//#[cfg(all(feature = "uikit", feature = "autolayout"))]
|
||||
//let anchor_view: id = view;
|
||||
|
||||
ListView {
|
||||
cell_factory: CellFactory::new(),
|
||||
menu: PropertyNullable::default(),
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(anchor_view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
scrollview: scrollview
|
||||
scrollview
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -241,8 +279,6 @@ impl<T> ListView<T> where T: ListViewDelegate + 'static {
|
|||
let cell = CellFactory::new();
|
||||
|
||||
unsafe {
|
||||
//let view: id = msg_send![register_view_class_with_delegate::<T>(), new];
|
||||
//let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
let delegate_ptr: *const T = &*delegate;
|
||||
(&mut *view).set_ivar(LISTVIEW_DELEGATE_PTR, delegate_ptr as usize);
|
||||
let _: () = msg_send![view, setDelegate:view];
|
||||
|
@ -261,7 +297,7 @@ impl<T> ListView<T> where T: ListViewDelegate + 'static {
|
|||
};
|
||||
|
||||
// For AppKit, we need to use the NSScrollView anchor points, not the NSTableView.
|
||||
#[cfg(feature = "appkit")]
|
||||
#[cfg(all(feature = "appkit", feature = "autolayout"))]
|
||||
let anchor_view: id = scrollview.objc.get(|obj| unsafe {
|
||||
msg_send![obj, self]
|
||||
});
|
||||
|
@ -273,20 +309,39 @@ impl<T> ListView<T> where T: ListViewDelegate + 'static {
|
|||
cell_factory: cell,
|
||||
menu: PropertyNullable::default(),
|
||||
delegate: None,
|
||||
top: LayoutAnchorY::top(anchor_view),
|
||||
left: LayoutAnchorX::left(anchor_view),
|
||||
leading: LayoutAnchorX::leading(anchor_view),
|
||||
right: LayoutAnchorX::right(anchor_view),
|
||||
trailing: LayoutAnchorX::trailing(anchor_view),
|
||||
bottom: LayoutAnchorY::bottom(anchor_view),
|
||||
width: LayoutAnchorDimension::width(anchor_view),
|
||||
height: LayoutAnchorDimension::height(anchor_view),
|
||||
center_x: LayoutAnchorX::center(anchor_view),
|
||||
center_y: LayoutAnchorY::center(anchor_view),
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(anchor_view),
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
scrollview: scrollview
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(anchor_view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(anchor_view),
|
||||
|
||||
scrollview
|
||||
};
|
||||
|
||||
(&mut delegate).did_load(view.clone_as_handle());
|
||||
|
@ -305,19 +360,38 @@ impl<T> ListView<T> {
|
|||
cell_factory: CellFactory::new(),
|
||||
menu: self.menu.clone(),
|
||||
delegate: None,
|
||||
top: self.top.clone(),
|
||||
leading: self.leading.clone(),
|
||||
left: self.left.clone(),
|
||||
trailing: self.trailing.clone(),
|
||||
right: self.right.clone(),
|
||||
bottom: self.bottom.clone(),
|
||||
width: self.width.clone(),
|
||||
height: self.height.clone(),
|
||||
center_x: self.center_x.clone(),
|
||||
center_y: self.center_y.clone(),
|
||||
objc: self.objc.clone(),
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
|
||||
scrollview: self.scrollview.clone_as_handle()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,13 @@ use objc::{class, msg_send, sel, sel_impl};
|
|||
use crate::foundation::{id, nil, YES, NO, NSArray, NSString};
|
||||
use crate::color::Color;
|
||||
use crate::layer::Layer;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::view::ViewDelegate;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
mod appkit;
|
||||
|
||||
|
@ -74,6 +77,8 @@ pub(crate) static LISTVIEW_ROW_DELEGATE_PTR: &str = "cacaoListViewRowDelegatePtr
|
|||
fn allocate_view(registration_fn: fn() -> *const Class) -> id {
|
||||
unsafe {
|
||||
let view: id = msg_send![registration_fn(), new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -95,33 +100,43 @@ pub struct ListViewRow<T = ()> {
|
|||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -138,17 +153,37 @@ impl ListViewRow {
|
|||
|
||||
ListViewRow {
|
||||
delegate: None,
|
||||
top: LayoutAnchorY::top(view),
|
||||
left: LayoutAnchorX::left(view),
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
right: LayoutAnchorX::right(view),
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,17 +210,37 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
|
|||
|
||||
let view = ListViewRow {
|
||||
delegate: Some(delegate),
|
||||
top: LayoutAnchorY::top(view),
|
||||
left: LayoutAnchorX::left(view),
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
right: LayoutAnchorX::right(view),
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
};
|
||||
|
||||
view
|
||||
|
@ -201,25 +256,43 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
|
|||
pub fn with_boxed(mut delegate: Box<T>) -> ListViewRow<T> {
|
||||
let view = allocate_view(register_listview_row_class_with_delegate::<T>);
|
||||
unsafe {
|
||||
//let view: id = msg_send![register_view_class_with_delegate::<T>(), new];
|
||||
//let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
let ptr: *const T = &*delegate;
|
||||
(&mut *view).set_ivar(LISTVIEW_ROW_DELEGATE_PTR, ptr as usize);
|
||||
};
|
||||
|
||||
let mut view = ListViewRow {
|
||||
delegate: None,
|
||||
top: LayoutAnchorY::top(view),
|
||||
left: LayoutAnchorX::left(view),
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
right: LayoutAnchorX::right(view),
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
};
|
||||
|
||||
(&mut delegate).did_load(view.clone_as_handle());
|
||||
|
@ -237,17 +310,37 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
|
|||
|
||||
ListViewRow {
|
||||
delegate: None,
|
||||
objc: self.objc.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
objc: self.objc.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -262,17 +355,37 @@ impl<T> ListViewRow<T> {
|
|||
delegate: None,
|
||||
is_handle: true,
|
||||
layer: Layer::new(),
|
||||
objc: self.objc.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
objc: self.objc.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! A progress indicator widget.
|
||||
//!
|
||||
//! This control wraps `NSProgressIndicator` on macOS, and
|
||||
//! `UIProgressView+UIActivityIndicatorView` on iOS and tvOS. It operates in two modes: determinate
|
||||
//! This control wraps `NSProgressIndicator` in AppKit, and
|
||||
//! `UIProgressView+UIActivityIndicatorView` in iOS/tvOS. It operates in two modes: determinate
|
||||
//! (where you have a fixed start and end) and indeterminate (infinite; it will go and go until you
|
||||
//! tell it to stop).
|
||||
//!
|
||||
|
@ -19,9 +19,12 @@ use objc::{class, msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, YES, NO, NSUInteger};
|
||||
use crate::color::Color;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
mod enums;
|
||||
pub use enums::ProgressIndicatorStyle;
|
||||
|
||||
|
@ -32,33 +35,43 @@ pub struct ProgressIndicator {
|
|||
pub objc: ObjcProperty,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -75,6 +88,8 @@ impl ProgressIndicator {
|
|||
let view = unsafe {
|
||||
#[cfg(feature = "appkit")]
|
||||
let view: id = msg_send![class!(NSProgressIndicator), new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -84,16 +99,36 @@ impl ProgressIndicator {
|
|||
};
|
||||
|
||||
ProgressIndicator {
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,10 +47,14 @@ use objc::{msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, YES, NO, NSArray, NSString};
|
||||
use crate::color::Color;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
use crate::layout::Layout;
|
||||
use crate::pasteboard::PasteboardType;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
mod appkit;
|
||||
|
||||
|
@ -72,6 +76,8 @@ pub(crate) static SCROLLVIEW_DELEGATE_PTR: &str = "rstScrollViewDelegatePtr";
|
|||
fn allocate_view(registration_fn: fn() -> *const Class) -> id {
|
||||
unsafe {
|
||||
let view: id = msg_send![registration_fn(), new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -97,33 +103,43 @@ pub struct ScrollView<T = ()> {
|
|||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -140,16 +156,37 @@ impl ScrollView {
|
|||
|
||||
ScrollView {
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
}
|
||||
}
|
||||
|
@ -169,16 +206,37 @@ impl<T> ScrollView<T> where T: ScrollViewDelegate + 'static {
|
|||
|
||||
let mut view = ScrollView {
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
};
|
||||
|
||||
|
@ -196,16 +254,37 @@ impl<T> ScrollView<T> {
|
|||
pub(crate) fn clone_as_handle(&self) -> ScrollView {
|
||||
ScrollView {
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
|
||||
objc: self.objc.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,9 +11,12 @@ use objc::{class, msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, BOOL, YES, NO, NSString};
|
||||
use crate::invoker::TargetActionHandler;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::utils::{load, properties::ObjcProperty};
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
/// A wrapper for `NSSwitch`. Holds (retains) pointers for the Objective-C runtime
|
||||
/// where our `NSSwitch` lives.
|
||||
#[derive(Debug)]
|
||||
|
@ -23,33 +26,43 @@ pub struct Switch {
|
|||
handler: Option<TargetActionHandler>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
|
||||
}
|
||||
|
@ -62,24 +75,49 @@ impl Switch {
|
|||
|
||||
let view: id = unsafe {
|
||||
let button: id = msg_send![register_class(), buttonWithTitle:title target:nil action:nil];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![button, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
let _: () = msg_send![button, setButtonType:3];
|
||||
|
||||
button
|
||||
};
|
||||
|
||||
Switch {
|
||||
handler: None,
|
||||
top: LayoutAnchorY::top(view),
|
||||
left: LayoutAnchorX::left(view),
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
right: LayoutAnchorX::right(view),
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
objc: ObjcProperty::retain(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,10 +46,13 @@ use objc::{msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, YES, NO, NSArray, NSInteger, NSUInteger, NSString};
|
||||
use crate::color::Color;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::text::{Font, TextAlign, LineBreakMode};
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
mod appkit;
|
||||
|
||||
|
@ -77,9 +80,10 @@ fn allocate_view(registration_fn: fn() -> *const Class) -> id {
|
|||
msg_send![registration_fn(), labelWithString:&*blank]
|
||||
};
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
#[cfg(feature = "uikit")]
|
||||
let view: id = msg_send![registration_fn(), new];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -141,33 +145,43 @@ pub struct Label<T = ()> {
|
|||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -184,16 +198,37 @@ impl Label {
|
|||
|
||||
Label {
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
objc: ObjcProperty::retain(view),
|
||||
}
|
||||
}
|
||||
|
@ -207,24 +242,43 @@ impl<T> Label<T> where T: LabelDelegate + 'static {
|
|||
|
||||
let label = allocate_view(register_view_class_with_delegate::<T>);
|
||||
unsafe {
|
||||
//let view: id = msg_send![register_view_class_with_delegate::<T>(), new];
|
||||
//let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
let ptr: *const T = &*delegate;
|
||||
(&mut *label).set_ivar(LABEL_DELEGATE_PTR, ptr as usize);
|
||||
};
|
||||
|
||||
let mut label = Label {
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(label),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(label),
|
||||
|
||||
objc: ObjcProperty::retain(label),
|
||||
};
|
||||
|
||||
|
@ -242,16 +296,37 @@ impl<T> Label<T> {
|
|||
pub(crate) fn clone_as_handle(&self) -> Label {
|
||||
Label {
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
|
||||
objc: self.objc.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,12 @@ use objc::{msg_send, sel, sel_impl};
|
|||
use crate::foundation::{id, nil, YES, NO, NSArray, NSString};
|
||||
use crate::color::Color;
|
||||
use crate::layer::Layer;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::{LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
use crate::pasteboard::PasteboardType;
|
||||
|
||||
|
@ -70,6 +73,7 @@ pub use controller::ViewController;
|
|||
|
||||
#[cfg(feature = "appkit")]
|
||||
mod splitviewcontroller;
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
pub use splitviewcontroller::SplitViewController;
|
||||
|
||||
|
@ -100,33 +104,43 @@ pub struct View<T = ()> {
|
|||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -145,6 +159,7 @@ impl View {
|
|||
/// so on. It returns a generic `View<T>`, which the caller can then customize as needed.
|
||||
pub(crate) fn init<T>(view: id) -> View<T> {
|
||||
unsafe {
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![view, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
#[cfg(feature = "appkit")]
|
||||
|
@ -154,15 +169,35 @@ impl View {
|
|||
View {
|
||||
is_handle: false,
|
||||
delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
layer: Layer::wrap(unsafe {
|
||||
|
@ -213,17 +248,37 @@ impl<T> View<T> {
|
|||
delegate: None,
|
||||
is_handle: true,
|
||||
layer: self.layer.clone(),
|
||||
objc: self.objc.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone(),
|
||||
objc: self.objc.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,13 @@ use objc::{class, msg_send, sel, sel_impl};
|
|||
|
||||
use crate::foundation::{id, nil, YES, NO, NSString};
|
||||
use crate::geometry::Rect;
|
||||
use crate::layout::{Layout, LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
use crate::layout::Layout;
|
||||
use crate::layer::Layer;
|
||||
use crate::utils::properties::ObjcProperty;
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
use crate::layout::LayoutAnchorX, LayoutAnchorY, LayoutAnchorDimension};
|
||||
|
||||
mod actions;
|
||||
pub use actions::*;
|
||||
|
||||
|
@ -82,6 +85,7 @@ fn allocate_webview(
|
|||
#[cfg(feature = "appkit")]
|
||||
let _: () = msg_send![webview, setWantsLayer:YES];
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
let _: () = msg_send![webview, setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
if let Some(delegate) = &objc_delegate {
|
||||
|
@ -113,33 +117,43 @@ pub struct WebView<T = ()> {
|
|||
pub delegate: Option<Box<T>>,
|
||||
|
||||
/// A pointer to the Objective-C runtime top layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub top: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub leading: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime left layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub left: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub trailing: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime right layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub right: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub bottom: LayoutAnchorY,
|
||||
|
||||
/// A pointer to the Objective-C runtime width layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub width: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime height layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub height: LayoutAnchorDimension,
|
||||
|
||||
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_x: LayoutAnchorX,
|
||||
|
||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||
#[cfg(feature = "autolayout")]
|
||||
pub center_y: LayoutAnchorY
|
||||
}
|
||||
|
||||
|
@ -167,15 +181,35 @@ impl WebView {
|
|||
is_handle: false,
|
||||
delegate: None,
|
||||
objc_delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: LayoutAnchorY::top(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: LayoutAnchorX::left(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: LayoutAnchorX::leading(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: LayoutAnchorX::right(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: LayoutAnchorX::trailing(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: LayoutAnchorY::bottom(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: LayoutAnchorDimension::width(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: LayoutAnchorDimension::height(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: LayoutAnchorX::center(view),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: LayoutAnchorY::center(view),
|
||||
|
||||
layer: Layer::wrap(unsafe {
|
||||
|
@ -224,20 +258,40 @@ impl<T> WebView<T> {
|
|||
pub(crate) fn clone_as_handle(&self) -> WebView {
|
||||
WebView {
|
||||
delegate: None,
|
||||
top: self.top.clone(),
|
||||
leading: self.leading.clone(),
|
||||
left: self.left.clone(),
|
||||
right: self.right.clone(),
|
||||
is_handle: true,
|
||||
trailing: self.trailing.clone(),
|
||||
bottom: self.bottom.clone(),
|
||||
width: self.width.clone(),
|
||||
height: self.height.clone(),
|
||||
center_x: self.center_x.clone(),
|
||||
center_y: self.center_y.clone(),
|
||||
layer: self.layer.clone(),
|
||||
objc: self.objc.clone(),
|
||||
objc_delegate: None
|
||||
objc_delegate: None,
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
top: self.top.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
leading: self.leading.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
left: self.left.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
right: self.right.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
trailing: self.trailing.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
bottom: self.bottom.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
width: self.width.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
height: self.height.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_x: self.center_x.clone(),
|
||||
|
||||
#[cfg(feature = "autolayout")]
|
||||
center_y: self.center_y.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue