Primitives · a raise keeps its state under its owner's id
A raise inside another was namespaced by its place in the layer's queue, so one that came before it moved its id path and rebuilt its keyed state and focus: an open date popup would lose its month when a tip appeared. raise now takes its owner's id and draws under it, and float and float_height pass the owner's id on from every call site. A test holds a focused box in a raise while another comes before it.
This commit is contained in:
1 parent
341420d1e4
commit
51ade29032
25 files changed
+188
-40
No files matched your search
+81
-2
@@ -1,6 +1,8 @@
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use gpui::{
|
||||
Context, IntoElement, Modifiers, ParentElement, Render, Styled, TestAppContext, Window,
|
||||
anchored, div, point, prelude::*, px,
|
||||
App, Context, Entity, FocusHandle, IntoElement, Modifiers, ParentElement, Render, RenderOnce,
|
||||
Styled, TestAppContext, Window, anchored, div, point, prelude::*, px,
|
||||
};
|
||||
|
||||
use super::raise;
|
||||
@@ -27,11 +29,13 @@ impl Render for Stack {
|
||||
.size(px(200.0))
|
||||
.on_click(move |_, _, cx| cover.update(cx, |stack, _| stack.heard.push("cover")));
|
||||
div().size_full().child(raise(
|
||||
"sheet",
|
||||
anchored().position(point(px(0.0), px(0.0))).child(
|
||||
div()
|
||||
.relative()
|
||||
.size(px(200.0))
|
||||
.child(raise(
|
||||
"button",
|
||||
anchored().position(point(px(50.0), px(50.0))).child(button),
|
||||
))
|
||||
.child(sheet),
|
||||
@@ -51,3 +55,78 @@ fn what_is_raised_inside_a_raise_lies_over_it(cx: &mut TestAppContext) {
|
||||
["inner"]
|
||||
);
|
||||
}
|
||||
|
||||
/// A focusable box whose focus handle lives in keyed state; each draw tells the test which one it drew.
|
||||
#[derive(IntoElement)]
|
||||
struct Held {
|
||||
seen: Rc<RefCell<Vec<Entity<FocusHandle>>>>,
|
||||
}
|
||||
|
||||
impl RenderOnce for Held {
|
||||
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
let kept = window.use_keyed_state("kept", cx, |_, cx| cx.focus_handle());
|
||||
self.seen.borrow_mut().push(kept.clone());
|
||||
let handle = kept.read(cx).clone();
|
||||
div().id("held").size(px(40.0)).track_focus(&handle)
|
||||
}
|
||||
}
|
||||
|
||||
/// A raised sheet holding a raised tip that comes and goes, then a raised box that must stay itself.
|
||||
struct Nest {
|
||||
tip: bool,
|
||||
seen: Rc<RefCell<Vec<Entity<FocusHandle>>>>,
|
||||
}
|
||||
|
||||
impl Render for Nest {
|
||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||
let tip = self.tip.then(|| {
|
||||
raise(
|
||||
"tip",
|
||||
anchored()
|
||||
.position(point(px(0.0), px(0.0)))
|
||||
.child(div().child("tip")),
|
||||
)
|
||||
});
|
||||
let held = Held {
|
||||
seen: self.seen.clone(),
|
||||
};
|
||||
div().size_full().child(raise(
|
||||
"sheet",
|
||||
anchored().position(point(px(0.0), px(0.0))).child(
|
||||
div().size(px(200.0)).children(tip).child(raise(
|
||||
"held",
|
||||
anchored().position(point(px(50.0), px(50.0))).child(held),
|
||||
)),
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_raise_keeps_its_state_while_another_comes_before_it(cx: &mut TestAppContext) {
|
||||
cx.update(Theme::init);
|
||||
let seen = Rc::new(RefCell::new(Vec::new()));
|
||||
let (view, cx) = cx.add_window_view(|_, _| Nest {
|
||||
tip: false,
|
||||
seen: seen.clone(),
|
||||
});
|
||||
cx.run_until_parked();
|
||||
let first = seen.borrow().last().cloned().expect("the box drew");
|
||||
let handle = first.read_with(cx, |handle, _| handle.clone());
|
||||
cx.update(|window, _| window.focus(&handle));
|
||||
view.update(cx, |nest, cx| {
|
||||
nest.tip = true;
|
||||
cx.notify();
|
||||
});
|
||||
cx.run_until_parked();
|
||||
let last = seen.borrow().last().cloned().expect("the box drew again");
|
||||
assert_eq!(
|
||||
last.entity_id(),
|
||||
first.entity_id(),
|
||||
"the box kept its state"
|
||||
);
|
||||
assert!(
|
||||
cx.update(|window, _| handle.is_focused(window)),
|
||||
"the box kept focus"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user