summary refs log tree commit diff
path: root/src/subtitle_view.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/subtitle_view.rs')
-rw-r--r--src/subtitle_view.rs94
1 files changed, 94 insertions, 0 deletions
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<CueView>,
+    secondary_cue: OptionTracker<String>,
+}
+
+#[derive(Debug)]
+pub enum SubtitleViewMsg {
+    SetPrimaryCue(Option<String>),
+    SetSecondaryCue(Option<String>),
+}
+
+#[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<Self>,
+    ) -> ComponentParts<Self> {
+        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<Self>) {
+        // 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);
+            }
+        }
+    }
+}