pushrod/widgets/
image_widget.rs1use crate::render::callbacks::CallbackRegistry;
17use crate::render::layout_cache::LayoutContainer;
18use crate::render::widget::*;
19use crate::render::widget_cache::WidgetContainer;
20use crate::render::widget_config::{
21 CompassPosition, Config, WidgetConfig, CONFIG_COLOR_BASE, CONFIG_IMAGE_POSITION, CONFIG_SIZE,
22};
23use crate::render::{make_size, Points, Size};
24
25use sdl2::rect::Rect;
26use sdl2::render::{Canvas, Texture, TextureQuery};
27use sdl2::video::Window;
28
29use crate::render::texture_cache::TextureCache;
30use crate::render::texture_store::TextureStore;
31use std::any::Any;
32use std::collections::HashMap;
33
34pub struct ImageWidget {
37 config: WidgetConfig,
38 system_properties: HashMap<i32, String>,
39 callback_registry: CallbackRegistry,
40 texture_store: TextureStore,
41 image_name: String,
42 scaled: bool,
43 texture_sizes: Size,
44}
45
46impl ImageWidget {
51 pub fn new(image_name: String, points: Points, size: Size, scaled: bool) -> Self {
58 Self {
59 config: WidgetConfig::new(points, size),
60 system_properties: HashMap::new(),
61 callback_registry: CallbackRegistry::new(),
62 texture_store: TextureStore::default(),
63 image_name,
64 scaled,
65 texture_sizes: make_size(0, 0),
66 }
67 }
68
69 pub fn get_texture_size(&self) -> Size {
71 self.texture_sizes.clone()
72 }
73}
74
75impl Widget for ImageWidget {
78 fn draw(&mut self, c: &mut Canvas<Window>, t: &mut TextureCache) -> Option<&Texture> {
79 if self.get_config().invalidated() {
80 let bounds = self.get_config().get_size(CONFIG_SIZE);
81
82 self.texture_store
83 .create_or_resize_texture(c, bounds[0] as u32, bounds[1] as u32);
84
85 let base_color = self.get_color(CONFIG_COLOR_BASE);
86 let image_texture = t.get_image(c, self.image_name.clone());
87 let widget_w = self.get_size(CONFIG_SIZE)[0] as i32;
88 let widget_h = self.get_size(CONFIG_SIZE)[1] as i32;
89 let TextureQuery { width, height, .. } = image_texture.query();
90 let scaled = self.scaled;
91
92 self.texture_sizes = make_size(width, height);
93
94 let texture_x = match self.get_compass(CONFIG_IMAGE_POSITION) {
95 CompassPosition::NW | CompassPosition::W | CompassPosition::SW => 0,
96
97 CompassPosition::N | CompassPosition::Center | CompassPosition::S => {
98 (widget_w - width as i32) / 2
99 }
100
101 CompassPosition::NE | CompassPosition::E | CompassPosition::SE => {
102 widget_w - width as i32
103 }
104 };
105
106 let texture_y = match self.get_compass(CONFIG_IMAGE_POSITION) {
107 CompassPosition::NW | CompassPosition::N | CompassPosition::NE => 0,
108
109 CompassPosition::W | CompassPosition::Center | CompassPosition::E => {
110 (widget_h - height as i32) / 2
111 }
112
113 CompassPosition::SW | CompassPosition::S | CompassPosition::SE => {
114 widget_h - height as i32
115 }
116 };
117
118 c.with_texture_canvas(self.texture_store.get_mut_ref(), |texture| {
119 texture.set_draw_color(base_color);
120 texture.clear();
121
122 if !scaled {
123 texture
124 .copy(
125 image_texture,
126 None,
127 Rect::new(texture_x, texture_y, width, height),
128 )
129 .unwrap();
130 } else {
131 texture
132 .copy(
133 image_texture,
134 None,
135 Rect::new(0, 0, widget_w as u32, widget_h as u32),
136 )
137 .unwrap();
138 }
139 })
140 .unwrap();
141 }
142
143 self.texture_store.get_optional_ref()
144 }
145
146 fn on_config_changed(&mut self, _k: u8, _v: Config) {
148 if _k == CONFIG_IMAGE_POSITION {
149 self.get_config().set_invalidated(true);
150 }
151 }
152
153 default_widget_functions!();
154 default_widget_properties!();
155 default_widget_callbacks!();
156}