Skip to content

Commit

Permalink
refactor: drop FramerateOption
Browse files Browse the repository at this point in the history
  • Loading branch information
SeaDve committed Mar 29, 2024
1 parent a1b3439 commit a0ddbcd
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 184 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ gst-plugin-gtk4 = { version = "0.12", features = [
"x11glx",
] }
gtk = { package = "gtk4", version = "0.8", features = ["gnome_46"] }
num-traits = "0.2"
once_cell = "1.19.0"
serde_yaml = "0.9.31"
serde = { version = "1.0.196", features = ["derive"] }
Expand Down
86 changes: 86 additions & 0 deletions src/framerate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use std::sync::OnceLock;

use gtk::{gio, glib::BoxedAnyObject};

use crate::settings::Settings;

/// Built-in framerates.
fn builtins() -> &'static [gst::Fraction] {
static BUILTINS: OnceLock<Vec<gst::Fraction>> = OnceLock::new();

BUILTINS.get_or_init(|| {
vec![
gst::Fraction::from_integer(10),
gst::Fraction::from_integer(20),
gst::Fraction::from_integer(24),
gst::Fraction::from_integer(25),
gst::Fraction::new(30_000, 1001), // 29.97
gst::Fraction::from_integer(30),
gst::Fraction::from_integer(48),
gst::Fraction::from_integer(50),
gst::Fraction::new(60_000, 1001), // 59.94
gst::Fraction::from_integer(60),
]
})
}

/// Returns a model of type `BoxedAnyObject`.
///
/// This appends the current framerate in the settings if it does not match any built-in ones.
pub fn builtins_model(settings: &Settings) -> gio::ListStore {
let list_store = gio::ListStore::new::<BoxedAnyObject>();

let items = builtins()
.iter()
.map(|fraction| BoxedAnyObject::new(*fraction))
.collect::<Vec<_>>();
list_store.splice(0, 0, &items);

let other = settings.framerate();
if !builtins().contains(&other) {
list_store.append(&BoxedAnyObject::new(other));
}

list_store
}

/// Formats a framerate in a human-readable format.
pub fn format(framerate: gst::Fraction) -> String {
let reduced = framerate.reduced();

if reduced.is_integer() {
return reduced.numer().to_string();
}

let float = *reduced.numer() as f64 / *reduced.denom() as f64;
format!("{:.2}", float)
}

#[cfg(test)]
mod tests {
use super::*;

#[track_caller]
fn assert_simplified(framerate: gst::Fraction) {
let reduced = framerate.0.reduced();

assert_eq!(
(framerate.numer(), framerate.denom()),
(*reduced.numer(), *reduced.denom())
);
}

#[test]
fn simplified() {
for framerate in builtins() {
assert_simplified(*framerate);
}
}

#[test]
fn test_format() {
assert_eq!(format(gst::Fraction::from_integer(24)), "24");
assert_eq!(format(gst::Fraction::new(30_000, 1001)), "29.97");
assert_eq!(format(gst::Fraction::new(60_000, 1001)), "59.94");
}
}
159 changes: 0 additions & 159 deletions src/framerate_option.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ mod config;
mod device;
mod experimental;
mod format_time;
mod framerate_option;
mod framerate;
mod help;
mod i18n;
mod item_row;
Expand Down
36 changes: 18 additions & 18 deletions src/preferences_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ use gtk::{
};

use crate::{
experimental::Feature, framerate_option::FramerateOption, item_row::ItemRow, profile::Profile,
settings::Settings,
experimental::Feature, framerate, item_row::ItemRow, profile::Profile, settings::Settings,
};

const ROW_SELECTED_ITEM_NOTIFY_HANDLER_ID_KEY: &str = "kooha-row-selected-item-notify-handler-id";
Expand Down Expand Up @@ -114,12 +113,11 @@ mod imp {
self.framerate_row
.connect_selected_item_notify(clone!(@weak obj => move |row| {
if let Some(item) = row.selected_item() {
let framerate_option = item
let framerate = item
.downcast_ref::<BoxedAnyObject>()
.unwrap()
.borrow::<FramerateOption>();
obj.settings()
.set_framerate(framerate_option.as_framerate());
.borrow::<gst::Fraction>();
obj.settings().set_framerate(*framerate);
}
}));
}
Expand Down Expand Up @@ -182,18 +180,18 @@ impl PreferencesDialog {
let imp = self.imp();

let settings = self.settings();
let framerate_option = FramerateOption::from_framerate(settings.framerate());
let framerate = settings.framerate();

let model = imp.framerate_row.model().unwrap();
let position = model
.iter::<BoxedAnyObject>()
.position(|item| *item.unwrap().borrow::<FramerateOption>() == framerate_option);
.position(|item| *item.unwrap().borrow::<gst::Fraction>() == framerate);
if let Some(position) = position {
imp.framerate_row.set_selected(position as u32);
} else {
tracing::error!(
"Active framerate `{:?}` was not found on framerate model",
framerate_option
framerate
);
}
}
Expand All @@ -210,11 +208,11 @@ impl PreferencesDialog {
let item = list_item.item().unwrap();
let item_row = list_item.child().unwrap().downcast::<ItemRow>().unwrap();

let framerate_option = item
let framerate = item
.downcast_ref::<BoxedAnyObject>()
.unwrap()
.borrow::<FramerateOption>();
item_row.set_title(framerate_option.to_string());
.borrow::<gst::Fraction>();
item_row.set_title(framerate::format(*framerate));

unsafe {
list_item.set_data(
Expand All @@ -239,7 +237,7 @@ impl PreferencesDialog {
}),
)));

let framerate_model = FramerateOption::model(&settings);
let framerate_model = framerate::builtins_model(&settings);
imp.framerate_row.set_model(Some(&framerate_model));

imp.profile_row.set_factory(Some(&row_factory(
Expand Down Expand Up @@ -361,14 +359,16 @@ fn update_framerate_row_shows_warning_icon(settings: &Settings, list_item: &gtk:
let item_row = list_item.child().unwrap().downcast::<ItemRow>().unwrap();
let item = list_item.item().unwrap();

let framerate_option = item
let framerate = item
.downcast_ref::<BoxedAnyObject>()
.unwrap()
.borrow::<FramerateOption>();
.borrow::<gst::Fraction>();

item_row.set_shows_warning_icon(settings.profile().is_some_and(|profile| {
framerate_option.as_framerate() > profile.suggested_max_framerate()
}));
item_row.set_shows_warning_icon(
settings
.profile()
.is_some_and(|profile| *framerate > profile.suggested_max_framerate()),
);
}

/// Returns `Some` if the object is a `Profile`, otherwise `None`, if the object is a `NoneProfile`.
Expand Down
7 changes: 3 additions & 4 deletions src/window/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ use self::{progress_icon::ProgressIcon, toggle_button::ToggleButton};
use crate::{
cancelled::Cancelled,
config::PROFILE,
format_time,
framerate_option::FramerateOption,
format_time, framerate,
help::ContextWithHelp,
preferences_dialog::PreferencesDialog,
recording::{NoProfileError, Recording, RecordingState},
Expand Down Expand Up @@ -533,10 +532,10 @@ impl Window {
let profile_text = settings
.profile()
.map_or_else(|| gettext("None"), |profile| profile.name().to_string());
let framerate_option = FramerateOption::from_framerate(settings.framerate());
let framerate_text = framerate::format(settings.framerate());

imp.title
.set_subtitle(&format!("{} • {} FPS", profile_text, framerate_option));
.set_subtitle(&format!("{} • {} FPS", profile_text, framerate_text));
}

fn update_audio_actions(&self) {
Expand Down

0 comments on commit a0ddbcd

Please sign in to comment.