parent
a19826af2b
commit
a176408d81
11 changed files with 203 additions and 80 deletions
|
|
@ -505,7 +505,11 @@ pub fn open_new(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for StoryWorkspace {
|
impl Render for StoryWorkspace {
|
||||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let sheet_layer = Root::render_sheet_layer(window, cx);
|
||||||
|
let dialog_layer = Root::render_dialog_layer(window, cx);
|
||||||
|
let notification_layer = Root::render_notification_layer(window, cx);
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.id("story-workspace")
|
.id("story-workspace")
|
||||||
.on_action(cx.listener(Self::on_action_add_panel))
|
.on_action(cx.listener(Self::on_action_add_panel))
|
||||||
|
|
@ -517,6 +521,9 @@ impl Render for StoryWorkspace {
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.child(self.title_bar.clone())
|
.child(self.title_bar.clone())
|
||||||
.child(self.dock_area.clone())
|
.child(self.dock_area.clone())
|
||||||
|
.children(sheet_layer)
|
||||||
|
.children(dialog_layer)
|
||||||
|
.children(notification_layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -409,8 +409,13 @@ pub fn open_new(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for StoryTiles {
|
impl Render for StoryTiles {
|
||||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let sheet_layer = Root::render_sheet_layer(window, cx);
|
||||||
|
let dialog_layer = Root::render_dialog_layer(window, cx);
|
||||||
|
let notification_layer = Root::render_notification_layer(window, cx);
|
||||||
|
|
||||||
div()
|
div()
|
||||||
|
.font_family(".SystemUIFont")
|
||||||
.relative()
|
.relative()
|
||||||
.size_full()
|
.size_full()
|
||||||
.flex()
|
.flex()
|
||||||
|
|
@ -419,6 +424,9 @@ impl Render for StoryTiles {
|
||||||
.text_color(cx.theme().foreground)
|
.text_color(cx.theme().foreground)
|
||||||
.child(TitleBar::new().child(div().flex().items_center().child("Story Tiles")))
|
.child(TitleBar::new().child(div().flex().items_center().child("Story Tiles")))
|
||||||
.child(self.dock_area.clone())
|
.child(self.dock_area.clone())
|
||||||
|
.children(sheet_layer)
|
||||||
|
.children(dialog_layer)
|
||||||
|
.children(notification_layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ pub fn create_new_window_with_size<F, E>(
|
||||||
let view = crate_view_fn(window, cx);
|
let view = crate_view_fn(window, cx);
|
||||||
let root = cx.new(|cx| StoryRoot::new(title.clone(), view, window, cx));
|
let root = cx.new(|cx| StoryRoot::new(title.clone(), view, window, cx));
|
||||||
|
|
||||||
cx.new(|cx| Root::new(root.into(), window, cx).text_base())
|
cx.new(|cx| Root::new(root.into(), window, cx))
|
||||||
})
|
})
|
||||||
.expect("failed to open window");
|
.expect("failed to open window");
|
||||||
|
|
||||||
|
|
@ -261,13 +261,22 @@ impl StoryRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for StoryRoot {
|
impl Render for StoryRoot {
|
||||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
div().size_full().child(
|
let sheet_layer = Root::render_sheet_layer(window, cx);
|
||||||
v_flex()
|
let dialog_layer = Root::render_dialog_layer(window, cx);
|
||||||
.size_full()
|
let notification_layer = Root::render_notification_layer(window, cx);
|
||||||
.child(self.title_bar.clone())
|
|
||||||
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
div()
|
||||||
)
|
.size_full()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.size_full()
|
||||||
|
.child(self.title_bar.clone())
|
||||||
|
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
||||||
|
)
|
||||||
|
.children(sheet_layer)
|
||||||
|
.children(dialog_layer)
|
||||||
|
.children(notification_layer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -324,8 +324,8 @@ impl Render for Notification {
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.absolute()
|
.absolute()
|
||||||
.top_1p5()
|
.top_3p5()
|
||||||
.right_1p5()
|
.right_3p5()
|
||||||
.invisible()
|
.invisible()
|
||||||
.group_hover("", |this| this.visible())
|
.group_hover("", |this| this.visible())
|
||||||
.child(
|
.child(
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ use crate::{
|
||||||
input::InputState,
|
input::InputState,
|
||||||
notification::{Notification, NotificationList},
|
notification::{Notification, NotificationList},
|
||||||
sheet::Sheet,
|
sheet::Sheet,
|
||||||
window_border, ActiveTheme, Placement, StyledExt, TITLE_BAR_HEIGHT,
|
window_border, ActiveTheme, Placement,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, canvas, div, prelude::FluentBuilder as _, AnyView, App, AppContext, Context,
|
actions, canvas, div, prelude::FluentBuilder as _, AnyView, App, AppContext, Context,
|
||||||
DefiniteLength, Entity, FocusHandle, InteractiveElement, IntoElement, KeyBinding,
|
DefiniteLength, Entity, FocusHandle, InteractiveElement, IntoElement, KeyBinding,
|
||||||
ParentElement as _, Render, StyleRefinement, Styled, Window,
|
ParentElement as _, Render, Styled, Window,
|
||||||
};
|
};
|
||||||
use std::{any::TypeId, rc::Rc};
|
use std::{any::TypeId, rc::Rc};
|
||||||
|
|
||||||
|
|
@ -210,7 +210,6 @@ impl WindowExt for Window {
|
||||||
///
|
///
|
||||||
/// It is used to manage the Sheet, Dialog, and Notification.
|
/// It is used to manage the Sheet, Dialog, and Notification.
|
||||||
pub struct Root {
|
pub struct Root {
|
||||||
style: StyleRefinement,
|
|
||||||
/// Used to store the focus handle of the previous view.
|
/// Used to store the focus handle of the previous view.
|
||||||
/// When the Dialog, Sheet closes, we will focus back to the previous view.
|
/// When the Dialog, Sheet closes, we will focus back to the previous view.
|
||||||
previous_focus_handle: Option<FocusHandle>,
|
previous_focus_handle: Option<FocusHandle>,
|
||||||
|
|
@ -238,7 +237,6 @@ pub(crate) struct ActiveDialog {
|
||||||
impl Root {
|
impl Root {
|
||||||
pub fn new(view: AnyView, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
pub fn new(view: AnyView, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
style: StyleRefinement::default(),
|
|
||||||
previous_focus_handle: None,
|
previous_focus_handle: None,
|
||||||
active_sheet: None,
|
active_sheet: None,
|
||||||
active_dialogs: Vec::new(),
|
active_dialogs: Vec::new(),
|
||||||
|
|
@ -276,64 +274,64 @@ impl Root {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render Notification layer.
|
// Render Notification layer.
|
||||||
fn render_notification_layer(
|
pub fn render_notification_layer(
|
||||||
&mut self,
|
window: &mut Window,
|
||||||
_: &mut Window,
|
cx: &mut App,
|
||||||
_: &mut Context<Self>,
|
|
||||||
) -> Option<impl IntoElement> {
|
) -> Option<impl IntoElement> {
|
||||||
let active_sheet_placement = self.active_sheet.clone().map(|d| d.placement);
|
let root = window.root::<Root>()??;
|
||||||
|
|
||||||
|
let active_sheet_placement = root.read(cx).active_sheet.clone().map(|d| d.placement);
|
||||||
|
|
||||||
let (mt, mr) = match active_sheet_placement {
|
let (mt, mr) = match active_sheet_placement {
|
||||||
Some(Placement::Right) => (None, self.sheet_size),
|
Some(Placement::Right) => (None, root.read(cx).sheet_size),
|
||||||
Some(Placement::Top) => (self.sheet_size, None),
|
Some(Placement::Top) => (root.read(cx).sheet_size, None),
|
||||||
_ => (None, None),
|
_ => (None, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
div()
|
div()
|
||||||
.absolute()
|
.absolute()
|
||||||
.top(TITLE_BAR_HEIGHT)
|
.top_0()
|
||||||
.right_0()
|
.right_0()
|
||||||
.when_some(mt, |this, offset| this.mt(offset))
|
.when_some(mt, |this, offset| this.mt(offset))
|
||||||
.when_some(mr, |this, offset| this.mr(offset))
|
.when_some(mr, |this, offset| this.mr(offset))
|
||||||
.child(self.notification.clone()),
|
.child(root.read(cx).notification.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the Sheet layer.
|
/// Render the Sheet layer.
|
||||||
fn render_sheet_layer(
|
pub fn render_sheet_layer(window: &mut Window, cx: &mut App) -> Option<impl IntoElement> {
|
||||||
&mut self,
|
let root = window.root::<Root>()??;
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut Context<Self>,
|
|
||||||
) -> Option<impl IntoElement> {
|
|
||||||
let active_sheet = self.active_sheet.clone()?;
|
|
||||||
let root = cx.entity();
|
|
||||||
let mut sheet = Sheet::new(window, cx);
|
|
||||||
sheet = (active_sheet.builder)(sheet, window, cx);
|
|
||||||
sheet.focus_handle = active_sheet.focus_handle.clone();
|
|
||||||
sheet.placement = active_sheet.placement;
|
|
||||||
|
|
||||||
let size = sheet.size;
|
if let Some(active_sheet) = root.read(cx).active_sheet.clone() {
|
||||||
|
let mut sheet = Sheet::new(window, cx);
|
||||||
|
sheet = (active_sheet.builder)(sheet, window, cx);
|
||||||
|
sheet.focus_handle = active_sheet.focus_handle.clone();
|
||||||
|
sheet.placement = active_sheet.placement;
|
||||||
|
|
||||||
Some(
|
let size = sheet.size;
|
||||||
div().relative().child(sheet).child(
|
|
||||||
canvas(
|
return Some(
|
||||||
move |_, _, cx| root.update(cx, |r, _| r.sheet_size = Some(size)),
|
div().relative().child(sheet).child(
|
||||||
|_, _, _, _| {},
|
canvas(
|
||||||
)
|
move |_, _, cx| root.update(cx, |r, _| r.sheet_size = Some(size)),
|
||||||
.absolute()
|
|_, _, _, _| {},
|
||||||
.size_full(),
|
)
|
||||||
),
|
.absolute()
|
||||||
)
|
.size_full(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the Dialog layer.
|
/// Render the Dialog layer.
|
||||||
fn render_dialog_layer(
|
pub fn render_dialog_layer(window: &mut Window, cx: &mut App) -> Option<impl IntoElement> {
|
||||||
&mut self,
|
let root = window.root::<Root>()??;
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut Context<Self>,
|
let active_dialogs = root.read(cx).active_dialogs.clone();
|
||||||
) -> Option<impl IntoElement> {
|
|
||||||
let active_dialogs = self.active_dialogs.clone();
|
|
||||||
if active_dialogs.is_empty() {
|
if active_dialogs.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -387,12 +385,6 @@ impl Root {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Styled for Root {
|
|
||||||
fn style(&mut self) -> &mut StyleRefinement {
|
|
||||||
&mut self.style
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Render for Root {
|
impl Render for Root {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let base_font_size = cx.theme().font_size;
|
let base_font_size = cx.theme().font_size;
|
||||||
|
|
@ -404,16 +396,12 @@ impl Render for Root {
|
||||||
.key_context(CONTEXT)
|
.key_context(CONTEXT)
|
||||||
.on_action(cx.listener(Self::on_action_tab))
|
.on_action(cx.listener(Self::on_action_tab))
|
||||||
.on_action(cx.listener(Self::on_action_tab_prev))
|
.on_action(cx.listener(Self::on_action_tab_prev))
|
||||||
.font_family(".SystemUIFont")
|
|
||||||
.refine_style(&self.style)
|
|
||||||
.bg(cx.theme().background)
|
|
||||||
.text_color(cx.theme().foreground)
|
|
||||||
.relative()
|
.relative()
|
||||||
.size_full()
|
.size_full()
|
||||||
.child(self.view.clone())
|
.font_family(".SystemUIFont")
|
||||||
.children(self.render_sheet_layer(window, cx))
|
.bg(cx.theme().background)
|
||||||
.children(self.render_dialog_layer(window, cx))
|
.text_color(cx.theme().foreground)
|
||||||
.children(self.render_notification_layer(window, cx)),
|
.child(self.view.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,37 @@ use gpui_component::WindowExt;
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Setup application root view for display of dialogs
|
||||||
|
|
||||||
|
You need to set up your application's root view to render the dialog layer. This is typically done in your main application struct's render method.
|
||||||
|
|
||||||
|
The [Root::render_dialog_layer](https://docs.rs/gpui-component/latest/gpui_component/struct.Root.html#method.render_dialog_layer) function handles rendering any active dialogs on top of your app content.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use gpui_component::TitleBar;
|
||||||
|
|
||||||
|
struct MyApp {
|
||||||
|
view: AnyView,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for MyApp {
|
||||||
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let dialog_layer = Root::render_dialog_layer(window, cx);
|
||||||
|
|
||||||
|
div()
|
||||||
|
.size_full()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.size_full()
|
||||||
|
.child(TitleBar::new())
|
||||||
|
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
||||||
|
)
|
||||||
|
// Render the dialog layer on top of the app content
|
||||||
|
.children(dialog_layer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Basic Dialog
|
### Basic Dialog
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,38 @@ use gpui_component::WindowExt;
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Setup application root view for display of notifications
|
||||||
|
|
||||||
|
You need to set up your application's root view to render the notification layer. This is typically done in your main application struct's render method.
|
||||||
|
|
||||||
|
The [Root::render_notification_layer](https://docs.rs/gpui-component/latest/gpui_component/struct.Root.html#method.render_notification_layer) function handles rendering any active modals on top of your app content.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use gpui_component::TitleBar;
|
||||||
|
|
||||||
|
struct MyApp {
|
||||||
|
view: AnyView,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for MyApp {
|
||||||
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let notification_layer = Root::render_notification_layer(window, cx);
|
||||||
|
|
||||||
|
|
||||||
|
div()
|
||||||
|
.size_full()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.size_full()
|
||||||
|
.child(TitleBar::new())
|
||||||
|
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
||||||
|
)
|
||||||
|
// Render the notification layer on top of the app content
|
||||||
|
.children(notification_layer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Basic Notification
|
### Basic Notification
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,43 @@ A Sheet (also known as a sidebar or slide-out panel) is a navigation component t
|
||||||
## Import
|
## Import
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use gpui_component::{WindowExt, Placement};
|
use gpui_component::WindowExt;
|
||||||
|
use gpui_component::Placement;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Setup application root view for display of sheets
|
||||||
|
|
||||||
|
You need to set up your application's root view to render the sheet layer. This is typically done in your main application struct's render method.
|
||||||
|
|
||||||
|
The [Root::render_sheet_layer](https://docs.rs/gpui-component/latest/gpui_component/struct.Root.html#method.render_sheet_layer) function handles rendering any active modals on top of your app content.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use gpui_component::TitleBar;
|
||||||
|
|
||||||
|
struct MyApp {
|
||||||
|
view: AnyView,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for MyApp {
|
||||||
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let sheet_layer = Root::render_sheet_layer(window, cx);
|
||||||
|
|
||||||
|
div()
|
||||||
|
.size_full()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.size_full()
|
||||||
|
.child(TitleBar::new())
|
||||||
|
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
||||||
|
)
|
||||||
|
// Render the sheet layer on top of the app content
|
||||||
|
.children(sheet_layer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Basic Sheet
|
### Basic Sheet
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
|
||||||
|
|
@ -30,19 +30,33 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Setup base styles
|
## Overlays
|
||||||
|
|
||||||
You can setup window level base styles by using `Styled` fluent method on [Root], then all child views will inherit these styles.
|
We have dialogs, sheets, notifications, we need placement for them to show, so [Root] provides methods to render these overlays:
|
||||||
|
|
||||||
|
- [Root::render_dialog_layer](https://docs.rs/gpui-component/latest/gpui_component/struct.Root.html#method.render_dialog_layer) - Render the current opened modals.
|
||||||
|
- [Root::render_sheet_layer](https://docs.rs/gpui-component/latest/gpui_component/struct.Root.html#method.render_sheet_layer) - Render the current opened drawers.
|
||||||
|
- [Root::render_notification_layer](https://docs.rs/gpui-component/latest/gpui_component/struct.Root.html#method.render_notification_layer) - Render the notification list.
|
||||||
|
|
||||||
|
We can put these layers in the `render` method your first level view (Root > YourFirstView):
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
Root::new(view.into(), window, cx)
|
struct MyApp;
|
||||||
// This default is `.SystemUIFont` it will use system UI font.
|
|
||||||
.font_family("Your Special Font")
|
impl Render for MyApp {
|
||||||
.text_sm()
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
div()
|
||||||
|
.size_full()
|
||||||
|
.child("My App Content")
|
||||||
|
.children(Root::render_dialog_layer(cx))
|
||||||
|
.children(Root::render_sheet_layer(cx))
|
||||||
|
.children(Root::render_notification_layer(cx))
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
:::tip
|
||||||
|
Here the example we used `children` method, it because if there is no opened dialogs, sheets, notifications, these methods will return `None`, so GPUI will not render anything.
|
||||||
|
:::
|
||||||
|
|
||||||
[Root]: https://docs.rs/gpui-component/latest/gpui_component/root/struct.Root.html
|
[Root]: https://docs.rs/gpui-component/latest/gpui_component/root/struct.Root.html
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ impl HelloWorld {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for HelloWorld {
|
impl Render for HelloWorld {
|
||||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
div()
|
div()
|
||||||
.bg(gpui::white())
|
.bg(gpui::white())
|
||||||
.size_full()
|
.size_full()
|
||||||
|
|
@ -72,6 +72,8 @@ impl Render for HelloWorld {
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
.children(Root::render_dialog_layer(window, cx))
|
||||||
|
.children(Root::render_sheet_layer(window, cx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ fn main() {
|
||||||
|
|
||||||
cx.open_window(window_options, |window, cx| {
|
cx.open_window(window_options, |window, cx| {
|
||||||
let view = cx.new(|_| Example);
|
let view = cx.new(|_| Example);
|
||||||
cx.new(|cx| Root::new(view.into(), window, cx).text_sm())
|
cx.new(|cx| Root::new(view.into(), window, cx))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok::<_, anyhow::Error>(())
|
Ok::<_, anyhow::Error>(())
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue