Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/draw/input_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'a> Drawable for InputText<'a> {

let pos = Point::new(rect_point.x + padding.left, rect_point.y + padding.top);
let end_pos = Point::new(
dt.width() as f32 - self.params.padding.right - self.params.margin.right,
point.x + space.width - self.params.padding.right - self.params.margin.right,
pos.y,
);

Expand Down
2 changes: 1 addition & 1 deletion src/draw/list_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ where
}

let pos = Point::new(x_offset + icon_size_f32 + icon_spacing, y_offset);
let end_pos = Point::new(dt.width() as f32 - self.params.margin.right, y_offset);
let end_pos = Point::new(point.x + space.width - margin.right, y_offset);

let color = if i == selected_item {
self.params.selected_font_color
Expand Down
34 changes: 28 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,51 @@ macro_rules! prog_name {
};
}

pub struct Viewport {
buf_size: (i32, i32),
content_offset: (f32, f32),
content_size: (f32, f32),
}

impl Viewport {
pub fn full(width: i32, height: i32) -> Self {
Self {
buf_size: (width, height),
content_offset: (0.0, 0.0),
content_size: (width as f32, height as f32),
}
}

pub fn inset(mut self, offset: (f32, f32), content: (f32, f32)) -> Self {
self.content_offset = offset;
self.content_size = content;
self
}
}

pub fn render_to_buffer(
config: &config::Config,
state: &mut state::State,
scale: u16,
width: i32,
height: i32,
buffer: &mut [u32],
viewport: Viewport,
) {
use draw::Drawable;

let mut dt = DrawTarget::from_backing(width, height, buffer);
let mut dt = DrawTarget::from_backing(viewport.buf_size.0, viewport.buf_size.1, buffer);
let mut space_left = draw::Space {
width: width as f32,
height: height as f32,
width: viewport.content_size.0,
height: viewport.content_size.1,
};
let mut point = draw::Point::new(0., 0.);
let mut point = draw::Point::new(viewport.content_offset.0, viewport.content_offset.1);

let (mut drawables, dyn_space) = draw::make_drawables(config, state, scale);
if let Some(dyn_space) = dyn_space {
space_left.height = space_left.height.min(dyn_space.height);
}
while let Some(d) = drawables.borrowed_next() {
let occupied = d.draw(&mut dt, scale, space_left, point);
debug_assert!(occupied.width <= space_left.width && occupied.height <= space_left.height);
point.y += occupied.height;
space_left.height -= occupied.height;
}
Expand Down
30 changes: 8 additions & 22 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,7 @@ impl Window {
}
};

use crate::draw::*;
let mut dt = {
let canvas = {
#[allow(clippy::needless_lifetimes)]
fn transmute_slice<'a>(a: &'a mut [u8]) -> &'a mut [u32] {
assert_eq!(a.as_ptr().align_offset(std::mem::align_of::<u32>()), 0);
Expand All @@ -289,30 +288,17 @@ impl Window {
&mut *std::ptr::slice_from_raw_parts_mut(a.as_mut_ptr().cast(), a.len() / 4)
}
}
let canvas = transmute_slice(canvas);
DrawTarget::from_backing(width, height, canvas)
transmute_slice(canvas)
};

let mut space_left = Space {
width: content_w as f32,
height: content_h as f32,
};
let mut point = Point::new(scaled_offset_x, scaled_offset_y);

let (mut drawables, dyn_space) =
crate::draw::make_drawables(&self.config, &mut self.state, self.scale);
if let Some(dyn_space) = dyn_space {
space_left.height = space_left.height.min(dyn_space.height);
}
while let Some(d) = drawables.borrowed_next() {
let occupied = d.draw(&mut dt, self.scale, space_left, point);
debug_assert!(
occupied.width <= space_left.width && occupied.height <= space_left.height
let mut viewport = crate::Viewport::full(width, height);
if overlay {
viewport = viewport.inset(
(scaled_offset_x, scaled_offset_y),
(content_w as f32, content_h as f32),
);

point.y += occupied.height;
space_left.height -= occupied.height;
}
crate::render_to_buffer(&self.config, &mut self.state, self.scale, canvas, viewport);

self.surface.damage_buffer(0, 0, width, height);
self.surface.frame(qh, self.surface.clone());
Expand Down
Binary file added tests/fixtures/long_input.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tests/fixtures/long_name.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 20 additions & 1 deletion tests/regression/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
//! inspection. The diff highlights changed pixels in red.

mod snap;
use snap::{run_regression, test_entries, Action};
use snap::{
run_regression, run_regression_with_padding, test_entries, test_entries_with_long_name, Action,
};

#[test]
fn initial() {
Expand Down Expand Up @@ -37,3 +39,20 @@ fn search_then_nav() {
&[Action::Type("te"), Action::NextItem],
);
}

#[test]
fn long_name() {
run_regression_with_padding("long_name", test_entries_with_long_name(), &[], (20, 10));
}

#[test]
fn long_input() {
run_regression_with_padding(
"long_input",
test_entries(),
&[Action::Type(
"very long input string that goes well past the input width",
)],
(20, 10),
);
}
47 changes: 36 additions & 11 deletions tests/regression/snap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ pub enum Action {
NextItem,
}

fn to_entries(items: &[&str]) -> Vec<String> {
items.iter().map(|s| s.to_string()).collect()
}

pub fn test_entries() -> Vec<String> {
[
to_entries(&[
"Firefox",
"Chromium",
"Terminal",
Expand All @@ -18,10 +22,16 @@ pub fn test_entries() -> Vec<String> {
"Calculator",
"Text Editor",
"Music Player",
]
.iter()
.map(|s| s.to_string())
.collect()
])
}

pub fn test_entries_with_long_name() -> Vec<String> {
to_entries(&[
"Very Long Application Name That Definitely Does Not Fit In The Window",
"Firefox",
"Chromium",
"Terminal",
])
}

fn unpremultiply_to_rgba(buffer: &[u32]) -> Vec<u8> {
Expand Down Expand Up @@ -85,6 +95,15 @@ fn load_png_rgba(path: &str) -> (u32, u32, Vec<u8>) {
}

pub fn run_regression(name: &str, entries: Vec<String>, actions: &[Action]) {
run_regression_with_padding(name, entries, actions, (0, 0));
}

pub fn run_regression_with_padding(
name: &str,
entries: Vec<String>,
actions: &[Action],
padding: (u32, u32),
) {
let config = Config::default();

let mode = Mode::dialog_from_lines(entries);
Expand All @@ -99,14 +118,20 @@ pub fn run_regression(name: &str, entries: Vec<String>, actions: &[Action]) {

let params: Params = config.param();
let scale = params.scale.unwrap_or(1);
let w = (params.width * u32::from(scale)) as i32;
let h = (params.height * u32::from(scale)) as i32;
let mut buffer = vec![0u32; (w * h) as usize];
yofi::render_to_buffer(&config, &mut state, scale, w, h, &mut buffer);
let content_w = params.width * u32::from(scale);
let content_h = params.height * u32::from(scale);
let buf_w = (content_w + 2 * padding.0) as i32;
let buf_h = (content_h + 2 * padding.1) as i32;

let mut buffer = vec![0u32; (buf_w * buf_h) as usize];
let viewport = yofi::Viewport::full(buf_w, buf_h).inset(
(padding.0 as f32, padding.1 as f32),
(content_w as f32, content_h as f32),
);
yofi::render_to_buffer(&config, &mut state, scale, &mut buffer, viewport);

let actual_rgba = unpremultiply_to_rgba(&buffer);
let w = w as u32;
let h = h as u32;
let (w, h) = (buf_w as u32, buf_h as u32);

let fixture = format!("tests/fixtures/{name}.png");
let new_file = format!("tests/fixtures/{name}.new.png");
Expand Down
Loading