diff --git a/hammond-gtk/resources/gtk/player_toolbar.ui b/hammond-gtk/resources/gtk/player_toolbar.ui
index bea3fc4..d766706 100644
--- a/hammond-gtk/resources/gtk/player_toolbar.ui
+++ b/hammond-gtk/resources/gtk/player_toolbar.ui
@@ -250,9 +250,122 @@
+
+ 3
+
+
+
+
4
+
diff --git a/hammond-gtk/src/widgets/player.rs b/hammond-gtk/src/widgets/player.rs
index 5368167..eaa28d2 100644
--- a/hammond-gtk/src/widgets/player.rs
+++ b/hammond-gtk/src/widgets/player.rs
@@ -35,8 +35,7 @@ pub trait PlayerExt {
fn seek(&self, offset: ClockTime, direction: SeekDirection);
fn fast_forward(&self);
fn rewind(&self);
- // TODO: change playback rate
- // fn set_playback_rate(&self);
+ fn set_playback_rate(&self, f64);
}
#[derive(Debug, Clone)]
@@ -136,6 +135,16 @@ fn format_duration(seconds: u32) -> String {
}
}
+#[derive(Debug, Clone)]
+struct PlayerRate {
+ radio150: gtk::RadioButton,
+ radio125: gtk::RadioButton,
+ radio_normal: gtk::RadioButton,
+ popover: gtk::Popover,
+ btn: gtk::MenuButton,
+ label: gtk::Label,
+}
+
#[derive(Debug, Clone)]
struct PlayerControls {
container: gtk::Box,
@@ -152,6 +161,7 @@ pub struct PlayerWidget {
controls: PlayerControls,
pub timer: PlayerTimes,
info: PlayerInfo,
+ rate: PlayerRate,
}
impl Default for PlayerWidget {
@@ -207,12 +217,28 @@ impl Default for PlayerWidget {
cover,
};
+ let radio150 = builder.get_object("rate_1_50").unwrap();
+ let radio125 = builder.get_object("rate_1_25").unwrap();
+ let radio_normal = builder.get_object("normal_rate").unwrap();
+ let popover = builder.get_object("rate_popover").unwrap();
+ let btn = builder.get_object("rate_button").unwrap();
+ let label = builder.get_object("rate_label").unwrap();
+ let rate = PlayerRate {
+ radio150,
+ radio125,
+ radio_normal,
+ popover,
+ label,
+ btn,
+ };
+
PlayerWidget {
player,
action_bar,
controls,
timer,
info,
+ rate,
}
}
}
@@ -226,7 +252,8 @@ impl PlayerWidget {
#[cfg_attr(rustfmt, rustfmt_skip)]
fn init(s: &Rc, sender: &Sender) {
- Self::connect_buttons(s);
+ Self::connect_control_buttons(s);
+ Self::connect_rate_buttons(s);
// Log gst warnings.
s.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
@@ -261,7 +288,7 @@ impl PlayerWidget {
#[cfg_attr(rustfmt, rustfmt_skip)]
/// Connect the `PlayerControls` buttons to the `PlayerExt` methods.
- fn connect_buttons(s: &Rc) {
+ fn connect_control_buttons(s: &Rc) {
// Connect the play button to the gst Player.
s.controls.play.connect_clicked(clone!(s => move |_| s.play()));
@@ -275,6 +302,18 @@ impl PlayerWidget {
s.controls.forward.connect_clicked(clone!(s => move |_| s.fast_forward()));
}
+ #[cfg_attr(rustfmt, rustfmt_skip)]
+ fn connect_rate_buttons(s: &Rc) {
+ s.rate.radio_normal.connect_toggled(clone!(s => move |_| s.on_rate_changed(1.00)));
+ s.rate.radio125.connect_toggled(clone!(s => move |_| s.on_rate_changed(1.25)));
+ s.rate.radio150.connect_toggled(clone!(s => move |_| s.on_rate_changed(1.50)));
+ }
+
+ fn on_rate_changed(&self, rate: f64) {
+ self.set_playback_rate(rate);
+ self.rate.label.set_text(&format!("{:.2}x", rate));
+ }
+
fn reveal(&self) {
self.action_bar.show();
}
@@ -370,4 +409,8 @@ impl PlayerExt for PlayerWidget {
fn fast_forward(&self) {
self.seek(ClockTime::from_seconds(10), SeekDirection::Forward)
}
+
+ fn set_playback_rate(&self, rate: f64) {
+ self.player.set_rate(rate);
+ }
}