Tables: focused headers scroll into view; long tables scroll sideways
A sortable header is a tracked Tab stop; once focused it sets its table's sideways offset whole from its painted bounds and asks one frame. The virtualized branch scrolls sideways too, and its list keeps a plain wheel to its rows. layout::on_axis keeps a scroll box's wheel to its axes; tables, code blocks, the thumbnail strip and the gallery's page use it. Footer figures move to tables/foot.rs; the profiler's ruler takes theme.chart().label. HumanInputRequest's answered state gets a test.
This commit is contained in:
15 files changed
+405
-254
No files matched your search
@@ -10,6 +10,7 @@ use crate::{
|
||||
buttons::{ButtonVariant, IconButton},
|
||||
documents::source,
|
||||
forms::{Pick, Run, reveal, revealer},
|
||||
layout::on_axis,
|
||||
motion::{self, Spinner},
|
||||
primitives::{FocusRing, Icon, IconName, Image, tab_stop},
|
||||
theme::{ActiveTheme, AvatarSize, ControlSize, IconSize, Radius, TextSize},
|
||||
@@ -168,8 +169,7 @@ impl RenderOnce for BrowserPreview {
|
||||
let thumb = theme.avatar_size(AvatarSize::Lg);
|
||||
let shown = self.shown;
|
||||
let strip = (self.frames.len() > 1).then(|| {
|
||||
div()
|
||||
.id((self.id.clone(), "strip"))
|
||||
on_axis(div().id((self.id.clone(), "strip")))
|
||||
.track_scroll(&scroll)
|
||||
.overflow_x_scroll()
|
||||
.flex()
|
||||
|
||||
+22
-13
@@ -11,7 +11,7 @@ use crate::{
|
||||
theme::Theme,
|
||||
};
|
||||
|
||||
/// A question with two answers to pick, and the answers given.
|
||||
/// A question with two answers to pick, and the answers given; once answered, it shows the first.
|
||||
struct Asked {
|
||||
field: Entity<TextInput>,
|
||||
answers: Vec<String>,
|
||||
@@ -20,17 +20,23 @@ struct Asked {
|
||||
impl Render for Asked {
|
||||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let view = cx.entity();
|
||||
div().w(px(420.0)).child(
|
||||
HumanInputRequest::new(
|
||||
"asked",
|
||||
"Keep the accents?",
|
||||
&self.field,
|
||||
move |answer, _, cx| {
|
||||
view.update(cx, |asked, _| asked.answers.push(answer.to_string()))
|
||||
},
|
||||
)
|
||||
.choices(["Keep them", "Lift further"]),
|
||||
let request = HumanInputRequest::new(
|
||||
"asked",
|
||||
"Keep the accents?",
|
||||
&self.field,
|
||||
move |answer, _, cx| {
|
||||
view.update(cx, |asked, cx| {
|
||||
asked.answers.push(answer.to_string());
|
||||
cx.notify();
|
||||
})
|
||||
},
|
||||
)
|
||||
.choices(["Keep them", "Lift further"]);
|
||||
let request = match self.answers.first() {
|
||||
Some(answer) => request.answered(answer.clone()),
|
||||
None => request,
|
||||
};
|
||||
div().w(px(420.0)).child(request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,14 +56,17 @@ fn asked(cx: &mut TestAppContext) -> (Entity<Asked>, &mut VisualTestContext) {
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_pick_answers_the_question(cx: &mut TestAppContext) {
|
||||
fn a_pick_answers_the_question_and_the_answer_stands_alone(cx: &mut TestAppContext) {
|
||||
let (view, cx) = asked(cx);
|
||||
cx.update(|window, _| window.focus_next());
|
||||
cx.update(|window, _| window.focus_next());
|
||||
press("enter", cx);
|
||||
cx.update(|window, _| window.focus_next());
|
||||
press("enter", cx);
|
||||
assert_eq!(
|
||||
view.read_with(cx, |asked, _| asked.answers.clone()),
|
||||
["Lift further"]
|
||||
["Lift further"],
|
||||
"once answered, no choice is left to press"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user