mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 19:57:25 +01:00
editor: Add basic work structure
This commit is contained in:
parent
bdf8ed989d
commit
3eed04d04b
3 changed files with 51 additions and 6 deletions
|
|
@ -38,6 +38,11 @@ pub fn connect(file_name: &str) -> Result<SqliteConnection> {
|
||||||
Ok(connection)
|
Ok(connection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a random string suitable as an item ID.
|
||||||
|
pub fn generate_id() -> String {
|
||||||
|
uuid::Uuid::new_v4().simple().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
/// A single translated string value.
|
/// A single translated string value.
|
||||||
#[derive(Serialize, Deserialize, AsExpression, FromSqlRow, Clone, Default, Debug)]
|
#[derive(Serialize, Deserialize, AsExpression, FromSqlRow, Clone, Default, Debug)]
|
||||||
#[diesel(sql_type = Text)]
|
#[diesel(sql_type = Text)]
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ pub struct Work {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle part composers.
|
// TODO: Handle part composers.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct WorkPart {
|
pub struct WorkPart {
|
||||||
pub work_id: String,
|
pub work_id: String,
|
||||||
pub level: u8,
|
pub level: u8,
|
||||||
|
|
@ -113,6 +113,13 @@ impl PartialEq for Composer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Eq for WorkPart {}
|
||||||
|
impl PartialEq for WorkPart {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.work_id == other.work_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Work {
|
impl Work {
|
||||||
pub fn from_table(data: tables::Work, connection: &mut SqliteConnection) -> Result<Self> {
|
pub fn from_table(data: tables::Work, connection: &mut SqliteConnection) -> Result<Self> {
|
||||||
fn visit_children(
|
fn visit_children(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
db::models::{Composer, Instrument, Person},
|
db::{
|
||||||
|
self,
|
||||||
|
models::{Composer, Instrument, Person, WorkPart},
|
||||||
|
},
|
||||||
editor::{
|
editor::{
|
||||||
instrument_selector_popover::MusicusInstrumentSelectorPopover,
|
instrument_selector_popover::MusicusInstrumentSelectorPopover,
|
||||||
person_selector_popover::MusicusPersonSelectorPopover,
|
person_selector_popover::MusicusPersonSelectorPopover,
|
||||||
|
|
@ -10,6 +13,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use adw::{prelude::*, subclass::prelude::*};
|
use adw::{prelude::*, subclass::prelude::*};
|
||||||
|
use gettextrs::gettext;
|
||||||
use gtk::glib::{self, clone, Properties};
|
use gtk::glib::{self, clone, Properties};
|
||||||
|
|
||||||
use std::cell::{OnceCell, RefCell};
|
use std::cell::{OnceCell, RefCell};
|
||||||
|
|
@ -28,6 +32,7 @@ mod imp {
|
||||||
// results when finishing the process of editing the work. The composer rows
|
// results when finishing the process of editing the work. The composer rows
|
||||||
// handle all state related to the composer.
|
// handle all state related to the composer.
|
||||||
pub composer_rows: RefCell<Vec<MusicusWorkEditorComposerRow>>,
|
pub composer_rows: RefCell<Vec<MusicusWorkEditorComposerRow>>,
|
||||||
|
pub parts: RefCell<Vec<WorkPart>>,
|
||||||
pub instruments: RefCell<Vec<Instrument>>,
|
pub instruments: RefCell<Vec<Instrument>>,
|
||||||
|
|
||||||
pub persons_popover: OnceCell<MusicusPersonSelectorPopover>,
|
pub persons_popover: OnceCell<MusicusPersonSelectorPopover>,
|
||||||
|
|
@ -38,6 +43,8 @@ mod imp {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub select_person_box: TemplateChild<gtk::Box>,
|
pub select_person_box: TemplateChild<gtk::Box>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
|
pub part_list: TemplateChild<gtk::ListBox>,
|
||||||
|
#[template_child]
|
||||||
pub instrument_list: TemplateChild<gtk::ListBox>,
|
pub instrument_list: TemplateChild<gtk::ListBox>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
pub select_instrument_box: TemplateChild<gtk::Box>,
|
pub select_instrument_box: TemplateChild<gtk::Box>,
|
||||||
|
|
@ -109,9 +116,7 @@ mod imp {
|
||||||
remove_button.connect_clicked(
|
remove_button.connect_clicked(
|
||||||
clone!(@weak obj, @weak row, @strong instrument => move |_| {
|
clone!(@weak obj, @weak row, @strong instrument => move |_| {
|
||||||
obj.imp().instrument_list.remove(&row);
|
obj.imp().instrument_list.remove(&row);
|
||||||
let mut instruments = obj.imp().instruments.borrow_mut();
|
obj.imp().instruments.borrow_mut().retain(|i| *i != instrument);
|
||||||
let index = instruments.iter().position(|i| *i == instrument).unwrap();
|
|
||||||
instruments.remove(index);
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -152,7 +157,35 @@ impl MusicusWorkEditor {
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
fn add_part(&self, _: &adw::ActionRow) {
|
fn add_part(&self, _: &adw::ActionRow) {
|
||||||
todo!();
|
let part = WorkPart {
|
||||||
|
work_id: db::generate_id(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let row = adw::EntryRow::builder().title(gettext("Name")).build();
|
||||||
|
|
||||||
|
let remove_button = gtk::Button::builder()
|
||||||
|
.icon_name("user-trash-symbolic")
|
||||||
|
.valign(gtk::Align::Center)
|
||||||
|
.css_classes(["flat"])
|
||||||
|
.build();
|
||||||
|
|
||||||
|
remove_button.connect_clicked(
|
||||||
|
clone!(@weak self as obj, @weak row, @strong part => move |_| {
|
||||||
|
obj.imp().part_list.remove(&row);
|
||||||
|
obj.imp().parts.borrow_mut().retain(|p| *p != part);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
row.add_suffix(&remove_button);
|
||||||
|
|
||||||
|
self.imp()
|
||||||
|
.part_list
|
||||||
|
.insert(&row, self.imp().parts.borrow().len() as i32);
|
||||||
|
|
||||||
|
row.grab_focus();
|
||||||
|
|
||||||
|
self.imp().parts.borrow_mut().push(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[template_callback]
|
#[template_callback]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue