From 338babaad2189f7ff1ee088994c8c20a0646ff4d Mon Sep 17 00:00:00 2001 From: Malte Voos Date: Wed, 1 Oct 2025 00:20:10 +0200 Subject: init --- src/subtitle_view.rs | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/subtitle_view.rs (limited to 'src/subtitle_view.rs') diff --git a/src/subtitle_view.rs b/src/subtitle_view.rs new file mode 100644 index 0000000..30c089c --- /dev/null +++ b/src/subtitle_view.rs @@ -0,0 +1,94 @@ +use crate::cue_view::{CueView, CueViewMsg, CueViewOutput}; +use crate::util::OptionTracker; +use gtk::prelude::*; +use relm4::prelude::*; + +pub struct SubtitleView { + primary_cue: Controller, + secondary_cue: OptionTracker, +} + +#[derive(Debug)] +pub enum SubtitleViewMsg { + SetPrimaryCue(Option), + SetSecondaryCue(Option), +} + +#[derive(Debug)] +pub enum SubtitleViewOutput { + SetHoveringCue(bool), +} + +#[relm4::component(pub)] +impl SimpleComponent for SubtitleView { + type Init = (); + type Input = SubtitleViewMsg; + type Output = SubtitleViewOutput; + + view! { + gtk::ScrolledWindow { + gtk::Box { + set_orientation: gtk::Orientation::Vertical, + set_vexpand: true, + set_halign: gtk::Align::Center, + + gtk::Box { + set_vexpand: true, + }, + + model.primary_cue.widget(), + + gtk::Box { + set_vexpand: true, + }, + + gtk::Label { + #[track = "model.secondary_cue.is_dirty()"] + set_text: model.secondary_cue.get().as_ref().map(|val| val.as_str()).unwrap_or("TODO placeholder"), + set_justify: gtk::Justification::Center, + }, + + gtk::Box { + set_vexpand: true, + }, + } + }, + } + + fn init( + _init: Self::Init, + root: Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = Self { + primary_cue: CueView::builder() + .launch(()) + .forward(sender.output_sender(), |output| match output { + CueViewOutput::MouseEnter => SubtitleViewOutput::SetHoveringCue(true), + CueViewOutput::MouseLeave => SubtitleViewOutput::SetHoveringCue(false), + }), + secondary_cue: OptionTracker::default(), + }; + + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update(&mut self, msg: Self::Input, _sender: ComponentSender) { + // Reset trackers + self.secondary_cue.reset(); + + match msg { + SubtitleViewMsg::SetPrimaryCue(value) => { + self.primary_cue + .sender() + .send(CueViewMsg::SetText(value)) + .unwrap(); + } + SubtitleViewMsg::SetSecondaryCue(value) => { + self.secondary_cue.set(value); + } + } + } +} -- cgit 1.4.1