style: cargo fmt with the workspace tab policy (hard_tabs)

Whitespace only; the fork has no own rustfmt.toml so the Oak root
policy applies.
This commit is contained in:
2026-08-11 23:06:13 +08:00
parent 507d7e6e8d
commit af5482d774
318 changed files with 132564 additions and 132170 deletions
+218 -218
View File
@@ -91,8 +91,8 @@ use accesskit::{Action, NodeId, TreeUpdate};
use collections::{FxHashMap, FxHashSet};
use smallvec::SmallVec;
use std::sync::{
Arc,
atomic::{AtomicBool, Ordering},
Arc,
atomic::{AtomicBool, Ordering},
};
/// The fixed AccessKit node ID used for the root of every window's a11y tree.
@@ -100,262 +100,262 @@ pub(crate) const ROOT_NODE_ID: NodeId = NodeId(0);
/// A listener for an accessibility action on a specific node.
pub(crate) type A11yActionListener =
Box<dyn FnMut(Option<&accesskit::ActionData>, &mut Window, &mut App) + 'static>;
Box<dyn FnMut(Option<&accesskit::ActionData>, &mut Window, &mut App) + 'static>;
/// Per-window accessibility state.
///
/// Manages the AccessKit tree that is built each frame and the mappings
/// needed to dispatch incoming action requests back to the right elements.
pub(crate) struct A11y {
/// Whether accessibility has been [forcibly disabled] for this window.
///
/// [forcibly disabled]: crate::Application::new_inaccessible
force_disabled: bool,
/// Whether a11y features have been requested by the system.
///
/// Updated by AccessKit using callbacks provided to the adapter. Can change
/// halfway through a frame.
active_flag: Arc<AtomicBool>,
/// Whether a11y features are active for *this specific frame*.
///
/// At the start of each frame, we load [`Self::active_flag`] (using
/// [`Self::sync_active_flag`]) and use this to determine whether we
/// should construct a [`TreeUpdate`] for this frame. It's important that
/// this value is stable within a frame, because the builder API exposed by
/// this type maintains a stack of nodes and each must be pushed and popped
/// exactly once.
///
/// At the end of the frame, we re-call [`Self::sync_active_flag`] to
/// determine whether we should actually send the finished [`TreeUpdate`].
active_this_frame: bool,
pub(crate) nodes: A11yNodeBuilder,
pub(crate) focus_ids: FxHashMap<NodeId, FocusId>,
pub(crate) node_bounds: FxHashMap<NodeId, Bounds<Pixels>>,
pub(crate) action_listeners: FxHashMap<NodeId, Vec<(Action, A11yActionListener)>>,
/// Whether accessibility has been [forcibly disabled] for this window.
///
/// [forcibly disabled]: crate::Application::new_inaccessible
force_disabled: bool,
/// Whether a11y features have been requested by the system.
///
/// Updated by AccessKit using callbacks provided to the adapter. Can change
/// halfway through a frame.
active_flag: Arc<AtomicBool>,
/// Whether a11y features are active for *this specific frame*.
///
/// At the start of each frame, we load [`Self::active_flag`] (using
/// [`Self::sync_active_flag`]) and use this to determine whether we
/// should construct a [`TreeUpdate`] for this frame. It's important that
/// this value is stable within a frame, because the builder API exposed by
/// this type maintains a stack of nodes and each must be pushed and popped
/// exactly once.
///
/// At the end of the frame, we re-call [`Self::sync_active_flag`] to
/// determine whether we should actually send the finished [`TreeUpdate`].
active_this_frame: bool,
pub(crate) nodes: A11yNodeBuilder,
pub(crate) focus_ids: FxHashMap<NodeId, FocusId>,
pub(crate) node_bounds: FxHashMap<NodeId, Bounds<Pixels>>,
pub(crate) action_listeners: FxHashMap<NodeId, Vec<(Action, A11yActionListener)>>,
}
impl A11y {
pub(crate) fn new(active_flag: Arc<AtomicBool>, force_disabled: bool) -> Self {
Self {
force_disabled,
active_flag,
active_this_frame: false,
nodes: A11yNodeBuilder::new(),
focus_ids: FxHashMap::default(),
node_bounds: FxHashMap::default(),
action_listeners: FxHashMap::default(),
}
}
pub(crate) fn new(active_flag: Arc<AtomicBool>, force_disabled: bool) -> Self {
Self {
force_disabled,
active_flag,
active_this_frame: false,
nodes: A11yNodeBuilder::new(),
focus_ids: FxHashMap::default(),
node_bounds: FxHashMap::default(),
action_listeners: FxHashMap::default(),
}
}
/// Ensures that [`Self::is_active`] returns up to date information.
///
/// See the docs for [`Self::active_flag`] and [`Self::active_this_frame`]
/// for more commentary.
pub(crate) fn sync_active_flag(&mut self) {
self.active_this_frame = !self.force_disabled && self.active_flag.load(Ordering::SeqCst);
}
/// Ensures that [`Self::is_active`] returns up to date information.
///
/// See the docs for [`Self::active_flag`] and [`Self::active_this_frame`]
/// for more commentary.
pub(crate) fn sync_active_flag(&mut self) {
self.active_this_frame = !self.force_disabled && self.active_flag.load(Ordering::SeqCst);
}
pub(crate) fn is_active(&self) -> bool {
self.active_this_frame
}
pub(crate) fn is_active(&self) -> bool {
self.active_this_frame
}
/// Clear per-frame state and push the root node to start a new frame.
pub(crate) fn begin_frame(&mut self) {
self.focus_ids.clear();
self.node_bounds.clear();
self.action_listeners.clear();
self.nodes.begin_frame();
}
/// Clear per-frame state and push the root node to start a new frame.
pub(crate) fn begin_frame(&mut self) {
self.focus_ids.clear();
self.node_bounds.clear();
self.action_listeners.clear();
self.nodes.begin_frame();
}
/// Finalize the tree and produce a [`TreeUpdate`] for the platform adapter.
pub(crate) fn end_frame(&mut self) -> TreeUpdate {
let tree_update = self.nodes.finalize();
/// Finalize the tree and produce a [`TreeUpdate`] for the platform adapter.
pub(crate) fn end_frame(&mut self) -> TreeUpdate {
let tree_update = self.nodes.finalize();
// Zed currently doesn't set any a11y APIs on *any* UI elements, so a
// tree with nodes other than the root indicates a bug in the
// `TreeUpdate`-producing logic.
//
// Remove this when adding aria attributes.
if tree_update.nodes.len() > 1 {
log::warn!(
"expected an empty a11y tree update (only the root node), but got {} nodes; Zed has no accessible UI elements yet",
tree_update.nodes.len()
);
}
// Zed currently doesn't set any a11y APIs on *any* UI elements, so a
// tree with nodes other than the root indicates a bug in the
// `TreeUpdate`-producing logic.
//
// Remove this when adding aria attributes.
if tree_update.nodes.len() > 1 {
log::warn!(
"expected an empty a11y tree update (only the root node), but got {} nodes; Zed has no accessible UI elements yet",
tree_update.nodes.len()
);
}
tree_update
}
tree_update
}
}
pub(crate) struct A11yNodeBuilder {
ids_stack: SmallVec<[NodeId; 16]>,
nodes_stack: SmallVec<[accesskit::Node; 16]>,
/// This is the exact type required by accesskit, so we can't just make it a
/// `HashMap<NodeId, Node>` to remove the need for `seen_ids`
all_nodes: Vec<(NodeId, accesskit::Node)>,
seen_ids: FxHashSet<NodeId>,
focus: NodeId,
#[cfg(debug_assertions)]
has_set_focus: bool,
ids_stack: SmallVec<[NodeId; 16]>,
nodes_stack: SmallVec<[accesskit::Node; 16]>,
/// This is the exact type required by accesskit, so we can't just make it a
/// `HashMap<NodeId, Node>` to remove the need for `seen_ids`
all_nodes: Vec<(NodeId, accesskit::Node)>,
seen_ids: FxHashSet<NodeId>,
focus: NodeId,
#[cfg(debug_assertions)]
has_set_focus: bool,
}
impl A11yNodeBuilder {
fn new() -> Self {
Self {
ids_stack: SmallVec::new(),
nodes_stack: SmallVec::new(),
all_nodes: Vec::new(),
seen_ids: FxHashSet::default(),
focus: ROOT_NODE_ID,
#[cfg(debug_assertions)]
has_set_focus: false,
}
}
fn new() -> Self {
Self {
ids_stack: SmallVec::new(),
nodes_stack: SmallVec::new(),
all_nodes: Vec::new(),
seen_ids: FxHashSet::default(),
focus: ROOT_NODE_ID,
#[cfg(debug_assertions)]
has_set_focus: false,
}
}
/// Push a new node onto the stack. It becomes a child of the current
/// top-of-stack node.
///
/// Returns `true` if the node was successfully pushed.
pub(crate) fn push(&mut self, id: NodeId, node: accesskit::Node) -> bool {
debug_assert!(!self.ids_stack.is_empty(), "push called before push_root");
/// Push a new node onto the stack. It becomes a child of the current
/// top-of-stack node.
///
/// Returns `true` if the node was successfully pushed.
pub(crate) fn push(&mut self, id: NodeId, node: accesskit::Node) -> bool {
debug_assert!(!self.ids_stack.is_empty(), "push called before push_root");
if !self.seen_ids.insert(id) {
debug_assert!(
false,
"Duplicate a11y node id: {id:?}. In a release build, this node would be silently discarded from the a11y tree."
);
// We need to return `false` here because inserting a duplicate
// node will cause a panic in accesskit
return false;
}
if !self.seen_ids.insert(id) {
debug_assert!(
false,
"Duplicate a11y node id: {id:?}. In a release build, this node would be silently discarded from the a11y tree."
);
// We need to return `false` here because inserting a duplicate
// node will cause a panic in accesskit
return false;
}
if let Some(parent) = self.nodes_stack.last_mut() {
parent.push_child(id);
}
self.ids_stack.push(id);
self.nodes_stack.push(node);
true
}
if let Some(parent) = self.nodes_stack.last_mut() {
parent.push_child(id);
}
self.ids_stack.push(id);
self.nodes_stack.push(node);
true
}
/// Pop the current node off the stack and finalize it into the all_nodes
/// list.
pub(crate) fn pop(&mut self) {
debug_assert!(self.ids_stack.len() > 1, "pop would remove the root node");
/// Pop the current node off the stack and finalize it into the all_nodes
/// list.
pub(crate) fn pop(&mut self) {
debug_assert!(self.ids_stack.len() > 1, "pop would remove the root node");
if let (Some(id), Some(node)) = (self.ids_stack.pop(), self.nodes_stack.pop()) {
self.all_nodes.push((id, node));
}
}
if let (Some(id), Some(node)) = (self.ids_stack.pop(), self.nodes_stack.pop()) {
self.all_nodes.push((id, node));
}
}
/// Push the root node to start a new frame.
fn begin_frame(&mut self) {
self.all_nodes.clear();
self.ids_stack.clear();
self.nodes_stack.clear();
self.seen_ids.clear();
#[cfg(debug_assertions)]
{
self.has_set_focus = false;
}
let root_node = accesskit::Node::new(accesskit::Role::Window);
/// Push the root node to start a new frame.
fn begin_frame(&mut self) {
self.all_nodes.clear();
self.ids_stack.clear();
self.nodes_stack.clear();
self.seen_ids.clear();
#[cfg(debug_assertions)]
{
self.has_set_focus = false;
}
let root_node = accesskit::Node::new(accesskit::Role::Window);
self.ids_stack.push(ROOT_NODE_ID);
self.nodes_stack.push(root_node);
self.focus = ROOT_NODE_ID;
}
self.ids_stack.push(ROOT_NODE_ID);
self.nodes_stack.push(root_node);
self.focus = ROOT_NODE_ID;
}
/// Returns whether a node with the given ID has been pushed in this frame.
pub(crate) fn has_node(&self, id: NodeId) -> bool {
id == ROOT_NODE_ID || self.seen_ids.contains(&id)
}
/// Returns whether a node with the given ID has been pushed in this frame.
pub(crate) fn has_node(&self, id: NodeId) -> bool {
id == ROOT_NODE_ID || self.seen_ids.contains(&id)
}
/// Set the focused node for this frame.
pub(crate) fn set_focus(&mut self, id: NodeId) {
#[cfg(debug_assertions)]
{
debug_assert!(
!self.has_set_focus,
"set_focus called more than once in a single frame"
);
self.has_set_focus = true;
}
self.focus = id;
}
/// Set the focused node for this frame.
pub(crate) fn set_focus(&mut self, id: NodeId) {
#[cfg(debug_assertions)]
{
debug_assert!(
!self.has_set_focus,
"set_focus called more than once in a single frame"
);
self.has_set_focus = true;
}
self.focus = id;
}
fn finalize(&mut self) -> TreeUpdate {
// Stack should contain only the root node
debug_assert_eq!(self.ids_stack.len(), 1);
debug_assert_eq!(self.ids_stack[0], ROOT_NODE_ID);
fn finalize(&mut self) -> TreeUpdate {
// Stack should contain only the root node
debug_assert_eq!(self.ids_stack.len(), 1);
debug_assert_eq!(self.ids_stack[0], ROOT_NODE_ID);
if self.ids_stack.len() != 1 {
log::error!(
"a11y: Stack imbalance at end of frame: expected 1 (root), got {}. \
if self.ids_stack.len() != 1 {
log::error!(
"a11y: Stack imbalance at end of frame: expected 1 (root), got {}. \
Some elements may have pushed without popping.",
self.ids_stack.len()
);
}
self.ids_stack.len()
);
}
// Pop remaining nodes (should just be the root).
while !self.ids_stack.is_empty() {
if let (Some(id), Some(node)) = (self.ids_stack.pop(), self.nodes_stack.pop()) {
self.all_nodes.push((id, node));
}
}
// Pop remaining nodes (should just be the root).
while !self.ids_stack.is_empty() {
if let (Some(id), Some(node)) = (self.ids_stack.pop(), self.nodes_stack.pop()) {
self.all_nodes.push((id, node));
}
}
let nodes = std::mem::take(&mut self.all_nodes);
let update = TreeUpdate {
nodes,
tree: Some(accesskit::Tree::new(ROOT_NODE_ID)),
tree_id: accesskit::TreeId::ROOT,
focus: self.focus,
};
let nodes = std::mem::take(&mut self.all_nodes);
let update = TreeUpdate {
nodes,
tree: Some(accesskit::Tree::new(ROOT_NODE_ID)),
tree_id: accesskit::TreeId::ROOT,
focus: self.focus,
};
Self::repair_tree_update(update)
}
Self::repair_tree_update(update)
}
/// Accesskit panics on invalid [`TreeUpdate`]s. This function defensively
/// checks invariants that accesskit panics on, and tries to fix them.
fn repair_tree_update(mut update: TreeUpdate) -> TreeUpdate {
let node_ids: FxHashSet<NodeId> = update.nodes.iter().map(|(id, _)| *id).collect();
/// Accesskit panics on invalid [`TreeUpdate`]s. This function defensively
/// checks invariants that accesskit panics on, and tries to fix them.
fn repair_tree_update(mut update: TreeUpdate) -> TreeUpdate {
let node_ids: FxHashSet<NodeId> = update.nodes.iter().map(|(id, _)| *id).collect();
// Focus must point to a node in the tree.
if !node_ids.contains(&update.focus) {
log::error!(
"a11y: Focused node {:?} is not in the tree ({} nodes). \
// Focus must point to a node in the tree.
if !node_ids.contains(&update.focus) {
log::error!(
"a11y: Focused node {:?} is not in the tree ({} nodes). \
Falling back to root. This is a bug in the a11y tree builder.",
update.focus,
update.nodes.len()
);
update.focus = ROOT_NODE_ID;
}
update.focus,
update.nodes.len()
);
update.focus = ROOT_NODE_ID;
}
// Every child reference must point to a node in the update.
for (id, node) in &mut update.nodes {
let has_invalid_child = node
.children()
.iter()
.any(|child_id| !node_ids.contains(child_id));
if has_invalid_child {
let children = node.children();
let invalid_count = children
.iter()
.filter(|child_id| !node_ids.contains(child_id))
.count();
log::error!(
"a11y: Node {:?} references {} children not present in the tree. \
// Every child reference must point to a node in the update.
for (id, node) in &mut update.nodes {
let has_invalid_child = node
.children()
.iter()
.any(|child_id| !node_ids.contains(child_id));
if has_invalid_child {
let children = node.children();
let invalid_count = children
.iter()
.filter(|child_id| !node_ids.contains(child_id))
.count();
log::error!(
"a11y: Node {:?} references {} children not present in the tree. \
Stripping invalid child references.",
id,
invalid_count
);
let valid: Vec<NodeId> = children
.iter()
.copied()
.filter(|child_id| node_ids.contains(child_id))
.collect();
node.set_children(valid);
}
}
id,
invalid_count
);
let valid: Vec<NodeId> = children
.iter()
.copied()
.filter(|child_id| node_ids.contains(child_id))
.collect();
node.set_children(valid);
}
}
update
}
update
}
}
+167 -167
View File
@@ -3,9 +3,9 @@ use std::ops::Deref;
use futures::channel::oneshot;
use crate::{
AnyView, App, AppContext as _, Context, Entity, EventEmitter, FocusHandle, Focusable,
InteractiveElement, IntoElement, ParentElement, PromptButton, PromptLevel, Render,
StatefulInteractiveElement, Styled, div, opaque_grey, white,
AnyView, App, AppContext as _, Context, Entity, EventEmitter, FocusHandle, Focusable,
InteractiveElement, IntoElement, ParentElement, PromptButton, PromptLevel, Render,
StatefulInteractiveElement, Styled, div, opaque_grey, white,
};
use super::Window;
@@ -22,211 +22,211 @@ impl<V: EventEmitter<PromptResponse> + Focusable> Prompt for V {}
/// A handle to a prompt that can be used to interact with it.
pub struct PromptHandle {
sender: oneshot::Sender<usize>,
sender: oneshot::Sender<usize>,
}
impl PromptHandle {
pub(crate) fn new(sender: oneshot::Sender<usize>) -> Self {
Self { sender }
}
pub(crate) fn new(sender: oneshot::Sender<usize>) -> Self {
Self { sender }
}
/// Construct a new prompt handle from a view of the appropriate types
pub fn with_view<V: Prompt + Render>(
self,
view: Entity<V>,
window: &mut Window,
cx: &mut App,
) -> RenderablePromptHandle {
let mut sender = Some(self.sender);
let previous_focus = window.focused(cx);
let window_handle = window.window_handle();
cx.subscribe(&view, move |_: Entity<V>, e: &PromptResponse, cx| {
if let Some(sender) = sender.take() {
sender.send(e.0).ok();
window_handle
.update(cx, |_, window, cx| {
window.prompt.take();
if let Some(previous_focus) = &previous_focus {
window.focus(previous_focus, cx);
}
})
.ok();
}
})
.detach();
/// Construct a new prompt handle from a view of the appropriate types
pub fn with_view<V: Prompt + Render>(
self,
view: Entity<V>,
window: &mut Window,
cx: &mut App,
) -> RenderablePromptHandle {
let mut sender = Some(self.sender);
let previous_focus = window.focused(cx);
let window_handle = window.window_handle();
cx.subscribe(&view, move |_: Entity<V>, e: &PromptResponse, cx| {
if let Some(sender) = sender.take() {
sender.send(e.0).ok();
window_handle
.update(cx, |_, window, cx| {
window.prompt.take();
if let Some(previous_focus) = &previous_focus {
window.focus(previous_focus, cx);
}
})
.ok();
}
})
.detach();
window.focus(&view.focus_handle(cx), cx);
window.focus(&view.focus_handle(cx), cx);
RenderablePromptHandle {
view: Box::new(view),
}
}
RenderablePromptHandle {
view: Box::new(view),
}
}
}
/// A prompt handle capable of being rendered in a window.
pub struct RenderablePromptHandle {
pub(crate) view: Box<dyn PromptViewHandle>,
pub(crate) view: Box<dyn PromptViewHandle>,
}
/// Use this function in conjunction with [App::set_prompt_builder] to force
/// GPUI to always use the fallback prompt renderer.
pub fn fallback_prompt_renderer(
level: PromptLevel,
message: &str,
detail: Option<&str>,
actions: &[PromptButton],
handle: PromptHandle,
window: &mut Window,
cx: &mut App,
level: PromptLevel,
message: &str,
detail: Option<&str>,
actions: &[PromptButton],
handle: PromptHandle,
window: &mut Window,
cx: &mut App,
) -> RenderablePromptHandle {
let renderer = cx.new(|cx| FallbackPromptRenderer {
_level: level,
message: message.to_string(),
detail: detail.map(ToString::to_string),
actions: actions.to_vec(),
focus: cx.focus_handle(),
});
let renderer = cx.new(|cx| FallbackPromptRenderer {
_level: level,
message: message.to_string(),
detail: detail.map(ToString::to_string),
actions: actions.to_vec(),
focus: cx.focus_handle(),
});
handle.with_view(renderer, window, cx)
handle.with_view(renderer, window, cx)
}
/// The default GPUI fallback for rendering prompts, when the platform doesn't support it.
pub struct FallbackPromptRenderer {
_level: PromptLevel,
message: String,
detail: Option<String>,
actions: Vec<PromptButton>,
focus: FocusHandle,
_level: PromptLevel,
message: String,
detail: Option<String>,
actions: Vec<PromptButton>,
focus: FocusHandle,
}
impl Render for FallbackPromptRenderer {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let prompt = div()
.cursor_default()
.track_focus(&self.focus)
.w_72()
.bg(white())
.rounded_lg()
.overflow_hidden()
.p_3()
.child(
div()
.w_full()
.flex()
.flex_row()
.justify_around()
.child(div().overflow_hidden().child(self.message.clone())),
)
.children(self.detail.clone().map(|detail| {
div()
.w_full()
.flex()
.flex_row()
.justify_around()
.text_sm()
.mb_2()
.child(div().child(detail))
}))
.children(self.actions.iter().enumerate().map(|(ix, action)| {
div()
.flex()
.flex_row()
.justify_around()
.border_1()
.border_color(opaque_grey(0.2, 0.5))
.mt_1()
.rounded_xs()
.cursor_pointer()
.text_sm()
.child(action.label().clone())
.id(ix)
.on_click(cx.listener(move |_, _, _, cx| {
cx.emit(PromptResponse(ix));
cx.stop_propagation();
}))
}));
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let prompt = div()
.cursor_default()
.track_focus(&self.focus)
.w_72()
.bg(white())
.rounded_lg()
.overflow_hidden()
.p_3()
.child(
div()
.w_full()
.flex()
.flex_row()
.justify_around()
.child(div().overflow_hidden().child(self.message.clone())),
)
.children(self.detail.clone().map(|detail| {
div()
.w_full()
.flex()
.flex_row()
.justify_around()
.text_sm()
.mb_2()
.child(div().child(detail))
}))
.children(self.actions.iter().enumerate().map(|(ix, action)| {
div()
.flex()
.flex_row()
.justify_around()
.border_1()
.border_color(opaque_grey(0.2, 0.5))
.mt_1()
.rounded_xs()
.cursor_pointer()
.text_sm()
.child(action.label().clone())
.id(ix)
.on_click(cx.listener(move |_, _, _, cx| {
cx.emit(PromptResponse(ix));
cx.stop_propagation();
}))
}));
div()
.size_full()
.child(
div()
.size_full()
.bg(opaque_grey(0.5, 0.6))
.absolute()
.top_0()
.left_0(),
)
.child(
div()
.size_full()
.absolute()
.top_0()
.left_0()
.flex()
.flex_col()
.justify_around()
.child(
div()
.w_full()
.flex()
.flex_row()
.justify_around()
.child(prompt),
),
)
}
div()
.size_full()
.child(
div()
.size_full()
.bg(opaque_grey(0.5, 0.6))
.absolute()
.top_0()
.left_0(),
)
.child(
div()
.size_full()
.absolute()
.top_0()
.left_0()
.flex()
.flex_col()
.justify_around()
.child(
div()
.w_full()
.flex()
.flex_row()
.justify_around()
.child(prompt),
),
)
}
}
impl EventEmitter<PromptResponse> for FallbackPromptRenderer {}
impl Focusable for FallbackPromptRenderer {
fn focus_handle(&self, _: &crate::App) -> FocusHandle {
self.focus.clone()
}
fn focus_handle(&self, _: &crate::App) -> FocusHandle {
self.focus.clone()
}
}
pub(crate) trait PromptViewHandle {
fn any_view(&self) -> AnyView;
fn any_view(&self) -> AnyView;
}
impl<V: Prompt + Render> PromptViewHandle for Entity<V> {
fn any_view(&self) -> AnyView {
self.clone().into()
}
fn any_view(&self) -> AnyView {
self.clone().into()
}
}
pub(crate) enum PromptBuilder {
Default,
Custom(
Box<
dyn Fn(
PromptLevel,
&str,
Option<&str>,
&[PromptButton],
PromptHandle,
&mut Window,
&mut App,
) -> RenderablePromptHandle,
>,
),
Default,
Custom(
Box<
dyn Fn(
PromptLevel,
&str,
Option<&str>,
&[PromptButton],
PromptHandle,
&mut Window,
&mut App,
) -> RenderablePromptHandle,
>,
),
}
impl Deref for PromptBuilder {
type Target = dyn Fn(
PromptLevel,
&str,
Option<&str>,
&[PromptButton],
PromptHandle,
&mut Window,
&mut App,
) -> RenderablePromptHandle;
type Target = dyn Fn(
PromptLevel,
&str,
Option<&str>,
&[PromptButton],
PromptHandle,
&mut Window,
&mut App,
) -> RenderablePromptHandle;
fn deref(&self) -> &Self::Target {
match self {
Self::Default => &fallback_prompt_renderer,
Self::Custom(f) => f.as_ref(),
}
}
fn deref(&self) -> &Self::Target {
match self {
Self::Default => &fallback_prompt_renderer,
Self::Custom(f) => f.as_ref(),
}
}
}