1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-23 21:32:13 +03:00

conceptually allow for multiple image attachments in a cell

refs: #986
This commit is contained in:
Wez Furlong 2021-07-29 19:41:52 -07:00
parent 96f15a065c
commit 71e88a4fea
5 changed files with 99 additions and 50 deletions

View File

@ -2020,11 +2020,11 @@ impl TerminalState {
.get_cell(cursor_x + x, cursor_y)
.cloned()
.unwrap_or_else(|| Cell::new(' ', CellAttributes::default()));
cell.attrs_mut().set_image(Some(Box::new(ImageCell::new(
cell.attrs_mut().set_image(Box::new(ImageCell::new(
TextureCoordinate::new(xpos, ypos),
TextureCoordinate::new(xpos + x_delta, ypos + y_delta),
image_data.clone(),
))));
)));
self.screen_mut().set_cell(cursor_x + x, cursor_y, &cell);
xpos += x_delta;

View File

@ -76,7 +76,7 @@ struct FatAttributes {
/// The hyperlink content, if any
hyperlink: Option<Arc<Hyperlink>>,
/// The image data, if any
image: Option<Box<ImageCell>>,
image: Vec<Box<ImageCell>>,
/// The color of the underline. If None, then
/// the foreground color is to be used
underline_color: ColorAttribute,
@ -326,7 +326,7 @@ impl CellAttributes {
if self.fat.is_none() {
self.fat.replace(Box::new(FatAttributes {
hyperlink: None,
image: None,
image: vec![],
underline_color: ColorAttribute::Default,
foreground: ColorAttribute::Default,
background: ColorAttribute::Default,
@ -339,7 +339,7 @@ impl CellAttributes {
.fat
.as_ref()
.map(|fat| {
fat.image.is_none()
fat.image.is_empty()
&& fat.hyperlink.is_none()
&& fat.underline_color == ColorAttribute::Default
&& fat.foreground == ColorAttribute::Default
@ -362,15 +362,35 @@ impl CellAttributes {
}
}
pub fn set_image(&mut self, image: Option<Box<ImageCell>>) -> &mut Self {
if image.is_none() && self.fat.is_none() {
self
} else {
self.allocate_fat_attributes();
self.fat.as_mut().unwrap().image = image;
self.deallocate_fat_attributes_if_none();
self
/// Assign a single image to a cell.
pub fn set_image(&mut self, image: Box<ImageCell>) -> &mut Self {
self.allocate_fat_attributes();
self.fat.as_mut().unwrap().image = vec![image];
self
}
/// Clear all images from a cell
pub fn clear_images(&mut self) -> &mut Self {
if let Some(fat) = self.fat.as_mut() {
fat.image.clear();
}
self.deallocate_fat_attributes_if_none();
self
}
/// Add an image attachement, preserving any existing attachments.
/// The list of images is maintained in z-index order
pub fn attach_image(&mut self, image: Box<ImageCell>) -> &mut Self {
self.allocate_fat_attributes();
let fat = self.fat.as_mut().unwrap();
let z_index = image.z_index();
match fat
.image
.binary_search_by(|probe| probe.z_index().cmp(&z_index))
{
Ok(idx) | Err(idx) => fat.image.insert(idx, image),
}
self
}
pub fn set_underline_color<C: Into<ColorAttribute>>(
@ -420,10 +440,15 @@ impl CellAttributes {
self.fat.as_ref().and_then(|fat| fat.hyperlink.as_ref())
}
pub fn image(&self) -> Option<&ImageCell> {
self.fat
.as_ref()
.and_then(|fat| fat.image.as_ref().map(|im| im.as_ref()))
/// Returns the list of attached images in z-index order.
/// Returns None if there are no attached images; will
/// never return Some(vec![]).
pub fn images(&self) -> Option<Vec<ImageCell>> {
let fat = self.fat.as_ref()?;
if fat.image.is_empty() {
return None;
}
Some(fat.image.iter().map(|im| im.as_ref().clone()).collect())
}
pub fn underline_color(&self) -> ColorAttribute {

View File

@ -83,6 +83,7 @@ pub struct ImageCell {
bottom_right: TextureCoordinate,
/// References the underlying image data
data: Arc<ImageData>,
z_index: i32,
}
impl ImageCell {
@ -90,11 +91,21 @@ impl ImageCell {
top_left: TextureCoordinate,
bottom_right: TextureCoordinate,
data: Arc<ImageData>,
) -> Self {
Self::with_z_index(top_left, bottom_right, data, 0)
}
pub fn with_z_index(
top_left: TextureCoordinate,
bottom_right: TextureCoordinate,
data: Arc<ImageData>,
z_index: i32,
) -> Self {
Self {
top_left,
bottom_right,
data,
z_index,
}
}
@ -109,6 +120,14 @@ impl ImageCell {
pub fn image_data(&self) -> &Arc<ImageData> {
&self.data
}
/// negative z_index is rendered beneath the text layer.
/// >= 0 is rendered above the text.
/// negative z_index < INT32_MIN/2 will be drawn under cells
/// with non-default background colors
pub fn z_index(&self) -> i32 {
self.z_index
}
}
static IMAGE_ID: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0);

View File

@ -326,7 +326,7 @@ impl Surface {
' ',
self.attributes
.clone()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new(
image.top_left.x + xpos,
image.top_left.y + ypos,
@ -336,7 +336,7 @@ impl Surface {
image.top_left.y + ypos + ysize,
),
image.image.clone(),
))))
)))
.clone(),
),
);
@ -1596,41 +1596,41 @@ mod test {
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.0, 0.0),
TextureCoordinate::new_f32(0.25, 0.5),
data.clone()
))))
)))
.clone()
),
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.25, 0.0),
TextureCoordinate::new_f32(0.5, 0.5),
data.clone()
))))
)))
.clone()
),
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.5, 0.0),
TextureCoordinate::new_f32(0.75, 0.5),
data.clone()
))))
)))
.clone()
),
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.75, 0.0),
TextureCoordinate::new_f32(1.0, 0.5),
data.clone()
))))
)))
.clone()
),
],
@ -1638,41 +1638,41 @@ mod test {
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.0, 0.5),
TextureCoordinate::new_f32(0.25, 1.0),
data.clone()
))))
)))
.clone()
),
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.25, 0.5),
TextureCoordinate::new_f32(0.5, 1.0),
data.clone()
))))
)))
.clone()
),
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.5, 0.5),
TextureCoordinate::new_f32(0.75, 1.0),
data.clone()
))))
)))
.clone()
),
Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.75, 0.5),
TextureCoordinate::new_f32(1.0, 1.0),
data.clone()
))))
)))
.clone()
),
],
@ -1694,11 +1694,11 @@ mod test {
[[Cell::new(
' ',
CellAttributes::default()
.set_image(Some(Box::new(ImageCell::new(
.set_image(Box::new(ImageCell::new(
TextureCoordinate::new_f32(0.25, 0.3),
TextureCoordinate::new_f32(0.75, 0.8),
data.clone()
))))
)))
.clone()
),]]
);

View File

@ -871,19 +871,24 @@ impl super::TermWindow {
cursor_bg: params.cursor_bg,
});
if let Some(image) = cluster.attrs.image() {
self.populate_image_quad(
image,
gl_state,
quads,
cell_idx,
&params,
hsv,
cursor_shape,
glyph_color,
style_params.underline_color,
bg_color,
)?;
if let Some(images) = cluster.attrs.images() {
// FIXME: This is where we need to allocate distinct quads for each of
// these images
for image in images {
self.populate_image_quad(
&image,
gl_state,
quads,
cell_idx,
&params,
hsv,
cursor_shape,
glyph_color,
style_params.underline_color,
bg_color,
)?;
}
}
if self.config.custom_block_glyphs && glyph_idx == 0 {