Add user preference to show waveforms as stacked stereo

This commit is contained in:
Skyler Lehmkuhl 2026-02-15 04:50:33 -05:00
parent c6a8b944e5
commit 6fcee92d59
5 changed files with 25 additions and 2 deletions

View File

@ -45,6 +45,10 @@ pub struct AppConfig {
#[serde(default = "defaults::debug")] #[serde(default = "defaults::debug")]
pub debug: bool, pub debug: bool,
/// Show waveforms as stacked stereo instead of combined mono
#[serde(default = "defaults::waveform_stereo")]
pub waveform_stereo: bool,
/// Theme mode ("light", "dark", or "system") /// Theme mode ("light", "dark", or "system")
#[serde(default = "defaults::theme_mode")] #[serde(default = "defaults::theme_mode")]
pub theme_mode: String, pub theme_mode: String,
@ -63,6 +67,7 @@ impl Default for AppConfig {
reopen_last_session: defaults::reopen_last_session(), reopen_last_session: defaults::reopen_last_session(),
restore_layout_from_file: defaults::restore_layout_from_file(), restore_layout_from_file: defaults::restore_layout_from_file(),
debug: defaults::debug(), debug: defaults::debug(),
waveform_stereo: defaults::waveform_stereo(),
theme_mode: defaults::theme_mode(), theme_mode: defaults::theme_mode(),
} }
} }
@ -263,5 +268,6 @@ mod defaults {
pub fn reopen_last_session() -> bool { false } pub fn reopen_last_session() -> bool { false }
pub fn restore_layout_from_file() -> bool { true } pub fn restore_layout_from_file() -> bool { true }
pub fn debug() -> bool { false } pub fn debug() -> bool { false }
pub fn waveform_stereo() -> bool { false }
pub fn theme_mode() -> String { "system".to_string() } pub fn theme_mode() -> String { "system".to_string() }
} }

View File

@ -4389,6 +4389,7 @@ impl eframe::App for EditorApp {
target_format: self.target_format, target_format: self.target_format,
pending_menu_actions: &mut pending_menu_actions, pending_menu_actions: &mut pending_menu_actions,
clipboard_manager: &mut self.clipboard_manager, clipboard_manager: &mut self.clipboard_manager,
waveform_stereo: self.config.waveform_stereo,
}; };
render_layout_node( render_layout_node(
@ -4661,6 +4662,8 @@ struct RenderContext<'a> {
pending_menu_actions: &'a mut Vec<MenuAction>, pending_menu_actions: &'a mut Vec<MenuAction>,
/// Clipboard manager for paste availability checks /// Clipboard manager for paste availability checks
clipboard_manager: &'a mut lightningbeam_core::clipboard::ClipboardManager, clipboard_manager: &'a mut lightningbeam_core::clipboard::ClipboardManager,
/// Whether to show waveforms as stacked stereo
waveform_stereo: bool,
} }
/// Recursively render a layout node with drag support /// Recursively render a layout node with drag support
@ -5141,6 +5144,7 @@ fn render_pane(
target_format: ctx.target_format, target_format: ctx.target_format,
pending_menu_actions: ctx.pending_menu_actions, pending_menu_actions: ctx.pending_menu_actions,
clipboard_manager: ctx.clipboard_manager, clipboard_manager: ctx.clipboard_manager,
waveform_stereo: ctx.waveform_stereo,
}; };
pane_instance.render_header(&mut header_ui, &mut shared); pane_instance.render_header(&mut header_ui, &mut shared);
} }
@ -5210,6 +5214,7 @@ fn render_pane(
target_format: ctx.target_format, target_format: ctx.target_format,
pending_menu_actions: ctx.pending_menu_actions, pending_menu_actions: ctx.pending_menu_actions,
clipboard_manager: ctx.clipboard_manager, clipboard_manager: ctx.clipboard_manager,
waveform_stereo: ctx.waveform_stereo,
}; };
// Render pane content (header was already rendered above) // Render pane content (header was already rendered above)

View File

@ -215,6 +215,8 @@ pub struct SharedPaneState<'a> {
pub pending_menu_actions: &'a mut Vec<crate::menu::MenuAction>, pub pending_menu_actions: &'a mut Vec<crate::menu::MenuAction>,
/// Clipboard manager for cut/copy/paste operations /// Clipboard manager for cut/copy/paste operations
pub clipboard_manager: &'a mut lightningbeam_core::clipboard::ClipboardManager, pub clipboard_manager: &'a mut lightningbeam_core::clipboard::ClipboardManager,
/// Whether to show waveforms as stacked stereo (true) or combined mono (false)
pub waveform_stereo: bool,
} }
/// Trait for pane rendering /// Trait for pane rendering

View File

@ -928,6 +928,7 @@ impl TimelinePane {
raw_audio_cache: &std::collections::HashMap<usize, (Vec<f32>, u32, u32)>, raw_audio_cache: &std::collections::HashMap<usize, (Vec<f32>, u32, u32)>,
waveform_gpu_dirty: &mut std::collections::HashSet<usize>, waveform_gpu_dirty: &mut std::collections::HashSet<usize>,
target_format: wgpu::TextureFormat, target_format: wgpu::TextureFormat,
waveform_stereo: bool,
) -> Vec<(egui::Rect, uuid::Uuid, f64, f64)> { ) -> Vec<(egui::Rect, uuid::Uuid, f64, f64)> {
let painter = ui.painter(); let painter = ui.painter();
@ -1273,7 +1274,7 @@ impl TimelinePane {
tex_width: crate::waveform_gpu::tex_width() as f32, tex_width: crate::waveform_gpu::tex_width() as f32,
total_frames: total_frames as f32, total_frames: total_frames as f32,
segment_start_frame: 0.0, segment_start_frame: 0.0,
display_mode: 0.0, display_mode: if waveform_stereo { 1.0 } else { 0.0 },
_pad1: [0.0, 0.0], _pad1: [0.0, 0.0],
tint_color: tint, tint_color: tint,
screen_size: [screen_size.x, screen_size.y], screen_size: [screen_size.x, screen_size.y],
@ -2154,7 +2155,7 @@ impl PaneRenderer for TimelinePane {
// Render layer rows with clipping // Render layer rows with clipping
ui.set_clip_rect(content_rect.intersect(original_clip_rect)); ui.set_clip_rect(content_rect.intersect(original_clip_rect));
let video_clip_hovers = self.render_layers(ui, content_rect, shared.theme, document, shared.active_layer_id, shared.selection, shared.midi_event_cache, shared.raw_audio_cache, shared.waveform_gpu_dirty, shared.target_format); let video_clip_hovers = self.render_layers(ui, content_rect, shared.theme, document, shared.active_layer_id, shared.selection, shared.midi_event_cache, shared.raw_audio_cache, shared.waveform_gpu_dirty, shared.target_format, shared.waveform_stereo);
// Render playhead on top (clip to timeline area) // Render playhead on top (clip to timeline area)
ui.set_clip_rect(timeline_rect.intersect(original_clip_rect)); ui.set_clip_rect(timeline_rect.intersect(original_clip_rect));

View File

@ -33,6 +33,7 @@ struct PreferencesState {
reopen_last_session: bool, reopen_last_session: bool,
restore_layout_from_file: bool, restore_layout_from_file: bool,
debug: bool, debug: bool,
waveform_stereo: bool,
theme_mode: ThemeMode, theme_mode: ThemeMode,
} }
@ -48,6 +49,7 @@ impl From<(&AppConfig, &Theme)> for PreferencesState {
reopen_last_session: config.reopen_last_session, reopen_last_session: config.reopen_last_session,
restore_layout_from_file: config.restore_layout_from_file, restore_layout_from_file: config.restore_layout_from_file,
debug: config.debug, debug: config.debug,
waveform_stereo: config.waveform_stereo,
theme_mode: theme.mode(), theme_mode: theme.mode(),
} }
} }
@ -65,6 +67,7 @@ impl Default for PreferencesState {
reopen_last_session: false, reopen_last_session: false,
restore_layout_from_file: true, restore_layout_from_file: true,
debug: false, debug: false,
waveform_stereo: false,
theme_mode: ThemeMode::System, theme_mode: ThemeMode::System,
} }
} }
@ -335,6 +338,10 @@ impl PreferencesDialog {
.default_open(false) .default_open(false)
.show(ui, |ui| { .show(ui, |ui| {
ui.checkbox(&mut self.working_prefs.debug, "Enable debug mode"); ui.checkbox(&mut self.working_prefs.debug, "Enable debug mode");
ui.checkbox(
&mut self.working_prefs.waveform_stereo,
"Show waveforms as stacked stereo",
);
}); });
} }
@ -359,6 +366,7 @@ impl PreferencesDialog {
temp_config.reopen_last_session = self.working_prefs.reopen_last_session; temp_config.reopen_last_session = self.working_prefs.reopen_last_session;
temp_config.restore_layout_from_file = self.working_prefs.restore_layout_from_file; temp_config.restore_layout_from_file = self.working_prefs.restore_layout_from_file;
temp_config.debug = self.working_prefs.debug; temp_config.debug = self.working_prefs.debug;
temp_config.waveform_stereo = self.working_prefs.waveform_stereo;
temp_config.theme_mode = self.working_prefs.theme_mode.to_string_lower(); temp_config.theme_mode = self.working_prefs.theme_mode.to_string_lower();
// Validate // Validate
@ -380,6 +388,7 @@ impl PreferencesDialog {
config.reopen_last_session = self.working_prefs.reopen_last_session; config.reopen_last_session = self.working_prefs.reopen_last_session;
config.restore_layout_from_file = self.working_prefs.restore_layout_from_file; config.restore_layout_from_file = self.working_prefs.restore_layout_from_file;
config.debug = self.working_prefs.debug; config.debug = self.working_prefs.debug;
config.waveform_stereo = self.working_prefs.waveform_stereo;
config.theme_mode = self.working_prefs.theme_mode.to_string_lower(); config.theme_mode = self.working_prefs.theme_mode.to_string_lower();
// Apply theme immediately // Apply theme immediately