par_term_render/custom_shader_renderer/
state.rs1use std::collections::BTreeMap;
8use std::time::Instant;
9
10use super::CustomShaderRenderer;
11use super::cubemap::CubemapTexture;
12use super::textures::ChannelTexture;
13use anyhow::Result;
14use wgpu::*;
15
16impl CustomShaderRenderer {
17 pub fn animation_enabled(&self) -> bool {
21 self.animation_enabled
22 }
23
24 pub fn set_animation_enabled(&mut self, enabled: bool) {
26 let now = Instant::now();
27 self.start_time = super::animation_start_after_enabled_update(
28 self.animation_enabled,
29 enabled,
30 self.start_time,
31 now,
32 );
33 self.animation_enabled = enabled;
34 }
35
36 pub fn set_animation_speed(&mut self, speed: f32) {
38 self.animation_speed = speed.max(0.0);
39 }
40
41 pub fn set_opacity(&mut self, opacity: f32) {
45 self.window_opacity = opacity.clamp(0.0, 1.0);
46 }
47
48 pub fn set_brightness(&mut self, brightness: f32) {
50 self.brightness = brightness.clamp(0.05, 1.0);
51 }
52
53 pub fn set_auto_dim_under_text(&mut self, enabled: bool, strength: f32) {
55 self.auto_dim_under_text = enabled;
56 self.auto_dim_strength = strength.clamp(0.0, 1.0);
57 }
58
59 pub fn set_full_content_mode(&mut self, enabled: bool) {
61 self.full_content_mode = enabled;
62 }
63
64 pub fn full_content_mode(&self) -> bool {
66 self.full_content_mode
67 }
68
69 pub fn set_keep_text_opaque(&mut self, keep_opaque: bool) {
72 self.keep_text_opaque = keep_opaque;
73 }
74
75 pub fn set_mouse_position(&mut self, x: f32, y: f32) {
79 self.mouse_position = [x, y];
80 }
81
82 pub fn set_mouse_button(&mut self, pressed: bool, x: f32, y: f32) {
84 self.mouse_button_down = pressed;
85 if pressed {
86 self.mouse_click_position = [x, y];
87 }
88 }
89
90 pub fn update_key_press(&mut self) {
97 self.key_press_time = if self.animation_enabled {
98 self.start_time.elapsed().as_secs_f32() * self.animation_speed.max(0.0)
99 } else {
100 0.0
101 };
102 log::trace!("Key pressed at shader time={:.3}", self.key_press_time);
103 }
104
105 pub fn update_channel_texture(
109 &mut self,
110 device: &Device,
111 queue: &Queue,
112 channel: u8,
113 path: Option<&std::path::Path>,
114 ) -> Result<()> {
115 if !(1..=4).contains(&channel) {
116 anyhow::bail!("Invalid channel index: {} (must be 1-4)", channel);
117 }
118
119 let index = (channel - 1) as usize;
120
121 let new_texture = match path {
122 Some(p) => ChannelTexture::from_file(device, queue, p)?,
123 None => ChannelTexture::placeholder(device, queue),
124 };
125
126 self.channel_textures[index] = new_texture;
127 self.recreate_bind_group(device);
129
130 log::info!(
131 "Updated iChannel{} texture: {}",
132 channel,
133 path.map(|p| p.display().to_string())
134 .unwrap_or_else(|| "placeholder".to_string())
135 );
136
137 Ok(())
138 }
139
140 pub fn update_cubemap(
144 &mut self,
145 device: &Device,
146 queue: &Queue,
147 path: Option<&std::path::Path>,
148 ) -> Result<()> {
149 let new_cubemap = match path {
150 Some(p) => CubemapTexture::from_prefix(device, queue, p)?,
151 None => CubemapTexture::placeholder(device, queue),
152 };
153
154 self.cubemap = new_cubemap;
155
156 self.recreate_bind_group(device);
158
159 log::info!(
160 "Updated cubemap texture: {}",
161 path.map(|p| p.display().to_string())
162 .unwrap_or_else(|| "placeholder".to_string())
163 );
164
165 Ok(())
166 }
167
168 pub fn set_use_background_as_channel0(&mut self, use_background: bool) {
178 if self.use_background_as_channel0 != use_background {
179 self.use_background_as_channel0 = use_background;
180 log::info!("use_background_as_channel0 set to {}", use_background);
181 }
182 }
183
184 pub fn use_background_as_channel0(&self) -> bool {
186 self.use_background_as_channel0
187 }
188
189 pub fn set_background_texture(&mut self, device: &Device, texture: Option<ChannelTexture>) {
201 self.background_channel_texture = texture;
202
203 if self.use_background_as_channel0 {
206 self.recreate_bind_group(device);
207 }
208 }
209
210 pub fn set_background_color(&mut self, color: [f32; 3], active: bool) {
219 self.background_color = [color[0], color[1], color[2], if active { 1.0 } else { 0.0 }];
220 }
221
222 pub fn update_use_background_as_channel0(&mut self, device: &Device, use_background: bool) {
226 if self.use_background_as_channel0 != use_background {
227 self.use_background_as_channel0 = use_background;
228 self.recreate_bind_group(device);
229 log::info!("use_background_as_channel0 toggled to {}", use_background);
230 }
231 }
232
233 pub fn set_background_channel0_blend_mode(
235 &mut self,
236 mode: par_term_config::ShaderBackgroundBlendMode,
237 ) {
238 self.background_channel0_blend_mode = mode;
239 }
240
241 pub fn update_progress(&mut self, state: f32, percent: f32, is_active: f32, active_count: f32) {
251 self.progress_data = [state, percent, is_active, active_count];
252 }
253
254 pub fn update_command_status(&mut self, state: f32, exit_code: f32, running: f32) {
260 let state = state.clamp(0.0, 3.0);
261 let exit_code = if exit_code.is_finite() {
262 exit_code
263 } else {
264 0.0
265 };
266 let running = if running > 0.5 { 1.0 } else { 0.0 };
267 let changed = (self.command_data[0] - state).abs() > f32::EPSILON
268 || (self.command_data[1] - exit_code).abs() > f32::EPSILON
269 || (self.command_data[3] - running).abs() > f32::EPSILON;
270
271 if changed {
272 let event_time = if self.animation_enabled {
273 self.start_time.elapsed().as_secs_f32() * self.animation_speed.max(0.0)
274 } else {
275 0.0
276 };
277 self.command_data = [state, exit_code, event_time, running];
278 }
279 }
280
281 pub fn update_focused_pane(&mut self, x: f32, y: f32, width: f32, height: f32) {
283 self.focused_pane = [x.max(0.0), y.max(0.0), width.max(0.0), height.max(0.0)];
284 }
285
286 pub fn update_scrollback(&mut self, offset: f32, visible_lines: f32, scrollback_lines: f32) {
288 let offset = offset.max(0.0);
289 let scrollback_lines = scrollback_lines.max(0.0);
290 let normalized = if scrollback_lines > 0.0 {
291 (offset / scrollback_lines).clamp(0.0, 1.0)
292 } else {
293 0.0
294 };
295 self.scroll_data = [offset, visible_lines.max(0.0), scrollback_lines, normalized];
296 }
297
298 pub fn set_content_inset_right(&mut self, inset: f32) {
305 self.content_inset_right = inset;
306 }
307
308 pub fn set_custom_uniform_values(
312 &mut self,
313 values: BTreeMap<String, par_term_config::ShaderUniformValue>,
314 ) {
315 self.custom_uniform_values = values;
316 }
317}