From d5515d4c52452881f04c16304f4db56bd5ac032f Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Tue, 22 Feb 2022 15:27:22 -0600 Subject: [PATCH] Animations in library --- README.org | 2 +- src/qml/presenter/Library.qml | 112 ++++++++++++++++---------- src/qml/presenter/LibraryDelegate.qml | 11 --- src/qml/presenter/LibraryItem.qml | 98 ---------------------- src/qml/presenter/LibraryModel.qml | 76 ----------------- src/qml/presenter/MainWindow.qml | 22 ++++- src/qml/presenter/Slide.qml | 5 +- src/qml/presenter/SongEditor.qml | 5 +- src/resources.qrc | 3 - src/songsqlmodel.cpp | 18 ++--- 10 files changed, 104 insertions(+), 248 deletions(-) delete mode 100644 src/qml/presenter/LibraryDelegate.qml delete mode 100644 src/qml/presenter/LibraryItem.qml delete mode 100644 src/qml/presenter/LibraryModel.qml diff --git a/README.org b/README.org index 8e62e20..d3b8e13 100644 --- a/README.org +++ b/README.org @@ -20,7 +20,7 @@ cd church-presenter Then build. #+BEGIN_SRC -cmake -B build/ . && cmake --build build/ +cmake -B build/ . && make --dir build/ #+END_SRC Then run. diff --git a/src/qml/presenter/Library.qml b/src/qml/presenter/Library.qml index 0993c88..db0891a 100644 --- a/src/qml/presenter/Library.qml +++ b/src/qml/presenter/Library.qml @@ -23,6 +23,7 @@ Item { id: songLibraryPanel Layout.preferredHeight: 40 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop color: Kirigami.Theme.backgroundColor Controls.Label { @@ -32,6 +33,7 @@ Item { } Controls.Label { + id: songCount anchors {left: songlable.right verticalCenter: songlable.verticalCenter leftMargin: 15} @@ -40,6 +42,22 @@ Item { color: Kirigami.Theme.disabledTextColor } + Kirigami.Icon { + id: drawerArrow + anchors {right: parent.right + verticalCenter: songCount.verticalCenter + rightMargin: 10} + source: "arrow-down" + rotation: selectedLibrary == "songs" ? 0 : 180 + + Behavior on rotation { + NumberAnimation { + easing.type: Easing.OutCubic + duration: 300 + } + } + } + MouseArea { anchors.fill: parent onClicked: { @@ -52,28 +70,22 @@ Item { } } - SongSqlModel { - id: songsqlmodel - } - ListView { - Layout.fillHeight: true + Layout.preferredHeight: parent.height - 200 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop id: songLibraryList model: songsqlmodel - delegate: itemDelegate + delegate: songDelegate state: "selected" - /* Component.onCompleted: print(selectedLibrary) */ - + Component.onCompleted: songList = songLibraryList states: [ State { name: "deselected" when: (selectedLibrary !== "songs") PropertyChanges { target: songLibraryList - height: 0 - Layout.fillHeight: false - visible: false + Layout.preferredHeight: 0 } }, State { @@ -87,34 +99,38 @@ Item { to: "*" NumberAnimation { target: songLibraryList - properties: "height" + properties: "preferredHeight" easing.type: Easing.OutCubic duration: 300 } } Component { - id: itemDelegate + id: songDelegate Kirigami.BasicListItem { id: songListItem - width: ListView.view.width - height: 40 + implicitWidth: ListView.view.width + height: selectedLibrary == "songs" ? 40 : 0 + clip: true label: title subtitle: author hoverEnabled: true - onClicked: { - ListView.view.currentIndex = index - song = ListView.view.selected - songTitle = title - songLyrics = lyrics - songAuthor = author - showPassiveNotification(songLyrics, 3000) - } + Behavior on height { + NumberAnimation { + easing.type: Easing.OutCubic + duration: 300 + } + } MouseArea { id: dragHandler anchors.fill: parent + /* width: parent.width */ + /* height: parent.height */ + /* Layout.alignment: Qt.AlignTop */ + /* x: parent.x */ + /* y: parent.y */ drag { target: songListItem onActiveChanged: { @@ -124,6 +140,15 @@ Item { } } } + onClicked: { + showPassiveNotification(title, 3000) + songLibraryList.currentIndex = index + song = songLibraryList.selected + songTitle = title + songLyrics = lyrics + songAuthor = author + } + } Drag.active: dragHandler.drag.active Drag.hotSpot.x: width / 2 @@ -159,7 +184,9 @@ Item { id: videoLibraryPanel Layout.preferredHeight: 40 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop color: Kirigami.Theme.backgroundColor + opacity: 1.0 Controls.Label { anchors.centerIn: parent @@ -180,8 +207,9 @@ Item { ListView { id: videoLibraryList - Layout.fillHeight: true + Layout.preferredHeight: parent.height - 200 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop state: "deselected" states: [ @@ -189,9 +217,7 @@ Item { name: "deselected" when: (selectedLibrary !== "videos") PropertyChanges { target: videoLibraryList - height: 0 - Layout.fillHeight: false - visible: false + Layout.preferredHeight: 0 } }, State { @@ -205,7 +231,7 @@ Item { to: "*" NumberAnimation { target: videoLibraryList - properties: "height" + properties: "preferredHeight" easing.type: Easing.OutCubic duration: 300 } @@ -216,6 +242,7 @@ Item { id: imageLibraryPanel Layout.preferredHeight: 40 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop color: Kirigami.Theme.backgroundColor Controls.Label { @@ -237,8 +264,9 @@ Item { ListView { id: imageLibraryList - Layout.fillHeight: true + Layout.preferredHeight: parent.height - 200 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop state: "deselected" states: [ @@ -246,9 +274,7 @@ Item { name: "deselected" when: (selectedLibrary !== "images") PropertyChanges { target: imageLibraryList - height: 0 - Layout.fillHeight: false - visible: false + Layout.preferredHeight: 0 } }, State { @@ -262,7 +288,7 @@ Item { to: "*" NumberAnimation { target: imageLibraryList - properties: "height" + properties: "preferredHeight" easing.type: Easing.OutCubic duration: 300 } @@ -273,6 +299,7 @@ Item { id: presentationLibraryPanel Layout.preferredHeight: 40 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop color: Kirigami.Theme.backgroundColor Controls.Label { @@ -294,8 +321,9 @@ Item { ListView { id: presentationLibraryList - Layout.fillHeight: true + Layout.preferredHeight: parent.height - 200 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop state: "deselected" states: [ @@ -303,9 +331,7 @@ Item { name: "deselected" when: (selectedLibrary !== "presentations") PropertyChanges { target: presentationLibraryList - height: 0 - Layout.fillHeight: false - visible: false + Layout.preferredHeight: 0 } }, State { @@ -319,7 +345,7 @@ Item { to: "*" NumberAnimation { target: presentationLibraryList - properties: "height" + properties: "preferredHeight" easing.type: Easing.OutCubic duration: 300 } @@ -330,6 +356,7 @@ Item { id: slideLibraryPanel Layout.preferredHeight: 40 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop color: Kirigami.Theme.backgroundColor Controls.Label { @@ -351,8 +378,9 @@ Item { ListView { id: slideLibraryList - Layout.fillHeight: true + Layout.preferredHeight: parent.height - 200 Layout.fillWidth: true + Layout.alignment: Qt.AlignTop state: "deselected" states: [ @@ -360,9 +388,7 @@ Item { name: "deselected" when: (selectedLibrary !== "slides") PropertyChanges { target: slideLibraryList - height: 0 - Layout.fillHeight: false - visible: false + Layout.preferredHeight: 0 } }, State { @@ -376,7 +402,7 @@ Item { to: "*" NumberAnimation { target: slideLibraryList - properties: "height" + properties: "preferredHeight" easing.type: Easing.OutCubic duration: 300 } diff --git a/src/qml/presenter/LibraryDelegate.qml b/src/qml/presenter/LibraryDelegate.qml deleted file mode 100644 index 3d3f3cb..0000000 --- a/src/qml/presenter/LibraryDelegate.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.13 -import org.kde.kirigami 2.13 as Kirigami - -Kirigami.BasicListItem { - width: ListView.view.width - height:20 - label: model.itemName - subtitle: model.type - hoverEnabled: true - onClicked: ListView.view.currentIndex = index -} diff --git a/src/qml/presenter/LibraryItem.qml b/src/qml/presenter/LibraryItem.qml deleted file mode 100644 index 89c00bc..0000000 --- a/src/qml/presenter/LibraryItem.qml +++ /dev/null @@ -1,98 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Dialogs 1.0 -import QtQuick.Controls 2.0 as Controls -import QtQuick.Layouts 1.2 -import org.kde.kirigami 2.13 as Kirigami -import "./" as Presenter - -Column { - id: root - - property string title: "" - required property var model - property bool open - - Rectangle { - id: panel - implicitHeight: 40 - implicitWidth: parent.width - color: Kirigami.Theme.backgroundColor - - Controls.Label { - id: titleLabel - anchors.centerIn: parent - text: title - } - - Controls.Label { - text: "^" - font.pointSize: 24 - anchors.right: parent.right - anchors.margins: 15 - anchors.baseline: open ? titleLabel.bottom : parent.bottom - rotation: open ? 180 : 0 - - Behavior on rotation { - NumberAnimation { easing.type: Easing.OutCubic; duration: 300 } - } - } - - MouseArea { - anchors.fill: parent - onClicked: open = !open - } - } - - ListView { - id: libraryList - - model: _songListModel - delegate: libraryDelegate - clip: true - implicitWidth: parent.width - height: { - if (open) - parent.height - panel.height - else - 0 - } - y: panel.height - - Behavior on height { - NumberAnimation { easing.type: Easing.OutCubic; duration: 300 } - } - - Kirigami.WheelHandler { - id: wheelHandler - target: libraryList - filterMouseEvents: true - keyNavigationEnabled: true - } - - Controls.ScrollBar.vertical: Controls.ScrollBar { - anchors.right: libraryList.right - anchors.leftMargin: 10 - active: hovered || pressed - } - } - - - Component { - id: libraryDelegate - Kirigami.BasicListItem { - width: ListView.view.width - height:40 - label: title - subtitle: author - hoverEnabled: true - onClicked: { - ListView.view.currentIndex = index - songTitle = title - songLyrics = lyrics - songAuthor = author - showPassiveNotification(songLyrics, 3000) - } - } - } - -} diff --git a/src/qml/presenter/LibraryModel.qml b/src/qml/presenter/LibraryModel.qml deleted file mode 100644 index 2f748ca..0000000 --- a/src/qml/presenter/LibraryModel.qml +++ /dev/null @@ -1,76 +0,0 @@ -import QtQuick 2.13 - -ListModel { - ListElement { - itemName: "10,000 Reason" - type: "song" - } - ListElement { - itemName: "Marvelous Light" - type: "song" - } - ListElement { - itemName: "10 reason to use church presenter" - type: "video" - } - ListElement { - itemName: "killer.jpg" - type: "image" - } - ListElement { - itemName: "Marvelous Light" - type: "song" - } - ListElement { - itemName: "Cool runnings" - type: "video" - } - ListElement { - itemName: "10,000 Reason" - type: "song" - } - ListElement { - itemName: "Slides1.odp" - type: "presentation" - } - ListElement { - itemName: "IntroSlide" - type: "custom-slide" - } - ListElement { - itemName: "10,000 Reason" - type: "song" - } - ListElement { - itemName: "Marvelous Light" - type: "song" - } - ListElement { - itemName: "other slide" - type: "custom-slide" - } - ListElement { - itemName: "10,000 Reason" - type: "song" - } - ListElement { - itemName: "Marvelous Light" - type: "song" - } - ListElement { - itemName: "10 reason to use church presenter" - type: "video" - } - ListElement { - itemName: "10,000 Reason" - type: "song" - } - ListElement { - itemName: "Marvelous Light" - type: "song" - } - ListElement { - itemName: "10 reason to use church presenter" - type: "video" - } -} diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index 9ca358c..c7aa16d 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -7,6 +7,7 @@ import QtMultimedia 5.15 import QtAudioEngine 1.15 import org.kde.kirigami 2.13 as Kirigami import "./" as Presenter +import org.presenter 1.0 Controls.Page { id: mainPage @@ -15,16 +16,18 @@ Controls.Page { // properties passed around for the slides property url imageBackground: "" property url videoBackground: "" - property var song property string songTitle: "" property string songLyrics: "" property string songAuthor: "" property int blurRadius: 0 + property ListView songList + property Item slideItem - - + property var song property var draggedLibraryItem + signal songUpdated(string title, string lyrics, string author, string ccli, string audio) + Item { id: mainItem anchors.fill: parent @@ -83,7 +86,7 @@ Controls.Page { title: "presentation-window" height: maximumHeight width: maximumWidth - screen: secondScreen + screen: screens[1].name onClosing: presenting = false Component.onCompleted: { @@ -135,4 +138,15 @@ Controls.Page { } } + + + SongSqlModel { + id: songsqlmodel + } + + function updateLyrics(lyrics) { + showPassiveNotification("adding lyrics...") + songList.model.lyrics = lyrics; + showPassiveNotification("added lyrics:\n " + lyrics) + } } diff --git a/src/qml/presenter/Slide.qml b/src/qml/presenter/Slide.qml index de1cb8c..8fc7d26 100644 --- a/src/qml/presenter/Slide.qml +++ b/src/qml/presenter/Slide.qml @@ -16,7 +16,7 @@ Item { property bool editMode: false // These properties are for the slides visuals - property real textSize: 26 + property real textSize: 72 property bool dropShadow: false property url imageSource: imageBackground property url videoSource: videoBackground @@ -85,9 +85,12 @@ Item { id: lyrics text: "This is some test lyrics" // change to song lyrics of current verse font.pointSize: textSize + minimumPointSize: 5 + fontSizeMode: Text.Fit font.family: chosenFont style: Text.Raised anchors.centerIn: parent + /* width: parent.width */ clip: true layer.enabled: true diff --git a/src/qml/presenter/SongEditor.qml b/src/qml/presenter/SongEditor.qml index f22aac7..ed51748 100644 --- a/src/qml/presenter/SongEditor.qml +++ b/src/qml/presenter/SongEditor.qml @@ -136,7 +136,7 @@ Item { text: songLyrics textFormat: TextEdit.MarkdownText padding: 10 - onEditingFinished: song.lyricsSlides(text) + onEditingFinished: mainPage.updateLyrics(text) onPressed: editorTimer.running = true } } @@ -172,7 +172,8 @@ Item { Presenter.SlideEditor { id: slideEditor Layout.preferredWidth: 500 - Layout.preferredHeight: 292 + Layout.fillWidth: true + Layout.preferredHeight: slideEditor.width / 16 * 9 Layout.bottomMargin: 30 Layout.rightMargin: 20 Layout.leftMargin: 20 diff --git a/src/resources.qrc b/src/resources.qrc index 449f368..c980732 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -5,9 +5,6 @@ qml/presenter/LeftDock.qml qml/presenter/MainWindow.qml qml/presenter/Library.qml - qml/presenter/LibraryModel.qml - qml/presenter/LibraryDelegate.qml - qml/presenter/LibraryItem.qml qml/presenter/Header.qml qml/presenter/Actions.qml qml/presenter/PanelItem.qml diff --git a/src/songsqlmodel.cpp b/src/songsqlmodel.cpp index 51efae9..fb3678c 100644 --- a/src/songsqlmodel.cpp +++ b/src/songsqlmodel.cpp @@ -17,24 +17,23 @@ static void createTable() } QSqlQuery query; - if (!query.exec( - "CREATE TABLE IF NOT EXISTS 'songs' (" + if (!query.exec("CREATE TABLE IF NOT EXISTS 'songs' (" " 'title' TEXT NOT NULL," " 'lyrics' TEXT," " 'author' TEXT," " 'ccli' TEXT," " 'audio' TEXT," - " PRIMARY KEY(title))" - )) { - qFatal("Failed to query database: %s", qPrintable(query.lastError().text())); + " PRIMARY KEY(title))")) { + qFatal("Failed to query database: %s", + qPrintable(query.lastError().text())); } query.exec("INSERT INTO songs VALUES ('10,000 Reasons', '10,000 reasons for my heart to sing', 'Matt Redman', '13470183', '')"); query.exec("INSERT INTO songs VALUES ('River', 'Im going down to the river', 'Jordan Feliz', '13470183', '')"); query.exec("INSERT INTO songs VALUES ('Marvelous Light', 'Into marvelous light Im running', 'Chris Tomlin', '13470183', '')"); - query.exec("select * from songs"); - qDebug() << query.lastQuery(); + // query.exec("select * from songs"); + // qDebug() << query.lastQuery(); } SongSqlModel::SongSqlModel(QObject *parent) @@ -43,16 +42,17 @@ SongSqlModel::SongSqlModel(QObject *parent) createTable(); setTable(songsTableName); setEditStrategy(QSqlTableModel::OnFieldChange); + // make sure to call select else the model won't fill select(); } QVariant SongSqlModel::data(const QModelIndex &index, int role) const { if (role < Qt::UserRole) { - qDebug() << role; + // qDebug() << role; return QSqlTableModel::data(index, role); } - qDebug() << role; + // qDebug() << role; const QSqlRecord sqlRecord = record(index.row()); return sqlRecord.value(role - Qt::UserRole); }