mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
Implement program editor
This commit is contained in:
parent
fa94d61e1e
commit
8950b04ed2
8 changed files with 590 additions and 81 deletions
|
|
@ -1,12 +1,13 @@
|
|||
use std::cell::OnceCell;
|
||||
use std::cell::{OnceCell, RefCell};
|
||||
|
||||
use gtk::{
|
||||
glib::{self, Properties},
|
||||
gio,
|
||||
glib::{self, clone, Properties},
|
||||
prelude::*,
|
||||
subclass::prelude::*,
|
||||
};
|
||||
|
||||
use crate::program::{Program, ProgramDesign};
|
||||
use crate::{config, editor::program::ProgramEditor, program::Program};
|
||||
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
|
@ -16,7 +17,11 @@ mod imp {
|
|||
#[template(file = "data/ui/program_tile.blp")]
|
||||
pub struct ProgramTile {
|
||||
#[property(get, construct_only)]
|
||||
pub program: OnceCell<Program>,
|
||||
pub navigation: OnceCell<adw::NavigationView>,
|
||||
#[property(get, construct_only)]
|
||||
pub key: OnceCell<String>,
|
||||
#[property(get, set = Self::set_program)]
|
||||
pub program: RefCell<Program>,
|
||||
|
||||
#[template_child]
|
||||
pub edit_button: TemplateChild<gtk::Button>,
|
||||
|
|
@ -34,6 +39,7 @@ mod imp {
|
|||
|
||||
fn class_init(klass: &mut Self::Class) {
|
||||
klass.bind_template();
|
||||
klass.bind_template_instance_callbacks();
|
||||
}
|
||||
|
||||
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
||||
|
|
@ -42,10 +48,46 @@ mod imp {
|
|||
}
|
||||
|
||||
#[glib::derived_properties]
|
||||
impl ObjectImpl for ProgramTile {}
|
||||
impl ObjectImpl for ProgramTile {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
let settings = gio::Settings::new(config::APP_ID);
|
||||
self.set_program_from_settings(&settings);
|
||||
|
||||
let obj = self.obj().to_owned();
|
||||
settings.connect_changed(Some(&self.key.get().unwrap()), move |settings, _| {
|
||||
obj.imp().set_program_from_settings(settings);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl WidgetImpl for ProgramTile {}
|
||||
impl FlowBoxChildImpl for ProgramTile {}
|
||||
|
||||
impl ProgramTile {
|
||||
fn set_program_from_settings(&self, settings: &gio::Settings) {
|
||||
match Program::deserialize(&settings.string(self.key.get().unwrap())) {
|
||||
Ok(program) => self.set_program(&program),
|
||||
Err(err) => log::error!("Failed to deserialize program from settings: {err:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn set_program(&self, program: &Program) {
|
||||
self.obj()
|
||||
.set_css_classes(&["program-tile", &program.design().css_class()]);
|
||||
|
||||
if let Some(title) = program.title() {
|
||||
self.title_label.set_label(&title);
|
||||
}
|
||||
|
||||
if let Some(description) = program.description() {
|
||||
self.description_label.set_label(&description);
|
||||
}
|
||||
|
||||
self.program.replace(program.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glib::wrapper! {
|
||||
|
|
@ -53,35 +95,33 @@ glib::wrapper! {
|
|||
@extends gtk::Widget, gtk::FlowBoxChild;
|
||||
}
|
||||
|
||||
#[gtk::template_callbacks]
|
||||
impl ProgramTile {
|
||||
pub fn new(program: Program) -> Self {
|
||||
pub fn new_for_setting(navigation: &adw::NavigationView, key: &str) -> Self {
|
||||
let obj: Self = glib::Object::builder()
|
||||
.property("program", &program)
|
||||
.property("navigation", navigation)
|
||||
.property("key", key)
|
||||
.build();
|
||||
|
||||
let imp = obj.imp();
|
||||
|
||||
if program.design() != ProgramDesign::Generic {
|
||||
obj.add_css_class("highlight");
|
||||
obj.add_css_class(match program.design() {
|
||||
ProgramDesign::Generic => "generic",
|
||||
ProgramDesign::Program1 => "program1",
|
||||
ProgramDesign::Program2 => "program2",
|
||||
ProgramDesign::Program3 => "program3",
|
||||
ProgramDesign::Program4 => "program4",
|
||||
ProgramDesign::Program5 => "program5",
|
||||
ProgramDesign::Program6 => "program6",
|
||||
})
|
||||
}
|
||||
|
||||
if let Some(title) = program.title() {
|
||||
imp.title_label.set_label(&title);
|
||||
}
|
||||
|
||||
if let Some(description) = program.description() {
|
||||
imp.description_label.set_label(&description);
|
||||
}
|
||||
|
||||
obj
|
||||
}
|
||||
|
||||
#[template_callback]
|
||||
fn edit_button_clicked(&self) {
|
||||
let editor = ProgramEditor::new(&self.navigation(), Some(&self.program()));
|
||||
|
||||
editor.connect_save(clone!(
|
||||
#[weak(rename_to = obj)]
|
||||
self,
|
||||
move |_, program| {
|
||||
let settings = gio::Settings::new(config::APP_ID);
|
||||
if let Err(err) = settings.set_string(&obj.key(), &program.serialize()) {
|
||||
log::error!("Failed to save program to settings: {err:?}");
|
||||
};
|
||||
obj.set_program(&program);
|
||||
}
|
||||
));
|
||||
|
||||
self.navigation().push(&editor);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue