aboutsummaryrefslogtreecommitdiff
path: root/src/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app.rs')
-rw-r--r--src/app.rs146
1 files changed, 49 insertions, 97 deletions
diff --git a/src/app.rs b/src/app.rs
index 10c20e6..18f03e8 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,6 +1,4 @@
use adw::prelude::*;
-use gst::glib::clone;
-use gtk::gio::{Menu, MenuItem, SimpleAction, SimpleActionGroup};
use relm4::{WorkerController, prelude::*};
use crate::{
@@ -9,13 +7,14 @@ use crate::{
subtitle_extractor::{
StreamIndex, SubtitleExtractor, SubtitleExtractorMsg, SubtitleExtractorOutput, TRACKS,
},
+ subtitle_selection_dialog::{
+ SubtitleSelectionDialog, SubtitleSelectionDialogMsg, SubtitleSelectionDialogOutput,
+ },
subtitle_view::{SubtitleView, SubtitleViewMsg, SubtitleViewOutput},
transcript::{Transcript, TranscriptMsg, TranscriptOutput},
util::OptionTracker,
};
-const TRACK_SELECTION_ACTION_GROUP_NAME: &str = "subtitle_track_selection";
-
pub struct App {
url: String,
transcript: Controller<Transcript>,
@@ -23,9 +22,7 @@ pub struct App {
subtitle_view: Controller<SubtitleView>,
extractor: WorkerController<SubtitleExtractor>,
preferences: Controller<Preferences>,
-
- subtitle_selection_menu: Menu,
- subtitle_selection_action_group: SimpleActionGroup,
+ subtitle_selection_dialog: Controller<SubtitleSelectionDialog>,
primary_stream_ix: Option<StreamIndex>,
primary_last_cue_ix: OptionTracker<usize>,
@@ -42,11 +39,13 @@ pub struct App {
pub enum AppMsg {
NewOrUpdatedTrackMetadata(StreamIndex),
NewCue(StreamIndex, crate::subtitle_extractor::SubtitleCue),
- ExtractionComplete,
- TrackSelected(StreamIndex),
+ SubtitleExtractionComplete,
+ PrimarySubtitleTrackSelected(Option<StreamIndex>),
+ SecondarySubtitleTrackSelected(Option<StreamIndex>),
PositionUpdate(gst::ClockTime),
SetHoveringSubtitleCue(bool),
ShowPreferences,
+ ShowSubtitleSelectionDialog,
}
#[relm4::component(pub)]
@@ -65,14 +64,9 @@ impl SimpleComponent for App {
#[name(toolbar_view)]
adw::ToolbarView {
add_top_bar = &adw::HeaderBar {
- pack_start = &gtk::MenuButton {
- set_label: "Select Subtitle Track",
- set_popover: Some(&gtk::PopoverMenu::from_model(Some(&model.subtitle_selection_menu))),
- },
pack_start = &gtk::Button {
- set_label: "Preferences",
+ set_icon_name: "settings-symbolic",
connect_clicked => AppMsg::ShowPreferences,
- add_css_class: "flat",
}
},
@@ -96,14 +90,6 @@ impl SimpleComponent for App {
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
- let subtitle_selection_menu = Menu::new();
- let subtitle_selection_action_group = SimpleActionGroup::new();
- root.insert_action_group(
- TRACK_SELECTION_ACTION_GROUP_NAME,
- Some(&subtitle_selection_action_group),
- );
- Self::add_dummy_menu_item(&subtitle_selection_action_group, &subtitle_selection_menu);
-
let subtitle_view = SubtitleView::builder().launch(()).forward(
sender.input_sender(),
|output| match output {
@@ -114,6 +100,7 @@ impl SimpleComponent for App {
.launch(())
.forward(sender.input_sender(), |output| match output {
PlayerOutput::PositionUpdate(pos) => AppMsg::PositionUpdate(pos),
+ PlayerOutput::SubtitleSelectionButtonPressed => AppMsg::ShowSubtitleSelectionDialog,
});
let transcript =
Transcript::builder()
@@ -131,11 +118,21 @@ impl SimpleComponent for App {
SubtitleExtractorOutput::NewCue(stream_index, cue) => {
AppMsg::NewCue(stream_index, cue)
}
- SubtitleExtractorOutput::ExtractionComplete => AppMsg::ExtractionComplete,
+ SubtitleExtractorOutput::ExtractionComplete => AppMsg::SubtitleExtractionComplete,
},
);
let preferences = Preferences::builder().launch(root.clone().into()).detach();
+ let subtitle_selection_dialog = SubtitleSelectionDialog::builder()
+ .launch(root.clone().into())
+ .forward(sender.input_sender(), |output| match output {
+ SubtitleSelectionDialogOutput::PrimaryTrackSelected(ix) => {
+ AppMsg::PrimarySubtitleTrackSelected(ix)
+ }
+ SubtitleSelectionDialogOutput::SecondaryTrackSelected(ix) => {
+ AppMsg::SecondarySubtitleTrackSelected(ix)
+ }
+ });
let model = Self {
url: url.clone(), // TODO remove clone
@@ -144,8 +141,7 @@ impl SimpleComponent for App {
subtitle_view,
extractor,
preferences,
- subtitle_selection_menu,
- subtitle_selection_action_group,
+ subtitle_selection_dialog,
primary_stream_ix: None,
primary_last_cue_ix: OptionTracker::new(None),
@@ -173,31 +169,32 @@ impl SimpleComponent for App {
ComponentParts { model, widgets }
}
- fn update(&mut self, msg: Self::Input, sender: ComponentSender<Self>) {
+ fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
self.primary_last_cue_ix.reset();
self.secondary_last_cue_ix.reset();
match msg {
- AppMsg::NewOrUpdatedTrackMetadata(_stream_index) => {
- self.update_subtitle_selection_menu(&sender);
- }
+ AppMsg::NewOrUpdatedTrackMetadata(_stream_index) => {}
AppMsg::NewCue(stream_index, cue) => {
self.transcript
.sender()
.send(TranscriptMsg::NewCue(stream_index, cue))
.unwrap();
}
- AppMsg::ExtractionComplete => {
- println!("Subtitle extraction complete");
+ AppMsg::SubtitleExtractionComplete => {
+ log::info!("Subtitle extraction complete");
}
- AppMsg::TrackSelected(stream_index) => {
- self.primary_stream_ix = Some(stream_index);
+ AppMsg::PrimarySubtitleTrackSelected(stream_index) => {
+ self.primary_stream_ix = stream_index;
self.transcript
.sender()
.send(TranscriptMsg::SelectTrack(stream_index))
.unwrap();
}
+ AppMsg::SecondarySubtitleTrackSelected(stream_index) => {
+ self.secondary_stream_ix = stream_index;
+ }
AppMsg::PositionUpdate(pos) => {
if let Some(stream_ix) = self.primary_stream_ix {
let cue =
@@ -239,14 +236,18 @@ impl SimpleComponent for App {
}
}
if let Some(stream_ix) = self.secondary_stream_ix {
- self.subtitle_view
- .sender()
- .send(SubtitleViewMsg::SetPrimaryCue(Self::get_cue_and_update_ix(
- stream_ix,
- pos,
- &mut self.primary_last_cue_ix,
- )))
- .unwrap();
+ if !self.autopaused {
+ self.subtitle_view
+ .sender()
+ .send(SubtitleViewMsg::SetSecondaryCue(
+ Self::get_cue_and_update_ix(
+ stream_ix,
+ pos,
+ &mut self.secondary_last_cue_ix,
+ ),
+ ))
+ .unwrap();
+ }
}
}
AppMsg::SetHoveringSubtitleCue(hovering) => {
@@ -262,66 +263,17 @@ impl SimpleComponent for App {
.send(PreferencesMsg::Show)
.unwrap();
}
+ AppMsg::ShowSubtitleSelectionDialog => {
+ self.subtitle_selection_dialog
+ .sender()
+ .send(SubtitleSelectionDialogMsg::Show)
+ .unwrap();
+ }
}
}
}
impl App {
- fn update_subtitle_selection_menu(&mut self, sender: &ComponentSender<Self>) {
- self.subtitle_selection_menu.remove_all();
-
- for action_name in self.subtitle_selection_action_group.list_actions() {
- self.subtitle_selection_action_group
- .remove_action(&action_name);
- }
-
- let tracks = TRACKS.read();
- if tracks.is_empty() {
- Self::add_dummy_menu_item(
- &self.subtitle_selection_action_group,
- &self.subtitle_selection_menu,
- );
- } else {
- for (stream_index, track) in tracks.iter() {
- let unknown_string = "<unknown>".to_string();
- let language = track.language_code.as_ref().unwrap_or(&unknown_string);
- let label = format!("{} (Stream {})", language, stream_index);
-
- let action_name = format!("select_{}", stream_index);
- let action = SimpleAction::new(&action_name, None);
-
- action.connect_activate(clone!(
- #[strong]
- sender,
- #[strong]
- stream_index,
- move |_, _| {
- let _ = sender.input(AppMsg::TrackSelected(stream_index));
- }
- ));
-
- self.subtitle_selection_action_group.add_action(&action);
-
- // Create menu item
- let action_target =
- format!("{}.{}", TRACK_SELECTION_ACTION_GROUP_NAME, action_name);
- let item = MenuItem::new(Some(&label), Some(&action_target));
- self.subtitle_selection_menu.append_item(&item);
- }
- }
- }
-
- // Add disabled "No tracks available" item
- fn add_dummy_menu_item(action_group: &SimpleActionGroup, menu: &Menu) {
- let disabled_action = SimpleAction::new("no_tracks", None);
- disabled_action.set_enabled(false);
- action_group.add_action(&disabled_action);
-
- let action_target = format!("{}.no_tracks", TRACK_SELECTION_ACTION_GROUP_NAME);
- let item = MenuItem::new(Some("No tracks available"), Some(&action_target));
- menu.append_item(&item);
- }
-
fn get_cue_and_update_ix(
stream_ix: StreamIndex,
position: gst::ClockTime,