Skip to main content

par_term_render/renderer/shaders/
shared.rs

1//! Shader methods that coordinate across both background and cursor shaders.
2//!
3//! These operations apply uniformly to whichever renderers are currently active:
4//! mouse input forwarding, key press timing, cursor state, progress bar state,
5//! cursor shader config updates, and animation pause/resume.
6
7use super::super::Renderer;
8
9impl Renderer {
10    /// Update mouse position for custom shader (iMouse uniform)
11    pub fn set_shader_mouse_position(&mut self, x: f32, y: f32) {
12        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
13            custom_shader.set_mouse_position(x, y);
14        }
15    }
16
17    /// Update mouse button state for custom shader (iMouse uniform)
18    pub fn set_shader_mouse_button(&mut self, pressed: bool, x: f32, y: f32) {
19        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
20            custom_shader.set_mouse_button(pressed, x, y);
21        }
22    }
23
24    /// Record a key-press timestamp on both shader renderers (iTime-derived uniforms)
25    pub fn update_key_press_time(&mut self) {
26        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
27            custom_shader.update_key_press();
28        }
29        if let Some(ref mut cursor_shader) = self.cursor_shader_renderer {
30            cursor_shader.update_key_press();
31        }
32    }
33
34    /// Update cursor state for both shader renderers (Ghostty-compatible cursor uniforms).
35    ///
36    /// Enables cursor trail effects and other cursor-based animations in both
37    /// background and cursor shaders.
38    pub fn update_shader_cursor(
39        &mut self,
40        col: usize,
41        row: usize,
42        opacity: f32,
43        color: [f32; 4],
44        style: par_term_emu_core_rust::cursor::CursorStyle,
45    ) {
46        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
47            custom_shader.update_cursor(col, row, opacity, color, style);
48        }
49        if let Some(ref mut cursor_shader) = self.cursor_shader_renderer {
50            cursor_shader.update_cursor(col, row, opacity, color, style);
51        }
52    }
53
54    /// Update progress bar state for both shader renderers (iProgress uniform).
55    ///
56    /// # Arguments
57    /// * `state` - Progress state (0=hidden, 1=normal, 2=error, 3=indeterminate, 4=warning)
58    /// * `percent` - Progress percentage as 0.0–1.0
59    /// * `is_active` - 1.0 if any progress bar is active, 0.0 otherwise
60    /// * `active_count` - Total count of active bars (simple + named)
61    pub fn update_shader_progress(
62        &mut self,
63        state: f32,
64        percent: f32,
65        is_active: f32,
66        active_count: f32,
67    ) {
68        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
69            custom_shader.update_progress(state, percent, is_active, active_count);
70        }
71        if let Some(ref mut cursor_shader) = self.cursor_shader_renderer {
72            cursor_shader.update_progress(state, percent, is_active, active_count);
73        }
74    }
75
76    /// Update cursor shader configuration on both renderer instances.
77    ///
78    /// Glow radius is in logical pixels and will be scaled to physical pixels internally.
79    pub fn update_cursor_shader_config(
80        &mut self,
81        color: [u8; 3],
82        trail_duration: f32,
83        glow_radius: f32,
84        glow_intensity: f32,
85    ) {
86        let physical_glow_radius = glow_radius * self.cell_renderer.scale_factor;
87        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
88            custom_shader.update_cursor_shader_config(
89                color,
90                trail_duration,
91                physical_glow_radius,
92                glow_intensity,
93            );
94        }
95        if let Some(ref mut cursor_shader) = self.cursor_shader_renderer {
96            cursor_shader.update_cursor_shader_config(
97                color,
98                trail_duration,
99                physical_glow_radius,
100                glow_intensity,
101            );
102        }
103    }
104
105    /// Pause shader animations on all active renderers (e.g., when window loses focus).
106    pub fn pause_shader_animations(&mut self) {
107        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
108            custom_shader.set_animation_enabled(false);
109        }
110        if let Some(ref mut cursor_shader) = self.cursor_shader_renderer {
111            cursor_shader.set_animation_enabled(false);
112        }
113        log::info!("[SHADER] Shader animations paused");
114    }
115
116    /// Resume shader animations on all active renderers (e.g., when window regains focus).
117    ///
118    /// Only resumes if the user's config has animation enabled for that shader.
119    pub fn resume_shader_animations(
120        &mut self,
121        custom_shader_animation: bool,
122        cursor_shader_animation: bool,
123    ) {
124        if let Some(ref mut custom_shader) = self.custom_shader_renderer {
125            custom_shader.set_animation_enabled(custom_shader_animation);
126        }
127        if let Some(ref mut cursor_shader) = self.cursor_shader_renderer {
128            cursor_shader.set_animation_enabled(cursor_shader_animation);
129        }
130        self.dirty = true;
131        log::info!(
132            "[SHADER] Shader animations resumed (custom: {}, cursor: {})",
133            custom_shader_animation,
134            cursor_shader_animation
135        );
136    }
137}