update to make song_editor ready
This commit is contained in:
parent
e1cfa5e843
commit
96d5bdac73
5 changed files with 93 additions and 85 deletions
22
TODO.org
22
TODO.org
|
@ -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....
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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(); */
|
||||||
|
|
|
@ -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
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue