mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
Add preferences for default program
This commit is contained in:
parent
653d5cd629
commit
fa94d61e1e
11 changed files with 367 additions and 28 deletions
|
|
@ -629,14 +629,14 @@ impl Library {
|
|||
(
|
||||
UNIXEPOCH('now', 'localtime') - UNIXEPOCH(instruments.last_played_at)
|
||||
) * 1.0 / ")
|
||||
.bind::<sql_types::Integer, _>(program.avoid_repeated_instruments_seconds())
|
||||
.bind::<sql_types::Integer, _>(program.avoid_repeated_instruments())
|
||||
.sql(",
|
||||
1.0
|
||||
),
|
||||
IFNULL(
|
||||
(
|
||||
UNIXEPOCH('now', 'localtime') - UNIXEPOCH(persons.last_played_at)
|
||||
) * 1.0 / ").bind::<sql_types::Integer, _>(program.avoid_repeated_composers_seconds()).sql(",
|
||||
) * 1.0 / ").bind::<sql_types::Integer, _>(program.avoid_repeated_composers()).sql(",
|
||||
1.0
|
||||
),
|
||||
1.0
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ mod player_bar;
|
|||
mod playlist_item;
|
||||
mod playlist_page;
|
||||
mod playlist_tile;
|
||||
mod preferences_dialog;
|
||||
mod process;
|
||||
mod process_manager;
|
||||
mod process_row;
|
||||
|
|
@ -20,6 +21,7 @@ mod recording_tile;
|
|||
mod search_page;
|
||||
mod search_tag;
|
||||
mod selector;
|
||||
mod slider_row;
|
||||
mod tag_tile;
|
||||
mod util;
|
||||
mod welcome_page;
|
||||
|
|
|
|||
105
src/preferences_dialog.rs
Normal file
105
src/preferences_dialog.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use adw::{prelude::AdwDialogExt, subclass::prelude::*};
|
||||
use gtk::{gio, glib, prelude::*};
|
||||
|
||||
use crate::{config, slider_row::SliderRow};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||
#[template(file = "data/ui/preferences_dialog.blp")]
|
||||
pub struct PreferencesDialog {
|
||||
#[template_child]
|
||||
pub prefer_least_recently_played_adjustment: TemplateChild<gtk::Adjustment>,
|
||||
#[template_child]
|
||||
pub prefer_recently_added_adjustment: TemplateChild<gtk::Adjustment>,
|
||||
#[template_child]
|
||||
pub avoid_repeated_composers_adjustment: TemplateChild<gtk::Adjustment>,
|
||||
#[template_child]
|
||||
pub avoid_repeated_instruments_adjustment: TemplateChild<gtk::Adjustment>,
|
||||
#[template_child]
|
||||
pub play_full_recordings_row: TemplateChild<adw::SwitchRow>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for PreferencesDialog {
|
||||
const NAME: &'static str = "MusicusPreferencesDialog";
|
||||
type Type = super::PreferencesDialog;
|
||||
type ParentType = adw::PreferencesDialog;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
klass.bind_template_instance_callbacks();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
SliderRow::static_type();
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
impl ObjectImpl for PreferencesDialog {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let settings = gio::Settings::new(config::APP_ID);
|
||||
|
||||
settings
|
||||
.bind(
|
||||
"prefer-least-recently-played",
|
||||
&*self.prefer_least_recently_played_adjustment,
|
||||
"value",
|
||||
)
|
||||
.build();
|
||||
|
||||
settings
|
||||
.bind(
|
||||
"prefer-recently-added",
|
||||
&*self.prefer_recently_added_adjustment,
|
||||
"value",
|
||||
)
|
||||
.build();
|
||||
|
||||
settings
|
||||
.bind(
|
||||
"avoid-repeated-composers",
|
||||
&*self.avoid_repeated_composers_adjustment,
|
||||
"value",
|
||||
)
|
||||
.build();
|
||||
|
||||
settings
|
||||
.bind(
|
||||
"avoid-repeated-instruments",
|
||||
&*self.avoid_repeated_instruments_adjustment,
|
||||
"value",
|
||||
)
|
||||
.build();
|
||||
|
||||
settings
|
||||
.bind(
|
||||
"play-full-recordings",
|
||||
&*self.play_full_recordings_row,
|
||||
"active",
|
||||
)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for PreferencesDialog {}
|
||||
impl AdwDialogImpl for PreferencesDialog {}
|
||||
impl PreferencesDialogImpl for PreferencesDialog {}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct PreferencesDialog(ObjectSubclass<imp::PreferencesDialog>)
|
||||
@extends gtk::Widget, adw::Dialog, adw::PreferencesDialog;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl PreferencesDialog {
|
||||
pub fn show(parent: &impl IsA<gtk::Widget>) {
|
||||
let obj: Self = glib::Object::new();
|
||||
obj.present(Some(parent));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use anyhow::Result;
|
||||
use gtk::{glib, glib::Properties, prelude::*, subclass::prelude::*};
|
||||
use gtk::{gio, glib, glib::Properties, prelude::*, subclass::prelude::*};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::library::LibraryQuery;
|
||||
use crate::{config, library::LibraryQuery};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
|
@ -47,10 +47,10 @@ mod imp {
|
|||
pub prefer_least_recently_played: Cell<f64>,
|
||||
|
||||
#[property(get, set)]
|
||||
pub avoid_repeated_composers_seconds: Cell<i32>,
|
||||
pub avoid_repeated_composers: Cell<i32>,
|
||||
|
||||
#[property(get, set)]
|
||||
pub avoid_repeated_instruments_seconds: Cell<i32>,
|
||||
pub avoid_repeated_instruments: Cell<i32>,
|
||||
|
||||
#[property(get, set)]
|
||||
pub play_full_recordings: Cell<bool>,
|
||||
|
|
@ -80,6 +80,8 @@ impl Program {
|
|||
}
|
||||
|
||||
pub fn from_query(query: LibraryQuery) -> Self {
|
||||
let settings = gio::Settings::new(&config::APP_ID);
|
||||
|
||||
glib::Object::builder()
|
||||
.property(
|
||||
"composer-id",
|
||||
|
|
@ -92,25 +94,34 @@ impl Program {
|
|||
query.instrument.as_ref().map(|i| i.instrument_id.clone()),
|
||||
)
|
||||
.property("work-id", query.work.as_ref().map(|w| w.work_id.clone()))
|
||||
.property("prefer-recently-added", 0.0)
|
||||
.property("prefer-least-recently-played", 0.5)
|
||||
.property(
|
||||
"avoid-repeated-composers-seconds",
|
||||
"prefer-recently-added",
|
||||
settings.int("prefer-recently-added") as f64 / 100.0,
|
||||
)
|
||||
.property(
|
||||
"prefer-least-recently-played",
|
||||
settings.int("prefer-least-recently-played") as f64 / 100.0,
|
||||
)
|
||||
.property(
|
||||
"avoid-repeated-composers",
|
||||
if query.composer.is_none() && query.work.is_none() {
|
||||
3600
|
||||
settings.int("avoid-repeated-composers")
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
.property(
|
||||
"avoid-repeated-instruments-seconds",
|
||||
"avoid-repeated-instruments",
|
||||
if query.instrument.is_none() && query.work.is_none() {
|
||||
3600
|
||||
settings.int("avoid-repeated-instruments")
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
.property("play-full-recordings", true)
|
||||
.property(
|
||||
"play-full-recordings",
|
||||
settings.boolean("play-full-recordings"),
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
|
@ -127,12 +138,12 @@ impl Program {
|
|||
data.prefer_least_recently_played.get(),
|
||||
)
|
||||
.property(
|
||||
"avoid-repeated-composers-seconds",
|
||||
data.avoid_repeated_composers_seconds.get(),
|
||||
"avoid-repeated-composers",
|
||||
data.avoid_repeated_composers.get(),
|
||||
)
|
||||
.property(
|
||||
"avoid-repeated-instruments-seconds",
|
||||
data.avoid_repeated_instruments_seconds.get(),
|
||||
"avoid-repeated-instruments",
|
||||
data.avoid_repeated_instruments.get(),
|
||||
)
|
||||
.property("play-full-recordings", data.play_full_recordings.get())
|
||||
.build();
|
||||
|
|
|
|||
89
src/slider_row.rs
Normal file
89
src/slider_row.rs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gtk::glib::{self, clone};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
#[derive(glib::Properties, gtk::CompositeTemplate, Debug, Default)]
|
||||
#[properties(wrapper_type = super::SliderRow)]
|
||||
#[template(file = "data/ui/slider_row.blp")]
|
||||
pub struct SliderRow {
|
||||
#[property(get, set)]
|
||||
pub adjustment: RefCell<gtk::Adjustment>,
|
||||
|
||||
#[property(get, set)]
|
||||
pub suffix: RefCell<String>,
|
||||
|
||||
#[template_child]
|
||||
pub value_label: TemplateChild<gtk::Label>,
|
||||
}
|
||||
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for SliderRow {
|
||||
const NAME: &'static str = "MusicusSliderRow";
|
||||
type Type = super::SliderRow;
|
||||
type ParentType = adw::PreferencesRow;
|
||||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
klass.bind_template_instance_callbacks();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
obj.init_template();
|
||||
}
|
||||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for SliderRow {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let obj = self.obj().to_owned();
|
||||
obj.connect_adjustment_notify(move |obj| {
|
||||
obj.adjustment().connect_value_changed(clone!(
|
||||
#[weak]
|
||||
obj,
|
||||
move |_| obj.update()
|
||||
));
|
||||
|
||||
obj.update();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for SliderRow {}
|
||||
impl ListBoxRowImpl for SliderRow {}
|
||||
impl PreferencesRowImpl for SliderRow {}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
pub struct SliderRow(ObjectSubclass<imp::SliderRow>)
|
||||
@extends gtk::Widget, gtk::ListBoxRow, adw::PreferencesRow;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl SliderRow {
|
||||
/// Create a new slider row.
|
||||
///
|
||||
/// The adjustment can be used to control the range and initial value of the slider. Use the
|
||||
/// adjustment's `value-changed` signal for getting updates. The current value is displayed
|
||||
/// next to the slider followed by `suffix`.
|
||||
pub fn new(title: &str, adjustment: >k::Adjustment, suffix: &str) -> Self {
|
||||
glib::Object::builder()
|
||||
.property("title", title)
|
||||
.property("adjustment", adjustment)
|
||||
.property("suffix", suffix)
|
||||
.build()
|
||||
}
|
||||
|
||||
pub fn update(&self) {
|
||||
self.imp().value_label.set_label(&format!(
|
||||
"{:.0}{}",
|
||||
self.adjustment().value(),
|
||||
self.suffix()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
use std::{cell::RefCell, path::Path};
|
||||
|
||||
use adw::subclass::prelude::*;
|
||||
use gtk::{gio, glib, glib::clone, prelude::*};
|
||||
use adw::{prelude::*, subclass::prelude::*};
|
||||
use gettextrs::gettext;
|
||||
use gtk::{gio, glib, glib::clone};
|
||||
|
||||
use crate::{
|
||||
config,
|
||||
|
|
@ -11,15 +12,13 @@ use crate::{
|
|||
player::Player,
|
||||
player_bar::PlayerBar,
|
||||
playlist_page::PlaylistPage,
|
||||
preferences_dialog::PreferencesDialog,
|
||||
process_manager::ProcessManager,
|
||||
search_page::SearchPage,
|
||||
welcome_page::WelcomePage,
|
||||
};
|
||||
|
||||
mod imp {
|
||||
use adw::prelude::{AlertDialogExt, AlertDialogExtManual};
|
||||
use gettextrs::gettext;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||
|
|
@ -89,8 +88,15 @@ mod imp {
|
|||
})
|
||||
.build();
|
||||
|
||||
let obj = self.obj().to_owned();
|
||||
let preferences_action = gio::ActionEntry::builder("preferences")
|
||||
.activate(move |_, _, _| {
|
||||
PreferencesDialog::show(&obj);
|
||||
})
|
||||
.build();
|
||||
|
||||
self.obj()
|
||||
.add_action_entries([import_action, library_action]);
|
||||
.add_action_entries([import_action, library_action, preferences_action]);
|
||||
|
||||
let player_bar = PlayerBar::new(&self.player);
|
||||
self.player_bar_revealer.set_child(Some(&player_bar));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue