T24d round 3 fix, after the cap
- BrowserPreview marks the shown frame with accent; the focus color stays the focus ring's - BrowserPreview and ComputerUseViewer take the host's ratio, 16:10 unless set, so frames keep their shape and a pointer's share lands on the picture; test a_screen_takes_its_pictures_shape - TASKS: the review moves to a Claude Fable 5.1 max session after codex ran out of quota; round 3 fixed after the cap, no fourth review - AGENTS: focus and choice colors part; host pictures keep their shape
This commit is contained in:
1 parent
6274b24f03
commit
8550c086b0
4 files changed
+77
-9
No files matched your search
+28
-7
@@ -16,17 +16,22 @@ use crate::{
|
||||
typography::Ellipsis,
|
||||
};
|
||||
|
||||
/// Width over height of a frame from the host.
|
||||
/// Width over height of a frame from the host, unless it says.
|
||||
const FRAME: f32 = 16.0 / 10.0;
|
||||
|
||||
fn checked(ratio: f32) -> f32 {
|
||||
assert!(ratio.is_finite() && ratio > 0.0, "a frame ratio of {ratio}");
|
||||
ratio
|
||||
}
|
||||
|
||||
/// A box that keeps a frame's shape at the width it is given.
|
||||
fn framed(cx: &App) -> Div {
|
||||
fn framed(ratio: f32, cx: &App) -> Div {
|
||||
let mut frame = div()
|
||||
.relative()
|
||||
.w_full()
|
||||
.overflow_hidden()
|
||||
.bg(cx.theme().colors.sunken);
|
||||
frame.style().aspect_ratio = Some(FRAME);
|
||||
frame.style().aspect_ratio = Some(ratio);
|
||||
frame
|
||||
}
|
||||
|
||||
@@ -82,6 +87,7 @@ pub struct BrowserPreview {
|
||||
url: SharedString,
|
||||
frames: Vec<SharedString>,
|
||||
shown: usize,
|
||||
ratio: f32,
|
||||
loading: bool,
|
||||
on_show: Option<Pick>,
|
||||
}
|
||||
@@ -101,11 +107,18 @@ impl BrowserPreview {
|
||||
url: url.into(),
|
||||
frames,
|
||||
shown,
|
||||
ratio: FRAME,
|
||||
loading: false,
|
||||
on_show: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// The frames' width over their height, 16:10 unless set, so the boxes take the pictures' shape.
|
||||
pub fn ratio(mut self, width_over_height: f32) -> Self {
|
||||
self.ratio = checked(width_over_height);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn loading(mut self, loading: bool) -> Self {
|
||||
self.loading = loading;
|
||||
self
|
||||
@@ -174,7 +187,7 @@ impl RenderOnce for BrowserPreview {
|
||||
.rounded(theme.radius(Radius::Sm))
|
||||
.border_1()
|
||||
.border_color(if ix == shown {
|
||||
colors.focus
|
||||
colors.accent
|
||||
} else {
|
||||
colors.border
|
||||
})
|
||||
@@ -183,7 +196,7 @@ impl RenderOnce for BrowserPreview {
|
||||
.rounded(theme.radius(Radius::Sm))
|
||||
.size_full(),
|
||||
);
|
||||
tile.style().aspect_ratio = Some(FRAME);
|
||||
tile.style().aspect_ratio = Some(self.ratio);
|
||||
tile.when_some(show, |tile, show| {
|
||||
tile.track_focus(&handles[ix])
|
||||
.focus_ring(cx)
|
||||
@@ -204,7 +217,7 @@ impl RenderOnce for BrowserPreview {
|
||||
card(cx)
|
||||
.child(address_bar(&self.id, self.url, self.loading, None, cx))
|
||||
.child(
|
||||
framed(cx)
|
||||
framed(self.ratio, cx)
|
||||
.when(strip.is_none(), |frame| {
|
||||
frame.rounded_b(theme.radius(Radius::Lg))
|
||||
})
|
||||
@@ -228,6 +241,7 @@ impl RenderOnce for BrowserPreview {
|
||||
pub struct ComputerUseViewer {
|
||||
id: ElementId,
|
||||
frame: SharedString,
|
||||
ratio: f32,
|
||||
pointer: Option<Point<f32>>,
|
||||
action: Option<SharedString>,
|
||||
}
|
||||
@@ -238,11 +252,18 @@ impl ComputerUseViewer {
|
||||
Self {
|
||||
id: id.into(),
|
||||
frame: frame.into(),
|
||||
ratio: FRAME,
|
||||
pointer: None,
|
||||
action: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// The frame's width over its height, 16:10 unless set, so the box takes the picture's shape.
|
||||
pub fn ratio(mut self, width_over_height: f32) -> Self {
|
||||
self.ratio = checked(width_over_height);
|
||||
self
|
||||
}
|
||||
|
||||
/// Where the agent points, each side a share of the frame from its top left.
|
||||
pub fn pointer(mut self, at: Point<f32>) -> Self {
|
||||
assert!(
|
||||
@@ -302,7 +323,7 @@ impl RenderOnce for ComputerUseViewer {
|
||||
});
|
||||
card(cx)
|
||||
.child(
|
||||
framed(cx)
|
||||
framed(self.ratio, cx)
|
||||
.rounded_t(theme.radius(Radius::Lg))
|
||||
.when(self.action.is_none(), |frame| {
|
||||
frame.rounded_b(theme.radius(Radius::Lg))
|
||||
|
||||
@@ -244,3 +244,47 @@ fn tab_brings_a_hidden_frame_into_view(cx: &mut TestAppContext) {
|
||||
"the eighth frame sits in view"
|
||||
);
|
||||
}
|
||||
|
||||
/// A 4:3 screen in a 480px column, and its height as drawn.
|
||||
struct Screen {
|
||||
height: Rc<Cell<Pixels>>,
|
||||
}
|
||||
|
||||
impl Render for Screen {
|
||||
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
|
||||
let height = self.height.clone();
|
||||
div()
|
||||
.relative()
|
||||
.w(px(480.0))
|
||||
.child(
|
||||
ComputerUseViewer::new("screen", "a.png")
|
||||
.ratio(4.0 / 3.0)
|
||||
.pointer(point(0.5, 0.95)),
|
||||
)
|
||||
.child(
|
||||
canvas(
|
||||
move |bounds, _, _| height.set(bounds.size.height),
|
||||
|_, _, _, _| {},
|
||||
)
|
||||
.absolute()
|
||||
.top_0()
|
||||
.left_0()
|
||||
.size_full(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn a_screen_takes_its_pictures_shape(cx: &mut TestAppContext) {
|
||||
setup(cx);
|
||||
let height = Rc::new(Cell::new(Pixels::ZERO));
|
||||
let seen = height.clone();
|
||||
let (_, cx) = cx.add_window_view(|_, _| Screen { height: seen });
|
||||
settle(cx);
|
||||
let expected = px(478.0 * 3.0 / 4.0 + 2.0);
|
||||
assert!(
|
||||
(height.get() - expected).abs() < px(1.0),
|
||||
"478px inside the border at 4:3, plus the border: {:?} vs {expected:?}",
|
||||
height.get()
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user