diff --git a/TODO.org b/TODO.org index a88d4f4..418883d 100644 --- a/TODO.org +++ b/TODO.org @@ -1,7 +1,15 @@ #+TITLE: Todo List * Inbox +** TODO Build out a slide preview system so we can see each slide in the song or image slideshow +[[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::Presenter.SlideEditor {]] ** TODO Make sure the video gets changed in a proper manner to not have left over video showing from previous items [[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::currentServiceItem++;]] + +- [X] Build a basic system that changes to black first and then switches to the video +- [ ] Build out a loading system that will load the next video if it needs to and then the switch can be instant. + + The second option is the best, but requires a lot more work. I have the first already working so I'll come back to this once I have more of an idea of how to do it. + ** TODO Fix possible bug in arrangingItems in draghandler [[file:~/dev/church-presenter/src/qml/presenter/DragHandle.qml::function arrangeItem() {]] ** TODO [#A] Make Presentation Window follow the presenter component @@ -10,9 +18,11 @@ ** TODO Make toolbar functional for songeditor [[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::Controls.ToolBar {]] +- [ ] Will likely need to modify the model to persist the effects stored to the songs ** TODO Finish toolbar [[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::Controls.ToolBar {]] + ** TODO Find a way to maths the textsize [[file:~/dev/church-presenter/src/qml/presenter/Slide.qml::property real textSize: 50]] diff --git a/src/assets/black.jpg b/src/assets/black.jpg new file mode 100644 index 0000000..c5796d1 Binary files /dev/null and b/src/assets/black.jpg differ diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index 994423e..80f9e4f 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -109,7 +109,9 @@ Controls.Page { function changeServiceItem(index) { const item = serviceItemModel.getItem(index); + presentation.stopVideo() presentation.itemType = item.type; + print("Time to start changing"); if (item.backgroundType === "image") { presentation.vidbackground = ""; diff --git a/src/qml/presenter/Presentation.qml b/src/qml/presenter/Presentation.qml index fc25ef4..13c22f6 100644 --- a/src/qml/presenter/Presentation.qml +++ b/src/qml/presenter/Presentation.qml @@ -16,7 +16,7 @@ Item { property url imagebackground property url vidbackground - Component.onCompleted: nextSlideText() + Component.onCompleted: nextSlideAction() GridLayout { anchors.fill: parent @@ -122,6 +122,10 @@ Item { previewSlide.loadVideo(); } + function stopVideo() { + previewSlide.stopVideo() + } + function nextSlideAction() { if (itemType === "song") { if (textIndex === 0) { @@ -135,13 +139,17 @@ Item { } else { print("Next slide time"); textIndex = 0; - previewSlide.text = ""; + clearText(); nextSlide(); } - } else if (itemType === "video") + } else if (itemType === "video") { + clearText(); nextSlide(); - else if (itemType === "image") + } + else if (itemType === "image") { + clearText(); nextSlide(); + } } function nextSlide() { @@ -149,4 +157,8 @@ Item { changeServiceItem(currentServiceItem); print(slideItem); } + + function clearText() { + previewSlide.text = ""; + } } diff --git a/src/qml/presenter/Slide.qml b/src/qml/presenter/Slide.qml index 6a15b68..b7aca7b 100644 --- a/src/qml/presenter/Slide.qml +++ b/src/qml/presenter/Slide.qml @@ -72,8 +72,26 @@ Item { Timer { id: mpvLoadingTimer - interval: 100 - onTriggered: mpv.loadFile(videoSource.toString()) + interval: 2 + onTriggered: { + mpv.loadFile(videoSource.toString()); + blackTimer.restart(); + } + } + + Timer { + id: blackTimer + interval: 400 + onTriggered: { + black.visible = false; + } + } + + Rectangle { + id: black + color: "Black" + anchors.fill: parent + visible: false } Image { @@ -89,7 +107,7 @@ Item { FastBlur { id: imageBlue anchors.fill: parent - source: imageSource == "" ? mpv : backgroundImage + source: imageSource === "" ? mpv : backgroundImage radius: blurRadius Controls.Label { @@ -126,6 +144,8 @@ Item { } function stopVideo() { - mpv.stop() + mpv.stop(); + black.visible = true; + showPassiveNotification("Black is: " + black.visible); } } diff --git a/src/qml/presenter/SlideEditor.qml b/src/qml/presenter/SlideEditor.qml index 028c104..fcd3560 100644 --- a/src/qml/presenter/SlideEditor.qml +++ b/src/qml/presenter/SlideEditor.qml @@ -13,6 +13,7 @@ Item { property string imageBackground property string videoBackground + property string textAlignment Presenter.Slide { id: representation @@ -23,4 +24,23 @@ Item { videoSource: videoBackground preview: true } + + Component.onCompleted: updateHAlignment(textAlignment) + + function updateHAlignment(alignment) { + switch (alignment) { + case "left" : + representation.horizontalAlignment = Text.AlignLeft; + break; + case "center" : + representation.horizontalAlignment = Text.AlignHCenter; + break; + case "right" : + representation.horizontalAlignment = Text.AlignRight; + break; + case "justify" : + representation.horizontalAlignment = Text.AlignJustify; + break; + } + } } diff --git a/src/qml/presenter/SongEditor.qml b/src/qml/presenter/SongEditor.qml index 0f14f45..5083fe0 100644 --- a/src/qml/presenter/SongEditor.qml +++ b/src/qml/presenter/SongEditor.qml @@ -18,6 +18,7 @@ Item { property string songVorder property string songBackground property string songBackgroundType + property string songHAlignment GridLayout { id: mainLayout @@ -50,18 +51,28 @@ Item { model: ["Left", "Center", "Right", "Justify"] implicitWidth: 100 hoverEnabled: true + onCurrentTextChanged: updateTextAlignment(currentText.toLowerCase()); + } + Controls.ComboBox { + model: ["Top", "Center", "Bottom"] + implicitWidth: 100 + hoverEnabled: true + onCurrentTextChanged: print(currentText.toLowerCase()); } Controls.ToolButton { text: "B" hoverEnabled: true + visible: false } Controls.ToolButton { text: "I" hoverEnabled: true + visible: false } Controls.ToolButton { text: "U" hoverEnabled: true + visible: false } Controls.ToolSeparator {} Item { Layout.fillWidth: true } @@ -215,6 +226,7 @@ Item { Layout.bottomMargin: 30 Layout.rightMargin: 20 Layout.leftMargin: 20 + textAlignment: songHAlignment } } } @@ -273,6 +285,7 @@ Item { songVorder = song[5]; songBackground = song[6]; songBackgroundType = song[7]; + songHAlignment = song[8]; if (songBackgroundType == "image") { slideEditor.videoBackground = ""; slideEditor.imageBackground = songBackground; @@ -313,4 +326,8 @@ Item { songsqlmodel.updateBackgroundType(songIndex, backgroundType); print("changed background"); } + + function updateTextAlignment(textAlignment) { + songsqlmodel.updateTextAlignment(songIndex, textAlignment) + } } diff --git a/src/resources.qrc b/src/resources.qrc index 5fc74df..30066e3 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -17,5 +17,6 @@ qml/presenter/Presentation.qml qml/presenter/Settings.qml assets/parallel.jpg + assets/black.jpg diff --git a/src/songsqlmodel.cpp b/src/songsqlmodel.cpp index 218fa31..61e7c6c 100644 --- a/src/songsqlmodel.cpp +++ b/src/songsqlmodel.cpp @@ -34,6 +34,7 @@ static void createTable() " 'vorder' TEXT," " 'background' TEXT," " 'backgroundType' TEXT," + " 'textAlignment' TEXT," " PRIMARY KEY(id))")) { qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); @@ -41,11 +42,18 @@ static void createTable() qDebug() << query.lastQuery(); qDebug() << "inserting into songs"; - query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, background, backgroundType) VALUES ('10,000 Reasons', '10,000 reasons for my heart to sing', 'Matt Redman', '13470183', '', '', '', '')"); + query.exec( + "INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, " + "background, backgroundType) VALUES ('10,000 Reasons', '10,000 reasons " + "for my heart to sing', 'Matt Redman', '13470183', '', '', '', '', 'center')"); qDebug() << query.lastQuery(); - query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, background, backgroundType) VALUES ('River', 'Im going down to the river', 'Jordan Feliz', '13470183', '', '', '', '')"); - query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, background, backgroundType) VALUES ('Marvelous Light', 'Into marvelous " - "light Im running', 'Chris Tomlin', '13470183', '', '', '', '')"); + query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, " + "background, backgroundType) VALUES ('River', 'Im going down to " + "the river', 'Jordan Feliz', '13470183', '', '', '', '', 'center')"); + query.exec( + "INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, " + "background, backgroundType) VALUES ('Marvelous Light', 'Into marvelous " + "light Im running', 'Chris Tomlin', '13470183', '', '', '', '', 'center')"); query.exec("select * from songs"); qDebug() << query.lastQuery(); @@ -85,6 +93,7 @@ QHash SongSqlModel::roleNames() const names[Qt::UserRole + 6] = "vorder"; names[Qt::UserRole + 7] = "background"; names[Qt::UserRole + 8] = "backgroundType"; + names[Qt::UserRole + 9] = "textAlignment"; return names; } @@ -130,6 +139,7 @@ QVariantList SongSqlModel::getSong(const int &row) { song.append(recordData.value("vorder")); song.append(recordData.value("background")); song.append(recordData.value("backgroundType")); + song.append(recordData.value("textAlignment")); return song; } @@ -394,3 +404,29 @@ void SongSqlModel::updateBackgroundType(const int &row, const QString &backgroun submitAll(); emit backgroundTypeChanged(); } + +QString SongSqlModel::textAlignment() const { + return m_textAlignment; +} + +void SongSqlModel::setTextAlignment(const QString &textAlignment) { + if (textAlignment == m_textAlignment) + return; + + m_textAlignment = textAlignment; + + select(); + emit textAlignmentChanged(); +} + +// This function is for updating the lyrics from outside the delegate +void SongSqlModel::updateTextAlignment(const int &row, const QString &textAlignment) { + qDebug() << "Row is " << row; + QSqlRecord rowdata = record(row); + qDebug() << rowdata; + rowdata.setValue("textAlignment", textAlignment); + setRecord(row, rowdata); + qDebug() << rowdata; + submitAll(); + emit textAlignmentChanged(); +} diff --git a/src/songsqlmodel.h b/src/songsqlmodel.h index 09045c1..b90dd60 100644 --- a/src/songsqlmodel.h +++ b/src/songsqlmodel.h @@ -18,6 +18,7 @@ class SongSqlModel : public QSqlTableModel Q_PROPERTY(QString vorder READ vorder WRITE setVerseOrder NOTIFY vorderChanged) Q_PROPERTY(QString background READ background WRITE setBackground NOTIFY backgroundChanged) Q_PROPERTY(QString backgroundType READ backgroundType WRITE setBackgroundType NOTIFY backgroundTypeChanged) + Q_PROPERTY(QString textAlignment READ textAlignment WRITE setTextAlignment NOTIFY textAlignmentChanged) QML_ELEMENT public: @@ -32,6 +33,7 @@ public: QString vorder() const; QString background() const; QString backgroundType() const; + QString textAlignment() const; void setTitle(const QString &title); void setLyrics(const QString &lyrics); @@ -41,6 +43,7 @@ public: void setVerseOrder(const QString &vorder); void setBackground(const QString &background); void setBackgroundType(const QString &backgroundType); + void setTextAlignment(const QString &background); Q_INVOKABLE void updateTitle(const int &row, const QString &title); Q_INVOKABLE void updateLyrics(const int &row, const QString &lyrics); @@ -50,6 +53,7 @@ public: Q_INVOKABLE void updateVerseOrder(const int &row, const QString &vorder); Q_INVOKABLE void updateBackground(const int &row, const QString &background); Q_INVOKABLE void updateBackgroundType(const int &row, const QString &backgroundType); + Q_INVOKABLE void updateTextAlignment(const int &row, const QString &textAlignment); Q_INVOKABLE void newSong(); Q_INVOKABLE void deleteSong(const int &row); @@ -68,6 +72,7 @@ signals: void vorderChanged(); void backgroundChanged(); void backgroundTypeChanged(); + void textAlignmentChanged(); private: int m_id; @@ -79,6 +84,7 @@ private: QString m_vorder; QString m_background; QString m_backgroundType; + QString m_textAlignment; }; #endif //SONGSQLMODEL_H