Files
simple-multimidia-track-aud…/src/ui/components/add_audio_track_form.rs
T
Felipe 1ef47b3a07 feat: add AdjustExistingTrackDrift use case to adjust drift scale of existing tracks
- Implemented AdjustExistingTrackDrift struct with execute method to modify drift scale of existing tracks in a project.
- Added tests for adjusting drift scale, handling non-existent track IDs, and invalid scale values.
- Updated MediaTrackInfo and AudioTrack entities to include drift_scale field.
- Enhanced Project entity with needs_mkvmerge method to determine if mkvmerge is required based on drift scale.
- Integrated drift scale adjustments into existing track list UI, allowing users to modify drift values.
- Updated various use cases and UI components to support drift scale functionality, including add audio/subtitle forms and batch processing.
- Implemented mkvmerge availability check and integrated it into the application workflow for conditional processing.
2026-03-01 12:01:39 -03:00

109 lines
4.0 KiB
Rust

use crate::adapters::filesystem::FilePickerAdapter;
use crate::domain::value_objects::{FilePath, SyncOffset, TrackLanguage};
use crate::ui::components::{language_field::LanguageField, sync_offset_field::SyncOffsetField};
use eframe::egui;
/// Evento emitido ao confirmar adição de faixa de áudio.
pub struct AddAudioTrackRequest {
pub path: FilePath,
pub offset: SyncOffset,
pub language: TrackLanguage,
pub is_default: bool,
pub title: String,
/// Fator de escala temporal (correção de drift). 1.0 = sem correção.
pub drift_scale: f64,
}
/// Formulário para adicionar uma faixa de áudio externa.
pub struct AddAudioTrackForm {
selected_path: Option<FilePath>,
offset_field: SyncOffsetField,
language_field: LanguageField,
is_default: bool,
title_input: String,
}
impl AddAudioTrackForm {
pub fn new() -> Self {
AddAudioTrackForm {
selected_path: None,
offset_field: SyncOffsetField::new(SyncOffset::default()),
language_field: LanguageField::new(None),
is_default: false,
title_input: String::new(),
}
}
/// Renderiza o formulário. Retorna `Some(request)` ao confirmar.
pub fn ui(&mut self, ui: &mut egui::Ui, mkvmerge_available: bool) -> Option<AddAudioTrackRequest> {
let mut result = None;
ui.group(|ui| {
ui.heading("Adicionar faixa de áudio");
ui.horizontal(|ui| {
let label = self
.selected_path
.as_ref()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|| "Nenhum arquivo".to_string());
ui.label(&label);
if ui.button("Selecionar áudio…").clicked() {
self.selected_path = FilePickerAdapter::pick_audio();
}
});
self.offset_field.ui_with_drift(ui, "Atraso:", mkvmerge_available);
self.language_field.ui(ui);
ui.horizontal(|ui| {
ui.label("Nome da faixa:");
ui.text_edit_singleline(&mut self.title_input)
.on_hover_text(
"Nome exibido no player (ex: \"Português\", \"Comentários\").\n\
Deixe vazio para remover o nome original do arquivo fonte.\n\
Recomendado para evitar nomes como \"ISO Media file produced by Google Inc.\"",
);
});
ui.checkbox(&mut self.is_default, "Definir como faixa padrão")
.on_hover_text(
"Marca esta faixa como padrão no container MKV.\n\
Recomendado para que players como Jellyfin selecionem este áudio automaticamente.",
);
ui.add_space(4.0);
let can_add = self.selected_path.is_some();
if ui
.add_enabled(can_add, egui::Button::new("Adicionar"))
.clicked()
{
if let (Some(path), Some(offset), Some(language)) = (
self.selected_path.clone(),
self.offset_field.parse(),
self.language_field.parse(),
) {
let drift_scale = self.offset_field.parse_drift();
result = Some(AddAudioTrackRequest {
path,
offset,
language,
is_default: self.is_default,
title: self.title_input.trim().to_string(),
drift_scale,
});
// Reset form
self.selected_path = None;
self.offset_field = SyncOffsetField::new(SyncOffset::default());
self.language_field = LanguageField::new(None);
self.is_default = false;
self.title_input = String::new();
}
}
});
result
}
}