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 {
|
impl Render for StoryWorkspace {
|
||||||
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 {
|
||||||
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))
|
||||||
|
|
@ -521,9 +517,6 @@ 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,11 +409,7 @@ pub fn open_new(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for StoryTiles {
|
impl Render for StoryTiles {
|
||||||
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 {
|
||||||
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")
|
.font_family(".SystemUIFont")
|
||||||
.relative()
|
.relative()
|
||||||
|
|
@ -424,9 +420,6 @@ 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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -261,22 +261,13 @@ impl StoryRoot {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for StoryRoot {
|
impl Render for StoryRoot {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||||
let sheet_layer = Root::render_sheet_layer(window, cx);
|
div().size_full().child(
|
||||||
let dialog_layer = Root::render_dialog_layer(window, cx);
|
v_flex()
|
||||||
let notification_layer = Root::render_notification_layer(window, cx);
|
.size_full()
|
||||||
|
.child(self.title_bar.clone())
|
||||||
div()
|
.child(div().flex_1().overflow_hidden().child(self.view.clone())),
|
||||||
.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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -318,8 +318,8 @@ impl Render for Notification {
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.absolute()
|
.absolute()
|
||||||
.top_3p5()
|
.top_1p5()
|
||||||
.right_3p5()
|
.right_1p5()
|
||||||
.invisible()
|
.invisible()
|
||||||
.group_hover("", |this| this.visible())
|
.group_hover("", |this| this.visible())
|
||||||
.child(
|
.child(
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use crate::{
|
||||||
input::InputState,
|
input::InputState,
|
||||||
notification::{Notification, NotificationList},
|
notification::{Notification, NotificationList},
|
||||||
sheet::Sheet,
|
sheet::Sheet,
|
||||||
window_border, ActiveTheme, Placement,
|
window_border, ActiveTheme, Placement, TITLE_BAR_HEIGHT,
|
||||||
};
|
};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, canvas, div, prelude::FluentBuilder as _, AnyView, App, AppContext, Context,
|
actions, canvas, div, prelude::FluentBuilder as _, AnyView, App, AppContext, Context,
|
||||||
|
|
@ -274,64 +274,64 @@ impl Root {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render Notification layer.
|
// Render Notification layer.
|
||||||
pub fn render_notification_layer(
|
fn render_notification_layer(
|
||||||
window: &mut Window,
|
&mut self,
|
||||||
cx: &mut App,
|
_: &mut Window,
|
||||||
|
_: &mut Context<Self>,
|
||||||
) -> Option<impl IntoElement> {
|
) -> Option<impl IntoElement> {
|
||||||
let root = window.root::<Root>()??;
|
let active_sheet_placement = self.active_sheet.clone().map(|d| d.placement);
|
||||||
|
|
||||||
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, root.read(cx).sheet_size),
|
Some(Placement::Right) => (None, self.sheet_size),
|
||||||
Some(Placement::Top) => (root.read(cx).sheet_size, None),
|
Some(Placement::Top) => (self.sheet_size, None),
|
||||||
_ => (None, None),
|
_ => (None, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
div()
|
div()
|
||||||
.absolute()
|
.absolute()
|
||||||
.top_0()
|
.top(TITLE_BAR_HEIGHT)
|
||||||
.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(root.read(cx).notification.clone()),
|
.child(self.notification.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the Sheet layer.
|
/// Render the Sheet layer.
|
||||||
pub fn render_sheet_layer(window: &mut Window, cx: &mut App) -> Option<impl IntoElement> {
|
fn render_sheet_layer(
|
||||||
let root = window.root::<Root>()??;
|
&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 size = sheet.size;
|
||||||
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;
|
Some(
|
||||||
|
div().relative().child(sheet).child(
|
||||||
return Some(
|
canvas(
|
||||||
div().relative().child(sheet).child(
|
move |_, _, cx| root.update(cx, |r, _| r.sheet_size = Some(size)),
|
||||||
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.
|
||||||
pub fn render_dialog_layer(window: &mut Window, cx: &mut App) -> Option<impl IntoElement> {
|
fn render_dialog_layer(
|
||||||
let root = window.root::<Root>()??;
|
&mut self,
|
||||||
|
window: &mut Window,
|
||||||
let active_dialogs = root.read(cx).active_dialogs.clone();
|
cx: &mut Context<Self>,
|
||||||
|
) -> Option<impl IntoElement> {
|
||||||
|
let active_dialogs = self.active_dialogs.clone();
|
||||||
if active_dialogs.is_empty() {
|
if active_dialogs.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +401,10 @@ impl Render for Root {
|
||||||
.font_family(".SystemUIFont")
|
.font_family(".SystemUIFont")
|
||||||
.bg(cx.theme().background)
|
.bg(cx.theme().background)
|
||||||
.text_color(cx.theme().foreground)
|
.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
|
## 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,38 +16,6 @@ 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,43 +10,11 @@ A Sheet (also known as a sidebar or slide-out panel) is a navigation component t
|
||||||
## Import
|
## Import
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use gpui_component::WindowExt;
|
use gpui_component::{WindowExt, Placement};
|
||||||
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,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
|
[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, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
div()
|
div()
|
||||||
.bg(gpui::white())
|
.bg(gpui::white())
|
||||||
.size_full()
|
.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