1use super::{image::*, image_view::*, kitty::*, sizing::*, state::*, vec2f::*};
2
3use cursive::*;
4
5const TYPE_NAME: &str = "ImageView";
6
7impl View for ImageView {
8 fn type_name(&self) -> &'static str {
9 TYPE_NAME
10 }
11
12 fn required_size(&mut self, constraint: Vec2) -> Vec2 {
13 match &self.image {
14 Some(image) => {
15 let size = self.image_size_in_cells(image);
16 match self.sizing {
17 Sizing::Shrink => {
18 let constraint = constraint.into_vec2f();
19 if size > constraint { size.scale_to_fit(constraint) } else { size }
20 }
21
22 Sizing::Fit => size.scale_to_fit(constraint.into_vec2f()),
23
24 Sizing::Scale(scale) => size.scale(scale),
25 }
26 .into_vec2()
27 }
28
29 None => (1, 1).into(),
30 }
31 }
32
33 fn needs_relayout(&self) -> bool {
34 false
35 }
36
37 fn layout(&mut self, size: Vec2) {
38 if self.size != Some(size) {
39 self.size = Some(size);
40 self.set_content_offset(None);
41 self.set_state(State::Ready);
42 }
43 }
44
45 fn draw(&self, printer: &Printer) {
46 let Some(image) = &self.image else {
47 return;
48 };
49
50 if self.get_content_offset() != Some(printer.content_offset) {
51 self.set_content_offset(Some(printer.content_offset));
52
53 self.set_state(State::Ready);
55 }
56
57 if self.get_state().is_ready() {
58 let mut window = None;
59
60 let constraint = printer.output_size.into_vec2f();
61 let size = match self.sizing {
62 Sizing::Shrink => {
63 let size = self.image_size_in_cells(image);
64 if size > constraint { size.scale_to_fit(constraint) } else { size }
65 }
66
67 Sizing::Fit => self.scale_to_fit_image_size_in_cells(image, constraint),
68
69 Sizing::Scale(scale) => {
70 let mut size = self.image_size_in_cells(image).scale(scale);
71
72 let too_wide = size.x > constraint.x;
73 let too_high = size.y > constraint.y;
74
75 if too_wide || too_high {
76 if too_wide {
77 size.x = constraint.x;
78 }
79
80 if too_high {
81 size.y = constraint.y;
82 }
83
84 window = Some(Rect::from_size(
86 self.into_pixels(printer.content_offset.into_vec2f()),
87 self.into_pixels(size),
88 ));
89 }
90
91 size
92 }
93 };
94
95 let size = size.into_vec2();
96 let position: Vec2 = (
97 (printer.offset.x + self.align.h.get_offset(size.x, printer.output_size.x)),
98 (printer.offset.y + self.align.v.get_offset(size.y, printer.output_size.y)),
99 )
100 .into();
101
102 _ = image.display(position, Some(size), window);
103
104 self.set_state(State::Visible);
105 }
106 }
107}
108
109impl ImageView {
110 fn into_pixels(&self, vec: Vec2f) -> Vec2 {
111 vec.scale_vec(self.cell_size).into_vec2()
112 }
113
114 fn image_size_in_cells(&self, image: &Image) -> Vec2f {
115 image.size.into_vec2f().reverse_scale_vec(self.cell_size)
116 }
117
118 fn scale_to_fit_image_size_in_cells(&self, image: &Image, constraint: Vec2f) -> Vec2f {
119 let size: Vec2f = (image.size.x as f64 * self.cell_aspect_ratio, image.size.y as f64).into();
123 size.scale_to_fit(constraint)
124 }
125}
126
127