Skip to main content

i_slint_core/
lib.rs

1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4// cSpell: ignore sharedvector textlayout
5
6#![doc = include_str!("README.md")]
7#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
8#![cfg_attr(docsrs, feature(doc_cfg))]
9#![deny(unsafe_code)]
10#![allow(clippy::missing_safety_doc)] // FFI surface has many exported unsafe entry points
11#![cfg_attr(slint_nightly_test, feature(non_exhaustive_omitted_patterns_lint))]
12#![cfg_attr(slint_nightly_test, warn(non_exhaustive_omitted_patterns))]
13#![no_std]
14#![debugger_visualizer(gdb_script_file = "gdb_pretty_printers.py")]
15
16extern crate alloc;
17#[cfg(feature = "std")]
18extern crate std;
19
20#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
21pub mod unsafe_single_threaded;
22#[cfg(all(not(feature = "std"), not(feature = "unsafe-single-threaded")))]
23compile_error!(
24    "At least one of the following feature need to be enabled: `std` or `unsafe-single-threaded`"
25);
26pub use crate::items::OperatingSystemType;
27#[cfg(all(not(feature = "std"), feature = "unsafe-single-threaded"))]
28pub use crate::unsafe_single_threaded::thread_local;
29#[cfg(feature = "std")]
30pub use std::thread_local;
31
32pub mod accessibility;
33pub mod animations;
34pub mod api;
35pub mod callbacks;
36pub mod component_factory;
37pub mod context;
38pub mod date_time;
39pub mod future;
40pub mod graphics;
41pub mod input;
42pub mod item_focus;
43pub mod item_rendering;
44pub mod item_tree;
45pub mod items;
46pub mod layout;
47pub mod lengths;
48pub mod menus;
49pub mod model;
50pub mod partial_renderer;
51pub mod platform;
52pub mod properties;
53pub mod renderer;
54#[cfg(feature = "rtti")]
55pub mod rtti;
56pub mod sharedvector;
57pub mod slice;
58pub mod string;
59pub mod styled_text;
60pub mod tests;
61pub mod textlayout;
62pub mod timers;
63pub mod translations;
64pub mod window;
65
66#[doc(inline)]
67pub use string::SharedString;
68
69#[doc(inline)]
70pub use sharedvector::SharedVector;
71
72#[doc(inline)]
73pub use graphics::{ImageInner, StaticTextures};
74
75#[doc(inline)]
76pub use properties::Property;
77
78#[doc(inline)]
79pub use callbacks::Callback;
80
81#[doc(inline)]
82pub use graphics::Color;
83
84#[doc(inline)]
85pub use graphics::Brush;
86
87#[doc(inline)]
88pub use graphics::RgbaColor;
89
90#[cfg(feature = "std")]
91#[doc(inline)]
92pub use graphics::PathData;
93
94#[doc(inline)]
95pub use graphics::BorderRadius;
96
97pub use context::{SlintContext, with_global_context};
98
99#[cfg(not(slint_int_coord))]
100pub type Coord = f32;
101#[cfg(slint_int_coord)]
102pub type Coord = i32;
103
104/// This type is not exported from the public API crate, so function having this
105/// parameter cannot be called from the public API without naming it
106#[derive(Debug, Clone, Copy, PartialEq, Eq)]
107pub struct InternalToken;
108
109#[cfg(feature = "std")]
110thread_local!(
111    /// Permit testing code to force an OS type
112    pub static OPERATING_SYSTEM_OVERRIDE: core::cell::Cell<Option<OperatingSystemType>> =
113        Default::default();
114);
115
116#[cfg(not(target_family = "wasm"))]
117pub fn detect_operating_system() -> OperatingSystemType {
118    #[cfg(feature = "std")]
119    if let Some(os_override) = OPERATING_SYSTEM_OVERRIDE.with(|os_override| os_override.get()) {
120        return os_override;
121    }
122
123    if cfg!(target_os = "android") {
124        OperatingSystemType::Android
125    } else if cfg!(target_os = "ios") {
126        OperatingSystemType::Ios
127    } else if cfg!(target_os = "macos") {
128        OperatingSystemType::Macos
129    } else if cfg!(target_os = "windows") {
130        OperatingSystemType::Windows
131    } else if cfg!(target_os = "linux") {
132        OperatingSystemType::Linux
133    } else {
134        OperatingSystemType::Other
135    }
136}
137
138#[cfg(target_family = "wasm")]
139pub fn detect_operating_system() -> OperatingSystemType {
140    if let Some(os_override) = OPERATING_SYSTEM_OVERRIDE.with(|os_override| os_override.get()) {
141        return os_override;
142    }
143
144    let mut user_agent =
145        web_sys::window().and_then(|w| w.navigator().user_agent().ok()).unwrap_or_default();
146    user_agent.make_ascii_lowercase();
147    let mut platform =
148        web_sys::window().and_then(|w| w.navigator().platform().ok()).unwrap_or_default();
149    platform.make_ascii_lowercase();
150
151    if user_agent.contains("ipad") || user_agent.contains("iphone") {
152        OperatingSystemType::Ios
153    } else if user_agent.contains("android") {
154        OperatingSystemType::Android
155    } else if platform.starts_with("mac") {
156        OperatingSystemType::Macos
157    } else if platform.starts_with("win") {
158        OperatingSystemType::Windows
159    } else if platform.starts_with("linux") {
160        OperatingSystemType::Linux
161    } else {
162        OperatingSystemType::Other
163    }
164}
165
166/// Returns true if the current platform is an Apple platform (macOS, iOS, iPadOS)
167pub fn is_apple_platform() -> bool {
168    matches!(detect_operating_system(), OperatingSystemType::Macos | OperatingSystemType::Ios)
169}
170
171pub fn open_url(url: &str, window: &crate::api::Window) -> Result<(), crate::api::PlatformError> {
172    crate::window::WindowInner::from_pub(window).context().platform().open_url(url)
173}