update to make song_editor ready

This commit is contained in:
Chris Cochrun 2023-10-09 13:53:09 -05:00
parent e1cfa5e843
commit 96d5bdac73
5 changed files with 93 additions and 85 deletions

View file

@ -353,5 +353,25 @@ or at least turns the entry above it into the same as itself while retaining it'
** DONE Fix file dialog using basic QT theme ** DONE Fix file dialog using basic QT theme
[[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::FileDialog {]] [[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::FileDialog {]]
* Thoughts
I'm considering porting from using QML and CXX-QT to something like Iced or Slint and thus doing the entire app in a far more "Rust" way. The issues with this include:
- Rewrite almost the entire thing
- Most of the logic is fairly tied to the UI
- Will be using the current state of the app for a long time until it's nearly feature parity
* Inbox Having rewritten a lot of the logic once already to Rust, I think it'll go faster, but I'm afraid of continuing to have FOMO in picking a library that isn't quite up to snuff. Iced seems to be a good contender to be around for a while since System 76 is taking it on as their library to build COSMIC in. However, I just don't think I like the way you build UI's in Iced.
Slint on the other hand is basically like QML but for Rust, which is the whole reason this project started. QML and therefore Slint, are perfect for designing UI's. It's a powerful Object Tree that the code will nearly tell you in it's form how the UI should look since objects are nested. Slint also seems a bit more finished.
Slint is also GPL3. So that means its protected. Good for me, not for others. Iced seems to have more community backing. Slint does have a dual license though and that is a bit scary.
I think I might just use Slint. Maybe it's easier to contribute to than CXX-QT?
Let's also list the problems I've had with CXX-QT...
- A lot of types that need to cross the boundary are specific to QT and therefore cause a lot of duplicated memory.
- The specific QT types are different and not "Rust" like.
- It's complicated to inherit from QT types to build models. And that's the only way to work with collections of data in QML. Models.
- Some things listed in the docs just don't seem to compile.
- APIs are changing. They are still trying to land on a model for how things should look to the user of the library.
Slint and Iced both are a more nailed down API. However, QT is a far more mature system....

View file

@ -145,8 +145,8 @@ Controls.Page {
FileHelper { id: fileHelper } FileHelper { id: fileHelper }
SlideHelper { id: slideHelper } SlideHelper { id: slideHelper }
SongEditor { SongEditor {
id: songEditor id: songEditorModel
songModel: songProxyModel.songModel() /* songModel: songProxyModel.songModel() */
} }
function changeServiceItem(index) { function changeServiceItem(index) {

View file

@ -10,7 +10,7 @@ Item {
id: root id: root
property int songIndex property int songIndex
property var song property var song: songEditorModel
GridLayout { GridLayout {
id: mainLayout id: mainLayout
@ -445,8 +445,8 @@ Item {
Presenter.SongEditorSlideList { Presenter.SongEditorSlideList {
id: songList id: songList
imageBackground: song.backgroundType === "image" ? song.background : "" imageBackground: songEditorModel.backgroundType === "image" ? songEditor.background : ""
videoBackground: song.backgroundType === "video" ? song.background : "" videoBackground: songEditorModel.backgroundType === "video" ? songEditor.background : ""
Layout.preferredWidth: 500 Layout.preferredWidth: 500
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
@ -471,54 +471,6 @@ Item {
} }
} }
FileDialog {
id: audioFileDialog
title: "Please choose an audio file"
folder: shortcuts.home
selectMultiple: false
nameFilters: ["Audio files (*.mp3 *.flac *.wav *.opus *.MP3 *.FLAC *.WAV *.OPUS)"]
onAccepted: {
updateAudioFile(audioFileDialog.fileUrls[0]);
console.log("audio = " + audioFileDialog.fileUrls[0]);
}
onRejected: {
console.log("Canceled")
}
}
FileDialog {
id: videoFileDialog
title: "Please choose a background"
folder: shortcuts.home
selectMultiple: false
nameFilters: ["Video files (*.mp4 *.mkv *.mov *.wmv *.avi *.MP4 *.MOV *.MKV)"]
onAccepted: {
updateBackground(videoFileDialog.fileUrls[0], "video");
console.log("video background = " + videoFileDialog.fileUrls[0]);
}
onRejected: {
console.log("Canceled")
}
}
FileDialog {
id: imageFileDialog
title: "Please choose a background"
folder: shortcuts.home
selectMultiple: false
nameFilters: ["Image files (*.jpg *.jpeg *.png *.JPG *.JPEG *.PNG)"]
onAccepted: {
updateBackground(imageFileDialog.fileUrls[0], "image");
console.log("image background = " + imageFileDialog.fileUrls[0]);
}
onRejected: {
console.log("Canceled")
}
}
function newSong(index) { function newSong(index) {
clearSlides(); clearSlides();
song = songProxyModel.getSong(index); song = songProxyModel.getSong(index);
@ -534,7 +486,20 @@ Item {
function changeSong(index) { function changeSong(index) {
clearSlides(); clearSlides();
song = songProxyModel.getSong(index); const updatedSong = songProxyModel.getSong(index);
console.log(updatedSong.verseOrder + " " + updatedSong.title);
songEditorModel.title = updatedSong.title;
songEditorModel.lyrics = updatedSong.lyrics;
songEditorModel.author = updatedSong.author;
songEditorModel.ccli = updatedSong.ccli;
songEditorModel.audio = updatedSong.audio;
songEditorModel.verseOrder = updatedSong.verseOrder;
songEditorModel.background = updatedSong.background;
songEditorModel.backgroundType = updatedSong.backgroundType;
songEditorModel.horizontalTextAlignment = updatedSong.horizontalTextAlignment;
songEditorModel.verticalTextAlignment = updatedSong.verticalTextAlignment;
songEditorModel.font = updatedSong.font;
songEditorModel.fontSize = updatedSong.fontSize;
songIndex = song.id; songIndex = song.id;
changeSlideHAlignment(song.horizontalTextAlignment); changeSlideHAlignment(song.horizontalTextAlignment);
@ -577,26 +542,17 @@ Item {
function updateAudioFile() { function updateAudioFile() {
const file = fileHelper.loadFile("Pick Audio", "audio"); const file = fileHelper.loadFile("Pick Audio", "audio");
songEditorModel.audio = file
songProxyModel.songModel.updateAudio(songIndex, file); songProxyModel.songModel.updateAudio(songIndex, file);
} }
function updateBackground(backgroundType) { function updateBackground(backgroundType) {
song.backgroundType = backgroundType; songEditorModel.backgroundType = backgroundType;
const file = fileHelper.loadFile("Pick Background", backgroundType); const file = fileHelper.loadFile("Pick Background", backgroundType);
song.background = file; songEditorModel.background = file;
songProxyModel.songModel.updateBackground(songIndex, file); songProxyModel.songModel.updateBackground(songIndex, file);
songProxyModel.songModel.updateBackgroundType(songIndex, backgroundType); songProxyModel.songModel.updateBackgroundType(songIndex, backgroundType);
console.log("changed background"); console.log("changed background");
/* if (backgroundType === "image") { */
/* //todo */
/* songList.videoBackground = ""; */
/* songList.imageBackground = background; */
/* } else { */
/* //todo */
/* songList.imageBackground = ""; */
/* songList.videoBackground = background; */
/* songList.loadVideo(); */
/* } */
} }
@ -674,7 +630,6 @@ Item {
} }
function changeSlideText(id) { function changeSlideText(id) {
/* console.log("Here are the verses: " + verses); */
const verses = songProxyModel.getLyricList(id); const verses = songProxyModel.getLyricList(id);
verses.forEach(songList.appendVerse); verses.forEach(songList.appendVerse);
/* songList.loadVideo(); */ /* songList.loadVideo(); */

View file

@ -1,6 +1,5 @@
#[cxx_qt::bridge] #[cxx_qt::bridge]
mod song_editor { pub mod song_editor {
use crate::songs::song_model::qobject::SongModel;
unsafe extern "C++" { unsafe extern "C++" {
include!("cxx-qt-lib/qmap.h"); include!("cxx-qt-lib/qmap.h");
@ -16,8 +15,8 @@ mod song_editor {
type QStringList = cxx_qt_lib::QStringList; type QStringList = cxx_qt_lib::QStringList;
include!("cxx-qt-lib/qlist.h"); include!("cxx-qt-lib/qlist.h");
type QList_QString = cxx_qt_lib::QList<QString>; type QList_QString = cxx_qt_lib::QList<QString>;
#[cxx_name = "SongModel"] // #[cxx_name = "SongModel"]
type CxxSongs = SongModel; // type CxxSongs = crate::songs::song_model::qobject::SongModel;
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -49,8 +48,8 @@ mod song_editor {
font: QString, font: QString,
#[qproperty] #[qproperty]
font_size: i32, font_size: i32,
#[qproperty] // #[qproperty]
song_model: *mut CxxSongs, // song_model: *mut CxxSongs,
} }
impl Default for SongEditor { impl Default for SongEditor {
@ -69,17 +68,50 @@ mod song_editor {
vertical_text_alignment: QString::default(), vertical_text_alignment: QString::default(),
font: QString::default(), font: QString::default(),
font_size: 50, font_size: 50,
song_model: std::ptr::null_mut(), // song_model: std::ptr::null_mut(),
} }
} }
} }
impl SongEditor { impl qobject::SongEditor {
fn idk(mut self: Pin<&mut Self>) { fn idk(mut self: Pin<&mut Self>) {
let mut model = self.song_model().as_mut().unwrap(); // let mut model = self.song_model().as_mut().unwrap();
let pinned_model = Pin::new_unchecked(model); // let pinned_model = Pin::new_unchecked(model);
pinned_model.update_ccli(0, QString::from("idk")); // pinned_model.update_ccli(0, QString::from("idk"));
todo!(); todo!()
} }
// #[qinvokable]
// fn set_song(
// mut self: Pin<&mut Self>,
// title: QString,
// lyrics: QString,
// author: QString,
// ccli: QString,
// audio: QUrl,
// verse_order: QString,
// background: QUrl,
// background_type: QString,
// horizontal_text_alignment: QString,
// vertical_text_alignment: QString,
// font: QString,
// font_size: i32,
// ) -> bool {
// self.as_mut().set_title(title);
// self.as_mut().set_lyrics(lyrics);
// self.as_mut().set_author(author);
// self.as_mut().set_ccli(ccli);
// self.as_mut().set_audio(audio);
// self.as_mut().set_verse_order(verse_order);
// self.as_mut().set_background(background);
// self.as_mut().set_background_type(background_type);
// self.as_mut().set_horizontal_text_alignment(
// horizontal_text_alignment,
// );
// self.as_mut()
// .set_vertical_text_alignment(vertical_text_alignment);
// self.as_mut().set_font(font);
// self.as_mut().set_font_size(font_size);
// true
// }
} }
} }

View file

@ -286,11 +286,11 @@ pub mod song_model {
.get_mut(index as usize) .get_mut(index as usize)
{ {
song.title = updated_title.to_string(); song.title = updated_title.to_string();
self.as_mut().emit(Signals::DataChanged { self.as_mut().emit_data_changed(
top_left: &model_index, model_index,
bottom_right: &model_index, model_index,
roles: &vector_roles, &vector_roles,
}); );
self.as_mut().emit_title_changed(); self.as_mut().emit_title_changed();
true true
} else { } else {
@ -793,6 +793,7 @@ pub mod song_model {
let role_names_iter = role_names.iter(); let role_names_iter = role_names.iter();
if let Some(song) = self.rust().songs.get(index as usize) if let Some(song) = self.rust().songs.get(index as usize)
{ {
debug!(song);
for i in role_names_iter { for i in role_names_iter {
qvariantmap.insert( qvariantmap.insert(
QString::from(&i.1.to_string()), QString::from(&i.1.to_string()),