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
|
|
@ -17,19 +17,39 @@
|
||||||
<default>''</default>
|
<default>''</default>
|
||||||
<summary>Path to the music library</summary>
|
<summary>Path to the music library</summary>
|
||||||
</key>
|
</key>
|
||||||
|
<key name="prefer-least-recently-played" type="i">
|
||||||
|
<default>20</default>
|
||||||
|
<summary>How much recently played items should be penalized (0–100)</summary>
|
||||||
|
</key>
|
||||||
|
<key name="prefer-recently-added" type="i">
|
||||||
|
<default>0</default>
|
||||||
|
<summary>How much recently added items should be preferred (0–100)</summary>
|
||||||
|
</key>
|
||||||
|
<key name="avoid-repeated-composers" type="i">
|
||||||
|
<default>60</default>
|
||||||
|
<summary>For how many minutes a composer should be penalized</summary>
|
||||||
|
</key>
|
||||||
|
<key name="avoid-repeated-instruments" type="i">
|
||||||
|
<default>60</default>
|
||||||
|
<summary>For how many minutes an instrument should be penalized</summary>
|
||||||
|
</key>
|
||||||
|
<key name="play-full-recordings" type="b">
|
||||||
|
<default>true</default>
|
||||||
|
<summary>Whether to play full recordings</summary>
|
||||||
|
</key>
|
||||||
<key name="program1" type="s">
|
<key name="program1" type="s">
|
||||||
<!-- Translators: Configuration for the default programs in JSON. Please only translate the values of "title" and "description". -->
|
<!-- Translators: Configuration for the default programs in JSON. Please only translate the values of "title" and "description". -->
|
||||||
<default l10n="messages">'{"title":"Just play some music","description":"Randomly select some music. Customize programs using the button in the top right.","design":"Program1","prefer_recently_added":0.0,"prefer_least_recently_played":0.1,"avoid_repeated_composers_seconds":3600,"avoid_repeated_instruments_seconds":3600,"play_full_recordings":true}'</default>
|
<default l10n="messages">'{"title":"Just play some music","description":"Randomly select some music. Customize programs using the button in the top right.","design":"Program1","prefer_recently_added":0.0,"prefer_least_recently_played":0.1,"avoid_repeated_composers":60,"avoid_repeated_instruments":60,"play_full_recordings":true}'</default>
|
||||||
<summary>Default settings for program 1</summary>
|
<summary>Default settings for program 1</summary>
|
||||||
</key>
|
</key>
|
||||||
<key name="program2" type="s">
|
<key name="program2" type="s">
|
||||||
<!-- Translators: Configuration for the default programs in JSON. Please only translate the values of "title" and "description". -->
|
<!-- Translators: Configuration for the default programs in JSON. Please only translate the values of "title" and "description". -->
|
||||||
<default l10n="messages">'{"title":"What\'s new?","description":"Recordings that you recently added to your music library.","design":"Program2","prefer_recently_added":1.0,"prefer_least_recently_played":0.0,"avoid_repeated_composers_seconds":3600,"avoid_repeated_instruments_seconds":3600,"play_full_recordings":true}'</default>
|
<default l10n="messages">'{"title":"What\'s new?","description":"Recordings that you recently added to your music library.","design":"Program2","prefer_recently_added":1.0,"prefer_least_recently_played":0.0,"avoid_repeated_composers":60,"avoid_repeated_instruments":60,"play_full_recordings":true}'</default>
|
||||||
<summary>Default settings for program 2</summary>
|
<summary>Default settings for program 2</summary>
|
||||||
</key>
|
</key>
|
||||||
<key name="program3" type="s">
|
<key name="program3" type="s">
|
||||||
<!-- Translators: Configuration for the default programs in JSON. Please only translate the values of "title" and "description". -->
|
<!-- Translators: Configuration for the default programs in JSON. Please only translate the values of "title" and "description". -->
|
||||||
<default l10n="messages">'{"title":"A long time ago","description":"Works that you haven\'t listened to for a long time.","design":"Program3","prefer_recently_added":0.0,"prefer_least_recently_played":1.0,"avoid_repeated_composers_seconds":3600,"avoid_repeated_instruments_seconds":3600,"play_full_recordings":true}'</default>
|
<default l10n="messages">'{"title":"A long time ago","description":"Works that you haven\'t listened to for a long time.","design":"Program3","prefer_recently_added":0.0,"prefer_least_recently_played":1.0,"avoid_repeated_composers":60,"avoid_repeated_instruments":60,"play_full_recordings":true}'</default>
|
||||||
<summary>Default settings for program 3</summary>
|
<summary>Default settings for program 3</summary>
|
||||||
</key>
|
</key>
|
||||||
</schema>
|
</schema>
|
||||||
|
|
|
||||||
65
data/ui/preferences_dialog.blp
Normal file
65
data/ui/preferences_dialog.blp
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
template $MusicusPreferencesDialog: Adw.PreferencesDialog {
|
||||||
|
Adw.PreferencesPage {
|
||||||
|
title: _("Playback");
|
||||||
|
|
||||||
|
Adw.PreferencesGroup {
|
||||||
|
title: _("Default program");
|
||||||
|
description: _("These settings apply when you add search results to the playlist.");
|
||||||
|
|
||||||
|
$MusicusSliderRow {
|
||||||
|
title: _("Prefer recordings that haven't been played for a long time");
|
||||||
|
suffix: _("%");
|
||||||
|
|
||||||
|
adjustment: Gtk.Adjustment prefer_least_recently_played_adjustment {
|
||||||
|
lower: 0;
|
||||||
|
upper: 100;
|
||||||
|
step-increment: 1;
|
||||||
|
page-increment: 10;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$MusicusSliderRow {
|
||||||
|
title: _("Prefer recordings that were recently added");
|
||||||
|
suffix: _("%");
|
||||||
|
|
||||||
|
adjustment: Gtk.Adjustment prefer_recently_added_adjustment {
|
||||||
|
lower: 0;
|
||||||
|
upper: 100;
|
||||||
|
step-increment: 1;
|
||||||
|
page-increment: 10;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$MusicusSliderRow {
|
||||||
|
title: _("Avoid repeating composers");
|
||||||
|
suffix: _(" min");
|
||||||
|
|
||||||
|
adjustment: Gtk.Adjustment avoid_repeated_composers_adjustment {
|
||||||
|
lower: 0;
|
||||||
|
upper: 120;
|
||||||
|
step-increment: 10;
|
||||||
|
page-increment: 30;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
$MusicusSliderRow {
|
||||||
|
title: _("Avoid repeating instruments");
|
||||||
|
suffix: _(" min");
|
||||||
|
|
||||||
|
adjustment: Gtk.Adjustment avoid_repeated_instruments_adjustment {
|
||||||
|
lower: 0;
|
||||||
|
upper: 120;
|
||||||
|
step-increment: 10;
|
||||||
|
page-increment: 30;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Adw.SwitchRow play_full_recordings_row {
|
||||||
|
title: _("Play full recordings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -269,7 +269,7 @@ menu primary_menu {
|
||||||
|
|
||||||
item {
|
item {
|
||||||
label: _("_Preferences");
|
label: _("_Preferences");
|
||||||
action: "app.preferences";
|
action: "win.preferences";
|
||||||
}
|
}
|
||||||
|
|
||||||
item {
|
item {
|
||||||
|
|
|
||||||
41
data/ui/slider_row.blp
Normal file
41
data/ui/slider_row.blp
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
using Adw 1;
|
||||||
|
|
||||||
|
template $MusicusSliderRow: Adw.PreferencesRow {
|
||||||
|
activatable: false;
|
||||||
|
|
||||||
|
Gtk.Box {
|
||||||
|
orientation: vertical;
|
||||||
|
spacing: 12;
|
||||||
|
margin-top: 12;
|
||||||
|
margin-bottom: 12;
|
||||||
|
margin-start: 12;
|
||||||
|
margin-end: 12;
|
||||||
|
|
||||||
|
Gtk.Box {
|
||||||
|
spacing: 12;
|
||||||
|
|
||||||
|
Gtk.Label {
|
||||||
|
label: bind template.title;
|
||||||
|
wrap: true;
|
||||||
|
xalign: 0.0;
|
||||||
|
hexpand: true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gtk.Label value_label {
|
||||||
|
xalign: 1.0;
|
||||||
|
valign: center;
|
||||||
|
|
||||||
|
styles [
|
||||||
|
"numeric",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gtk.Scale {
|
||||||
|
adjustment: bind template.adjustment;
|
||||||
|
hexpand: true;
|
||||||
|
valign: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ template $MusicusWelcomePage : Adw.NavigationPage {
|
||||||
menu primary_menu {
|
menu primary_menu {
|
||||||
item {
|
item {
|
||||||
label: _("_Preferences");
|
label: _("_Preferences");
|
||||||
action: "app.preferences";
|
action: "win.preferences";
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
label: _("_About Musicus");
|
label: _("_About Musicus");
|
||||||
|
|
|
||||||
|
|
@ -629,14 +629,14 @@ impl Library {
|
||||||
(
|
(
|
||||||
UNIXEPOCH('now', 'localtime') - UNIXEPOCH(instruments.last_played_at)
|
UNIXEPOCH('now', 'localtime') - UNIXEPOCH(instruments.last_played_at)
|
||||||
) * 1.0 / ")
|
) * 1.0 / ")
|
||||||
.bind::<sql_types::Integer, _>(program.avoid_repeated_instruments_seconds())
|
.bind::<sql_types::Integer, _>(program.avoid_repeated_instruments())
|
||||||
.sql(",
|
.sql(",
|
||||||
1.0
|
1.0
|
||||||
),
|
),
|
||||||
IFNULL(
|
IFNULL(
|
||||||
(
|
(
|
||||||
UNIXEPOCH('now', 'localtime') - UNIXEPOCH(persons.last_played_at)
|
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
|
||||||
),
|
),
|
||||||
1.0
|
1.0
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ mod player_bar;
|
||||||
mod playlist_item;
|
mod playlist_item;
|
||||||
mod playlist_page;
|
mod playlist_page;
|
||||||
mod playlist_tile;
|
mod playlist_tile;
|
||||||
|
mod preferences_dialog;
|
||||||
mod process;
|
mod process;
|
||||||
mod process_manager;
|
mod process_manager;
|
||||||
mod process_row;
|
mod process_row;
|
||||||
|
|
@ -20,6 +21,7 @@ mod recording_tile;
|
||||||
mod search_page;
|
mod search_page;
|
||||||
mod search_tag;
|
mod search_tag;
|
||||||
mod selector;
|
mod selector;
|
||||||
|
mod slider_row;
|
||||||
mod tag_tile;
|
mod tag_tile;
|
||||||
mod util;
|
mod util;
|
||||||
mod welcome_page;
|
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 std::cell::{Cell, RefCell};
|
||||||
|
|
||||||
use anyhow::Result;
|
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 serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::library::LibraryQuery;
|
use crate::{config, library::LibraryQuery};
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
@ -47,10 +47,10 @@ mod imp {
|
||||||
pub prefer_least_recently_played: Cell<f64>,
|
pub prefer_least_recently_played: Cell<f64>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
pub avoid_repeated_composers_seconds: Cell<i32>,
|
pub avoid_repeated_composers: Cell<i32>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
pub avoid_repeated_instruments_seconds: Cell<i32>,
|
pub avoid_repeated_instruments: Cell<i32>,
|
||||||
|
|
||||||
#[property(get, set)]
|
#[property(get, set)]
|
||||||
pub play_full_recordings: Cell<bool>,
|
pub play_full_recordings: Cell<bool>,
|
||||||
|
|
@ -80,6 +80,8 @@ impl Program {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_query(query: LibraryQuery) -> Self {
|
pub fn from_query(query: LibraryQuery) -> Self {
|
||||||
|
let settings = gio::Settings::new(&config::APP_ID);
|
||||||
|
|
||||||
glib::Object::builder()
|
glib::Object::builder()
|
||||||
.property(
|
.property(
|
||||||
"composer-id",
|
"composer-id",
|
||||||
|
|
@ -92,25 +94,34 @@ impl Program {
|
||||||
query.instrument.as_ref().map(|i| i.instrument_id.clone()),
|
query.instrument.as_ref().map(|i| i.instrument_id.clone()),
|
||||||
)
|
)
|
||||||
.property("work-id", query.work.as_ref().map(|w| w.work_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(
|
.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() {
|
if query.composer.is_none() && query.work.is_none() {
|
||||||
3600
|
settings.int("avoid-repeated-composers")
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.property(
|
.property(
|
||||||
"avoid-repeated-instruments-seconds",
|
"avoid-repeated-instruments",
|
||||||
if query.instrument.is_none() && query.work.is_none() {
|
if query.instrument.is_none() && query.work.is_none() {
|
||||||
3600
|
settings.int("avoid-repeated-instruments")
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.property("play-full-recordings", true)
|
.property(
|
||||||
|
"play-full-recordings",
|
||||||
|
settings.boolean("play-full-recordings"),
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,12 +138,12 @@ impl Program {
|
||||||
data.prefer_least_recently_played.get(),
|
data.prefer_least_recently_played.get(),
|
||||||
)
|
)
|
||||||
.property(
|
.property(
|
||||||
"avoid-repeated-composers-seconds",
|
"avoid-repeated-composers",
|
||||||
data.avoid_repeated_composers_seconds.get(),
|
data.avoid_repeated_composers.get(),
|
||||||
)
|
)
|
||||||
.property(
|
.property(
|
||||||
"avoid-repeated-instruments-seconds",
|
"avoid-repeated-instruments",
|
||||||
data.avoid_repeated_instruments_seconds.get(),
|
data.avoid_repeated_instruments.get(),
|
||||||
)
|
)
|
||||||
.property("play-full-recordings", data.play_full_recordings.get())
|
.property("play-full-recordings", data.play_full_recordings.get())
|
||||||
.build();
|
.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 std::{cell::RefCell, path::Path};
|
||||||
|
|
||||||
use adw::subclass::prelude::*;
|
use adw::{prelude::*, subclass::prelude::*};
|
||||||
use gtk::{gio, glib, glib::clone, prelude::*};
|
use gettextrs::gettext;
|
||||||
|
use gtk::{gio, glib, glib::clone};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config,
|
config,
|
||||||
|
|
@ -11,15 +12,13 @@ use crate::{
|
||||||
player::Player,
|
player::Player,
|
||||||
player_bar::PlayerBar,
|
player_bar::PlayerBar,
|
||||||
playlist_page::PlaylistPage,
|
playlist_page::PlaylistPage,
|
||||||
|
preferences_dialog::PreferencesDialog,
|
||||||
process_manager::ProcessManager,
|
process_manager::ProcessManager,
|
||||||
search_page::SearchPage,
|
search_page::SearchPage,
|
||||||
welcome_page::WelcomePage,
|
welcome_page::WelcomePage,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
use adw::prelude::{AlertDialogExt, AlertDialogExtManual};
|
|
||||||
use gettextrs::gettext;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
#[derive(Debug, Default, gtk::CompositeTemplate)]
|
||||||
|
|
@ -89,8 +88,15 @@ mod imp {
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
let obj = self.obj().to_owned();
|
||||||
|
let preferences_action = gio::ActionEntry::builder("preferences")
|
||||||
|
.activate(move |_, _, _| {
|
||||||
|
PreferencesDialog::show(&obj);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
self.obj()
|
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);
|
let player_bar = PlayerBar::new(&self.player);
|
||||||
self.player_bar_revealer.set_child(Some(&player_bar));
|
self.player_bar_revealer.set_child(Some(&player_bar));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue