Implement ObjectFit::ScaleDown for images (#10063)
While working towards fixes for the image viewer, @mikayla-maki and I discovered that we didn't have `object-fit: scale-down` implemented. This doesn't _fully_ solve the image issues as there is some issue where only the bounds width is updating on layout change that I haven't fully chased down. Co-Authored-By: @mikayla-maki Release Notes: - N/A --------- Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
c64c2758c0
commit
c7961b9054
2 changed files with 102 additions and 58 deletions
|
@ -1,10 +1,11 @@
|
|||
use gpui::{
|
||||
canvas, div, fill, img, opaque_grey, point, size, AnyElement, AppContext, Bounds, Context,
|
||||
EventEmitter, FocusHandle, FocusableView, Img, InteractiveElement, IntoElement, Model,
|
||||
ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, WeakView, WindowContext,
|
||||
ObjectFit, ParentElement, Render, Styled, Task, View, ViewContext, VisualContext, WeakView,
|
||||
WindowContext,
|
||||
};
|
||||
use persistence::IMAGE_VIEWER;
|
||||
use ui::{h_flex, prelude::*};
|
||||
use ui::prelude::*;
|
||||
|
||||
use project::{Project, ProjectEntryId, ProjectPath};
|
||||
use std::{ffi::OsStr, path::PathBuf};
|
||||
|
@ -155,64 +156,67 @@ impl FocusableView for ImageView {
|
|||
|
||||
impl Render for ImageView {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let checkered_background = |bounds: Bounds<Pixels>, _, cx: &mut ElementContext| {
|
||||
let square_size = 32.0;
|
||||
|
||||
let start_y = bounds.origin.y.0;
|
||||
let height = bounds.size.height.0;
|
||||
let start_x = bounds.origin.x.0;
|
||||
let width = bounds.size.width.0;
|
||||
|
||||
let mut y = start_y;
|
||||
let mut x = start_x;
|
||||
let mut color_swapper = true;
|
||||
// draw checkerboard pattern
|
||||
while y <= start_y + height {
|
||||
// Keeping track of the grid in order to be resilient to resizing
|
||||
let start_swap = color_swapper;
|
||||
while x <= start_x + width {
|
||||
let rect =
|
||||
Bounds::new(point(px(x), px(y)), size(px(square_size), px(square_size)));
|
||||
|
||||
let color = if color_swapper {
|
||||
opaque_grey(0.6, 0.4)
|
||||
} else {
|
||||
opaque_grey(0.7, 0.4)
|
||||
};
|
||||
|
||||
cx.paint_quad(fill(rect, color));
|
||||
color_swapper = !color_swapper;
|
||||
x += square_size;
|
||||
}
|
||||
x = start_x;
|
||||
color_swapper = !start_swap;
|
||||
y += square_size;
|
||||
}
|
||||
};
|
||||
|
||||
let checkered_background = canvas(|_, _| (), checkered_background)
|
||||
.border_2()
|
||||
.border_color(cx.theme().styles.colors.border)
|
||||
.size_full()
|
||||
.absolute()
|
||||
.top_0()
|
||||
.left_0();
|
||||
|
||||
div()
|
||||
.track_focus(&self.focus_handle)
|
||||
.size_full()
|
||||
.child(checkered_background)
|
||||
.child(
|
||||
// Checkered background behind the image
|
||||
canvas(
|
||||
|_, _| (),
|
||||
|bounds, _, cx| {
|
||||
let square_size = 32.0;
|
||||
|
||||
let start_y = bounds.origin.y.0;
|
||||
let height = bounds.size.height.0;
|
||||
let start_x = bounds.origin.x.0;
|
||||
let width = bounds.size.width.0;
|
||||
|
||||
let mut y = start_y;
|
||||
let mut x = start_x;
|
||||
let mut color_swapper = true;
|
||||
// draw checkerboard pattern
|
||||
while y <= start_y + height {
|
||||
// Keeping track of the grid in order to be resilient to resizing
|
||||
let start_swap = color_swapper;
|
||||
while x <= start_x + width {
|
||||
let rect = Bounds::new(
|
||||
point(px(x), px(y)),
|
||||
size(px(square_size), px(square_size)),
|
||||
);
|
||||
|
||||
let color = if color_swapper {
|
||||
opaque_grey(0.6, 0.4)
|
||||
} else {
|
||||
opaque_grey(0.7, 0.4)
|
||||
};
|
||||
|
||||
cx.paint_quad(fill(rect, color));
|
||||
color_swapper = !color_swapper;
|
||||
x += square_size;
|
||||
}
|
||||
x = start_x;
|
||||
color_swapper = !start_swap;
|
||||
y += square_size;
|
||||
}
|
||||
},
|
||||
)
|
||||
.border_2()
|
||||
.border_color(cx.theme().styles.colors.border)
|
||||
.size_full()
|
||||
.absolute()
|
||||
.top_0()
|
||||
.left_0(),
|
||||
)
|
||||
.child(
|
||||
v_flex().h_full().justify_around().child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.justify_around()
|
||||
.child(img(self.path.clone())),
|
||||
),
|
||||
div()
|
||||
.flex()
|
||||
.justify_center()
|
||||
.items_center()
|
||||
.w_full()
|
||||
// TODO: In browser based Tailwind & Flex this would be h-screen and we'd use w-full
|
||||
.h_full()
|
||||
.child(
|
||||
img(self.path.clone())
|
||||
.object_fit(ObjectFit::ScaleDown)
|
||||
.max_w_full()
|
||||
.max_h_full(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue