root: Render overlays inside Root element by default. (#1570)
## Break Change - The `Root::render_notification_layer`, `Root::render_sheet_layer`, `Root::render_dialog_layer` has been removed, we don't need it now, the Root element has default rendered them.
This commit is contained in:
parent
f88b547b70
commit
f26f01909e
10 changed files with 55 additions and 201 deletions
|
|
@ -505,11 +505,7 @@ pub fn open_new(
|
|||
}
|
||||
|
||||
impl Render for StoryWorkspace {
|
||||
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);
|
||||
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.id("story-workspace")
|
||||
.on_action(cx.listener(Self::on_action_add_panel))
|
||||
|
|
@ -521,9 +517,6 @@ impl Render for StoryWorkspace {
|
|||
.flex_col()
|
||||
.child(self.title_bar.clone())
|
||||
.child(self.dock_area.clone())
|
||||
.children(sheet_layer)
|
||||
.children(dialog_layer)
|
||||
.children(notification_layer)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -409,11 +409,7 @@ pub fn open_new(
|
|||
}
|
||||
|
||||
impl Render for StoryTiles {
|
||||
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);
|
||||
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.font_family(".SystemUIFont")
|
||||
.relative()
|
||||
|
|
@ -424,9 +420,6 @@ impl Render for StoryTiles {
|
|||
.text_color(cx.theme().foreground)
|
||||
.child(TitleBar::new().child(div().flex().items_center().child("Story Tiles")))
|
||||
.child(self.dock_area.clone())
|
||||
.children(sheet_layer)
|
||||
.children(dialog_layer)
|
||||
.children(notification_layer)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -261,22 +261,13 @@ impl StoryRoot {
|
|||
}
|
||||
|
||||
impl Render for StoryRoot {
|
||||
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()
|
||||
.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)
|
||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||
div().size_full().child(
|
||||
v_flex()
|
||||
.size_full()
|
||||
.child(self.title_bar.clone())
|
||||
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -318,8 +318,8 @@ impl Render for Notification {
|
|||
.child(
|
||||
h_flex()
|
||||
.absolute()
|
||||
.top_3p5()
|
||||
.right_3p5()
|
||||
.top_1p5()
|
||||
.right_1p5()
|
||||
.invisible()
|
||||
.group_hover("", |this| this.visible())
|
||||
.child(
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
input::InputState,
|
||||
notification::{Notification, NotificationList},
|
||||
sheet::Sheet,
|
||||
window_border, ActiveTheme, Placement,
|
||||
window_border, ActiveTheme, Placement, TITLE_BAR_HEIGHT,
|
||||
};
|
||||
use gpui::{
|
||||
actions, canvas, div, prelude::FluentBuilder as _, AnyView, App, AppContext, Context,
|
||||
|
|
@ -274,64 +274,64 @@ impl Root {
|
|||
}
|
||||
|
||||
// Render Notification layer.
|
||||
pub fn render_notification_layer(
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
fn render_notification_layer(
|
||||
&mut self,
|
||||
_: &mut Window,
|
||||
_: &mut Context<Self>,
|
||||
) -> Option<impl IntoElement> {
|
||||
let root = window.root::<Root>()??;
|
||||
|
||||
let active_sheet_placement = root.read(cx).active_sheet.clone().map(|d| d.placement);
|
||||
let active_sheet_placement = self.active_sheet.clone().map(|d| d.placement);
|
||||
|
||||
let (mt, mr) = match active_sheet_placement {
|
||||
Some(Placement::Right) => (None, root.read(cx).sheet_size),
|
||||
Some(Placement::Top) => (root.read(cx).sheet_size, None),
|
||||
Some(Placement::Right) => (None, self.sheet_size),
|
||||
Some(Placement::Top) => (self.sheet_size, None),
|
||||
_ => (None, None),
|
||||
};
|
||||
|
||||
Some(
|
||||
div()
|
||||
.absolute()
|
||||
.top_0()
|
||||
.top(TITLE_BAR_HEIGHT)
|
||||
.right_0()
|
||||
.when_some(mt, |this, offset| this.mt(offset))
|
||||
.when_some(mr, |this, offset| this.mr(offset))
|
||||
.child(root.read(cx).notification.clone()),
|
||||
.child(self.notification.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
/// Render the Sheet layer.
|
||||
pub fn render_sheet_layer(window: &mut Window, cx: &mut App) -> Option<impl IntoElement> {
|
||||
let root = window.root::<Root>()??;
|
||||
fn render_sheet_layer(
|
||||
&mut self,
|
||||
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;
|
||||
|
||||
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;
|
||||
let size = sheet.size;
|
||||
|
||||
let size = sheet.size;
|
||||
|
||||
return Some(
|
||||
div().relative().child(sheet).child(
|
||||
canvas(
|
||||
move |_, _, cx| root.update(cx, |r, _| r.sheet_size = Some(size)),
|
||||
|_, _, _, _| {},
|
||||
)
|
||||
.absolute()
|
||||
.size_full(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
None
|
||||
Some(
|
||||
div().relative().child(sheet).child(
|
||||
canvas(
|
||||
move |_, _, cx| root.update(cx, |r, _| r.sheet_size = Some(size)),
|
||||
|_, _, _, _| {},
|
||||
)
|
||||
.absolute()
|
||||
.size_full(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/// Render the Dialog layer.
|
||||
pub fn render_dialog_layer(window: &mut Window, cx: &mut App) -> Option<impl IntoElement> {
|
||||
let root = window.root::<Root>()??;
|
||||
|
||||
let active_dialogs = root.read(cx).active_dialogs.clone();
|
||||
|
||||
fn render_dialog_layer(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<impl IntoElement> {
|
||||
let active_dialogs = self.active_dialogs.clone();
|
||||
if active_dialogs.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
|
@ -401,7 +401,10 @@ impl Render for Root {
|
|||
.font_family(".SystemUIFont")
|
||||
.bg(cx.theme().background)
|
||||
.text_color(cx.theme().foreground)
|
||||
.child(self.view.clone()),
|
||||
.child(self.view.clone())
|
||||
.children(self.render_sheet_layer(window, cx))
|
||||
.children(self.render_dialog_layer(window, cx))
|
||||
.children(self.render_notification_layer(window, cx)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,37 +16,6 @@ use gpui_component::WindowExt;
|
|||
|
||||
## 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
|
||||
|
||||
```rust
|
||||
|
|
|
|||
|
|
@ -16,38 +16,6 @@ use gpui_component::WindowExt;
|
|||
|
||||
## 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
|
||||
|
||||
```rust
|
||||
|
|
|
|||
|
|
@ -10,43 +10,11 @@ A Sheet (also known as a sidebar or slide-out panel) is a navigation component t
|
|||
## Import
|
||||
|
||||
```rust
|
||||
use gpui_component::WindowExt;
|
||||
use gpui_component::Placement;
|
||||
use gpui_component::{WindowExt, Placement};
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
```rust
|
||||
|
|
|
|||
|
|
@ -30,33 +30,4 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
## Overlays
|
||||
|
||||
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
|
||||
struct MyApp;
|
||||
|
||||
impl Render for MyApp {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ impl HelloWorld {
|
|||
}
|
||||
|
||||
impl Render for HelloWorld {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
div()
|
||||
.bg(gpui::white())
|
||||
.size_full()
|
||||
|
|
@ -72,8 +72,6 @@ impl Render for HelloWorld {
|
|||
}),
|
||||
),
|
||||
)
|
||||
.children(Root::render_dialog_layer(window, cx))
|
||||
.children(Root::render_sheet_layer(window, cx))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue