#[macro_export]
macro_rules! text {
($fmt:literal $(, $arg:expr)* $(,)?) => {
$crate::view::text(&::std::format!($fmt $(, $arg)*))
};
}
#[macro_export]
macro_rules! image {
($fmt:literal $(, $arg:expr)* $(,)?) => {
$crate::view::image(&::std::format!($fmt $(, $arg)*))
};
}
#[macro_export]
macro_rules! vstack {
(spacing: $spacing:expr; $($child:expr),* $(,)?) => {
$crate::view::vstack_spacing(
&[$($crate::view::IntoView::into_view($child)),*],
$spacing,
)
};
($($child:expr),* $(,)?) => {
$crate::view::vstack(&[$($crate::view::IntoView::into_view($child)),*])
};
}
#[macro_export]
macro_rules! hstack {
(spacing: $spacing:expr; $($child:expr),* $(,)?) => {
$crate::view::hstack_spacing(
&[$($crate::view::IntoView::into_view($child)),*],
$spacing,
)
};
($($child:expr),* $(,)?) => {
$crate::view::hstack(&[$($crate::view::IntoView::into_view($child)),*])
};
}
#[macro_export]
macro_rules! zstack {
(alignment: $alignment:expr; $($child:expr),* $(,)?) => {
$crate::view::zstack_aligned(
&[$($crate::view::IntoView::into_view($child)),*],
$alignment,
)
};
($($child:expr),* $(,)?) => {
$crate::view::zstack(&[$($crate::view::IntoView::into_view($child)),*])
};
}
#[macro_export]
macro_rules! lazy_vstack {
($($child:expr),* $(,)?) => {
$crate::view::lazy_vstack(&[$($crate::view::IntoView::into_view($child)),*])
};
}
#[macro_export]
macro_rules! lazy_hstack {
($($child:expr),* $(,)?) => {
$crate::view::lazy_hstack(&[$($crate::view::IntoView::into_view($child)),*])
};
}
#[macro_export]
macro_rules! grid_row {
($($cell:expr),* $(,)?) => {
$crate::view::grid_row(&[$($crate::view::IntoView::into_view($cell)),*])
};
}
#[macro_export]
macro_rules! grid {
($($row:expr),* $(,)?) => {
$crate::view::grid(&[$($row),*])
};
}
#[macro_export]
macro_rules! laid_out {
($layout:expr, $($child:expr),* $(,)?) => {
$crate::view::laid_out(&$layout, &[$($child),*])
};
}
#[macro_export]
macro_rules! foreach {
($range:expr, $body:expr) => {
$crate::view::for_each($range, $body)
};
}
#[macro_export]
macro_rules! view_if {
($cond:expr, $then:expr $(,)?) => {
$crate::view::conditional(
$cond,
$crate::view::IntoView::into_view($then),
$crate::view::empty(),
)
};
($cond:expr, $then:expr, $else:expr $(,)?) => {
$crate::view::conditional(
$cond,
$crate::view::IntoView::into_view($then),
$crate::view::IntoView::into_view($else),
)
};
}
#[macro_export]
macro_rules! list {
($($child:expr),* $(,)?) => {
$crate::view::list($crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! form {
($($child:expr),* $(,)?) => {
$crate::view::form($crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! section {
(header: $header:expr, footer: $footer:expr; $($child:expr),* $(,)?) => {
$crate::view::section_titled_footer(
$crate::view::IntoView::into_view($header),
$crate::view::IntoView::into_view($footer),
$crate::view::tuple_view(&[$($crate::view::IntoView::into_view($child)),*]),
)
};
(footer: $footer:expr; $($child:expr),* $(,)?) => {
$crate::view::section_footer(
$crate::view::IntoView::into_view($footer),
$crate::view::tuple_view(&[$($crate::view::IntoView::into_view($child)),*]),
)
};
(header: $header:expr; $($child:expr),* $(,)?) => {
$crate::view::section_titled(
$crate::view::IntoView::into_view($header),
$crate::view::tuple_view(&[$($crate::view::IntoView::into_view($child)),*]),
)
};
($($child:expr),* $(,)?) => {
$crate::view::section($crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! group {
($($child:expr),* $(,)?) => {
$crate::view::group($crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! control_group {
($($child:expr),* $(,)?) => {
$crate::view::control_group($crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! tab_view {
($($child:expr),* $(,)?) => {
$crate::view::tab_view($crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! tabs {
($($tab:expr),* $(,)?) => {
$crate::view::tab_view_tabs(vec![$($tab),*])
};
}
#[macro_export]
macro_rules! menu {
($label:expr, $($child:expr),* $(,)?) => {
$crate::view::menu($label, $crate::view::tuple_view(
&[$($crate::view::IntoView::into_view($child)),*],
))
};
}
#[macro_export]
macro_rules! picker_bound {
($title:expr, $state:expr, $($row:expr),* $(,)?) => {
$crate::view::picker_bound(
$title,
$state,
$crate::view::tuple_view(&[$($crate::view::IntoView::into_view($row)),*]),
)
};
}
#[macro_export]
macro_rules! picker {
($title:expr, $selection:expr, $($row:expr),* $(,)?) => {
$crate::view::picker(
$title,
$selection,
$crate::view::tuple_view(&[$($crate::view::IntoView::into_view($row)),*]),
)
};
}
macro_rules! swift_statics {
(
$(#[$meta:meta])*
$vis:vis enum $name:ident {
$($(#[$vmeta:meta])* $variant:ident = $symbol:expr),* $(,)?
}
) => {
$(#[$meta])*
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
$vis enum $name {
$($(#[$vmeta])* $variant),*
}
impl $name {
#[allow(unused_doc_comments)]
pub(crate) fn getter(self) -> &'static core::ffi::CStr {
match self {
$($(#[$vmeta])* Self::$variant => $symbol),*
}
}
#[allow(dead_code)]
pub(crate) fn resolved(self) -> *const core::ffi::c_void {
use std::sync::atomic::{AtomicUsize, Ordering};
const N: usize = [$(stringify!($variant)),*].len();
static CACHE: [AtomicUsize; N] = [const { AtomicUsize::new(0) }; N];
let slot = &CACHE[self as usize];
let v = slot.load(Ordering::Relaxed);
if v != 0 {
$crate::resolve::note(self.getter());
return v as *const core::ffi::c_void;
}
let p = $crate::resolve::require(self.getter());
slot.store(p as usize, Ordering::Relaxed);
p
}
}
};
}
#[macro_export]
macro_rules! scenes {
($($clause:tt)*) => {
$crate::scenes_build!(@scene [] $($clause)*)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! scenes_build {
(@scene [$($s:expr),* $(,)?] commands { $($c:tt)* }) => {
$crate::scene::commands(
$crate::scene::group(::std::vec![$($s),*]),
$crate::scenes_build!(@commands [] $($c)*),
)
};
(@scene [$($s:expr),* $(,)?] window_group $body:block $($rest:tt)*) => {
$crate::scenes_build!(@scene [$($s,)* $crate::scene::window_group(move || $body)] $($rest)*)
};
(@scene [$($s:expr),* $(,)?] settings $body:block $($rest:tt)*) => {
$crate::scenes_build!(@scene [$($s,)* $crate::scene::settings(move || $body)] $($rest)*)
};
(@scene [$($s:expr),* $(,)?] window($title:expr, $id:expr) $body:block $($rest:tt)*) => {
$crate::scenes_build!(@scene [$($s,)* $crate::scene::window($title, $id, move || $body)] $($rest)*)
};
(@scene [$($s:expr),* $(,)?] menu_bar_extra($title:expr, $image:expr) $body:block $($rest:tt)*) => {
$crate::scenes_build!(@scene [$($s,)* $crate::scene::menu_bar_extra($title, $image, move || $body)] $($rest)*)
};
(@scene [$($s:expr),* $(,)?]) => {
$crate::scene::group(::std::vec![$($s),*])
};
(@commands [$($c:expr),* $(,)?] menu($title:expr) $body:block $($rest:tt)*) => {
$crate::scenes_build!(@commands [$($c,)* $crate::scene::command_menu($title, move || $body)] $($rest)*)
};
(@commands [$($c:expr),* $(,)?] replacing($place:ident) $body:block $($rest:tt)*) => {
$crate::scenes_build!(@commands [$($c,)* $crate::scene::command_group(
$crate::scene::CommandPlacement::$place,
$crate::scene::Relative::Replacing,
move || $body,
)] $($rest)*)
};
(@commands [$($c:expr),* $(,)?] after($place:ident) $body:block $($rest:tt)*) => {
$crate::scenes_build!(@commands [$($c,)* $crate::scene::command_group(
$crate::scene::CommandPlacement::$place,
$crate::scene::Relative::After,
move || $body,
)] $($rest)*)
};
(@commands [$($c:expr),* $(,)?] before($place:ident) $body:block $($rest:tt)*) => {
$crate::scenes_build!(@commands [$($c,)* $crate::scene::command_group(
$crate::scene::CommandPlacement::$place,
$crate::scene::Relative::Before,
move || $body,
)] $($rest)*)
};
(@commands [$($c:expr),* $(,)?]) => { ::std::vec![$($c),*] };
}
#[macro_export]
macro_rules! environment_keys {
($(
$(#[$meta:meta])*
$name:ident : $ty:ty = $default:expr
),* $(,)?) => {$(
$(#[$meta])*
pub fn $name() -> &'static $crate::views::CustomEnvKey<$ty> {
static KEY: ::std::sync::OnceLock<$crate::views::CustomEnvKey<$ty>> =
::std::sync::OnceLock::new();
KEY.get_or_init(|| {
$crate::views::env_key(
concat!(module_path!(), "::", stringify!($name)),
$default,
)
})
}
)*};
}
#[macro_export]
macro_rules! container_keys {
($(
$(#[$meta:meta])*
$name:ident : $ty:ty = $default:expr
),* $(,)?) => {$(
$(#[$meta])*
pub fn $name() -> &'static $crate::views::CustomContainerKey<$ty> {
static KEY: ::std::sync::OnceLock<$crate::views::CustomContainerKey<$ty>> =
::std::sync::OnceLock::new();
KEY.get_or_init(|| {
$crate::views::container_key(
concat!(module_path!(), "::", stringify!($name)),
$default,
)
})
}
)*};
}
#[macro_export]
macro_rules! focused_keys {
($(
$(#[$meta:meta])*
$name:ident : $ty:ty
),* $(,)?) => {$(
$(#[$meta])*
pub fn $name() -> &'static $crate::views::FocusKey<$ty> {
static KEY: ::std::sync::OnceLock<$crate::views::FocusKey<$ty>> =
::std::sync::OnceLock::new();
KEY.get_or_init(|| {
$crate::views::focus_key(concat!(module_path!(), "::", stringify!($name)))
})
}
)*};
}
#[macro_export]
macro_rules! observable {
($(
$(#[$meta:meta])*
$vis:vis $name:ident {
$(
$(#[$field_meta:meta])*
$field:ident : $ty:ty = $default:expr
),* $(,)?
}
)*) => {$(
$(#[$meta])*
$vis struct $name {
model: $crate::observable::Model,
$(
$(#[$field_meta])*
pub $field: $crate::observable::Property<$ty>,
)*
}
impl $name {
pub fn new() -> Self {
let model = $crate::observable::object();
$name {
$($field: model.property(
concat!(module_path!(), "::", stringify!($name), ".", stringify!($field)),
$default,
),)*
model,
}
}
pub fn shared() -> &'static Self {
static SHARED: ::std::sync::OnceLock<$name> = ::std::sync::OnceLock::new();
SHARED.get_or_init($name::new)
}
pub fn as_model(&self) -> &$crate::observable::Model {
&self.model
}
}
impl ::core::default::Default for $name {
fn default() -> Self {
Self::new()
}
}
)*};
}