cursive_image/
image_view.rs1use super::{image::*, kitty::*, sizing::*, state::*, vec2f::*};
2
3use {
4 crossterm::terminal::*,
5 cursive::{align::*, *},
6 std::{cell::*, sync::*},
7};
8
9pub struct ImageView {
21 pub(crate) image: Option<Image>,
22 pub(crate) sizing: Sizing,
23 pub(crate) align: Align,
24
25 pub(crate) size: Option<Vec2>,
26 pub(crate) content_offset: Mutex<RefCell<Option<Vec2>>>,
27 pub(crate) state: Mutex<RefCell<State>>,
28
29 pub(crate) cell_size: XY<f64>,
30 pub(crate) cell_aspect_ratio: f64,
31}
32
33impl ImageView {
34 pub fn image(&self) -> Option<&Image> {
36 self.image.as_ref()
37 }
38
39 pub fn set_image(&mut self, image: Image) {
41 self.image = Some(image);
43 self.reset_layout();
44 }
45
46 pub fn take_image(&mut self) -> Option<Image> {
48 self.reset_layout();
49 match self.image.take() {
50 Some(image) => {
51 _ = image.free();
52 Some(image)
53 }
54 None => None,
55 }
56 }
57
58 pub fn with_image(self, image: Image) -> Self {
62 self.with(|self_| self_.set_image(image))
63 }
64
65 pub fn sizing(&self) -> Sizing {
67 self.sizing
68 }
69
70 pub fn set_sizing(&mut self, sizing: Sizing) {
72 if self.sizing != sizing {
73 self.sizing = sizing;
74 self.reset_layout();
75 }
76 }
77
78 pub fn with_sizing(self, sizing: Sizing) -> Self {
82 self.with(|self_| self_.set_sizing(sizing))
83 }
84
85 pub fn align(&self) -> Align {
87 self.align
88 }
89
90 pub fn set_align(&mut self, align: Align) {
92 if self.align != align {
93 self.align = align;
94 self.reset_layout();
95 }
96 }
97
98 pub fn with_align(self, align: Align) -> Self {
102 self.with(|self_| self_.set_align(align))
103 }
104
105 fn reset_layout(&mut self) {
107 self.size = None;
108 self.set_content_offset(None);
109 }
110
111 pub(crate) fn get_state(&self) -> State {
112 *self.state.lock().unwrap().borrow()
113 }
114
115 pub(crate) fn set_state(&self, state: State) {
116 *self.state.lock().unwrap().borrow_mut() = state;
117 }
118
119 pub(crate) fn get_content_offset(&self) -> Option<Vec2> {
120 *self.content_offset.lock().unwrap().borrow()
121 }
122
123 pub(crate) fn set_content_offset(&self, content_offset: Option<Vec2>) {
124 *self.content_offset.lock().unwrap().borrow_mut() = content_offset;
125 }
126}
127
128impl Default for ImageView {
129 fn default() -> Self {
130 let cell_size = cell_size();
131 Self {
132 image: None,
133 sizing: Default::default(),
134 align: Align::center(),
135 size: None,
136 content_offset: Default::default(),
137 state: Default::default(),
138 cell_size,
139 cell_aspect_ratio: cell_size.aspect_ratio(),
140 }
141 }
142}
143
144fn cell_size() -> Vec2f {
148 match window_size() {
149 Ok(size) if size.width != 0 && size.height != 0 && size.columns != 0 && size.rows != 0 => {
150 (size.width as f64 / size.columns as f64, size.height as f64 / size.rows as f64)
151 }
152
153 _ => (8., 8.),
154 }
155 .into()
156}