From d647f4442f5486c25a1b424e9b41ad40ad96e4d1 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Sun, 20 Feb 2022 07:29:41 -0600 Subject: [PATCH] adding a presentmode --- src/qml/main.qml | 2 + src/qml/presenter/Header.qml | 6 + src/qml/presenter/Library.qml | 666 ++++++++++++++--------------- src/qml/presenter/MainWindow.qml | 27 +- src/qml/presenter/Presentation.qml | 67 +++ src/qml/presenter/Slide.qml | 47 +- src/qml/presenter/SongEditor.qml | 166 +++---- src/resources.qrc | 1 + src/serviceitem.cpp | 57 --- src/serviceitem.h | 33 -- src/songtext.cpp | 25 -- src/songtext.h | 27 -- 12 files changed, 534 insertions(+), 590 deletions(-) create mode 100644 src/qml/presenter/Presentation.qml delete mode 100644 src/serviceitem.cpp delete mode 100644 src/serviceitem.h delete mode 100644 src/songtext.cpp delete mode 100644 src/songtext.h diff --git a/src/qml/main.qml b/src/qml/main.qml index 78a7b36..764dc69 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -13,6 +13,7 @@ Kirigami.ApplicationWindow { property bool libraryOpen: true property bool presenting: false + property bool presentMode: true property var secondScreen: null pageStack.initialPage: mainPage @@ -30,6 +31,7 @@ Kirigami.ApplicationWindow { Component.onCompleted: { print("checking screens") + print("Present Mode is " + presentMode) secondScreen = Qt.application.screens[1] print(secondScreen) } diff --git a/src/qml/presenter/Header.qml b/src/qml/presenter/Header.qml index 1b1015e..f90bce2 100644 --- a/src/qml/presenter/Header.qml +++ b/src/qml/presenter/Header.qml @@ -29,6 +29,12 @@ Kirigami.ActionToolBar { } }, + Kirigami.Action { + icon.name: "edit" + text: presentMode ? "Edit" : "Preview" + onTriggered: presentMode = !presentMode + }, + Kirigami.Action { icon.name: "view-presentation" text: "Go Live" diff --git a/src/qml/presenter/Library.qml b/src/qml/presenter/Library.qml index e194b52..bf37f53 100644 --- a/src/qml/presenter/Library.qml +++ b/src/qml/presenter/Library.qml @@ -12,379 +12,363 @@ Item { Kirigami.Theme.colorSet: Kirigami.Theme.View - ColumnLayout { + Rectangle { anchors.fill: parent - spacing: 0 - Rectangle { - id: songLibraryPanel - Layout.preferredHeight: 40 - Layout.fillWidth: true - color: Kirigami.Theme.backgroundColor + color: Kirigami.Theme.backgroundColor + ColumnLayout { + anchors.fill: parent + spacing: 0 + Rectangle { + id: songLibraryPanel + Layout.preferredHeight: 40 + Layout.fillWidth: true + color: Kirigami.Theme.backgroundColor - Controls.Label { - anchors.centerIn: parent - text: "Songs" - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (selectedLibrary == "songs") - selectedLibrary = "" - else - selectedLibrary = "songs" - print(selectedLibrary) + Controls.Label { + anchors.centerIn: parent + text: "Songs" } - } - } - ListView { - Layout.fillHeight: true - Layout.fillWidth: true - id: songLibraryList - model: _songListModel - delegate: itemDelegate - state: "selected" - - Component.onCompleted: print(selectedLibrary) - - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "songs") - PropertyChanges { target: songLibraryList - height: 0 - Layout.fillHeight: false - visible: false - } - }, - State { - name: "selected" - when: (selectedLibrary == "songs") - PropertyChanges { target: songLibraryList } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: songLibraryList - properties: "height" - easing.type: Easing.OutCubic - duration: 300 - } - } - - Component { - id: itemDelegate - Kirigami.BasicListItem { - id: songListItem - width: ListView.view.width - height:40 - label: title - subtitle: author - hoverEnabled: true + MouseArea { + anchors.fill: parent onClicked: { - ListView.view.currentIndex = index - song = ListView.view.selected - songTitle = title - songLyrics = lyrics - songAuthor = author - showPassiveNotification(songLyrics, 3000) + if (selectedLibrary == "songs") + selectedLibrary = "" + else + selectedLibrary = "songs" + print(selectedLibrary) } + } + } - Drag.active: dragHandler.drag.active - Drag.hotSpot.x: width / 2 - Drag.hotSpot.y: height / 2 + ListView { + Layout.fillHeight: true + Layout.fillWidth: true + id: songLibraryList + model: _songListModel + delegate: itemDelegate + state: "selected" - MouseArea { - id: dragHandler - anchors.fill: parent - drag { - target: songListItem - onActiveChanged: { - if (dragHandler.drag.active) { - draggedLibraryItem = songLibraryList.currentItem - showPassiveNotification(index) + Component.onCompleted: print(selectedLibrary) + + states: [ + State { + name: "deselected" + when: (selectedLibrary !== "songs") + PropertyChanges { target: songLibraryList + height: 0 + Layout.fillHeight: false + visible: false + } + }, + State { + name: "selected" + when: (selectedLibrary == "songs") + PropertyChanges { target: songLibraryList } + } + ] + + transitions: Transition { + to: "*" + NumberAnimation { + target: songLibraryList + properties: "height" + easing.type: Easing.OutCubic + duration: 300 + } + } + + Component { + id: itemDelegate + + Kirigami.BasicListItem { + id: songListItem + width: ListView.view.width + height: 40 + label: title + subtitle: author + hoverEnabled: true + onClicked: { + ListView.view.currentIndex = index + song = ListView.view.selected + songTitle = title + songLyrics = lyrics + songAuthor = author + showPassiveNotification(songLyrics, 3000) + } + + MouseArea { + id: dragHandler + anchors.fill: parent + drag { + target: songListItem + onActiveChanged: { + if (dragHandler.drag.active) { + draggedLibraryItem = songLibraryList.currentItem + showPassiveNotification(index) + } } } } - } + Drag.active: dragHandler.drag.active + Drag.hotSpot.x: width / 2 + Drag.hotSpot.y: height / 2 - states: State { - name: "dragged" - when: songListItem.Drag.active - PropertyChanges { - target: songListItem - x: x - y: y + states: State { + name: "dragged" + when: songListItem.Drag.active + PropertyChanges { + target: songListItem + x: x + y: y + } } } } - } - Kirigami.WheelHandler { - id: wheelHandler - target: songLibraryList - filterMouseEvents: true - keyNavigationEnabled: true - } - - Controls.ScrollBar.vertical: Controls.ScrollBar { - anchors.right: songLibraryList.right - anchors.leftMargin: 10 - active: hovered || pressed - } - } - - Rectangle { - id: videoLibraryPanel - Layout.preferredHeight: 40 - Layout.fillWidth: true - color: Kirigami.Theme.backgroundColor - - Controls.Label { - anchors.centerIn: parent - text: "Videos" - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (selectedLibrary == "videos") - selectedLibrary = "" - else - selectedLibrary = "videos" - print(selectedLibrary) + Kirigami.WheelHandler { + id: wheelHandler + target: songLibraryList + filterMouseEvents: true + keyNavigationEnabled: true } - } - } - ListView { - id: videoLibraryList - Layout.fillHeight: true - Layout.fillWidth: true - state: "deselected" - - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "videos") - PropertyChanges { target: videoLibraryList - height: 0 - Layout.fillHeight: false - visible: false - } - }, - State { - name: "selected" - when: (selectedLibrary == "videos") - PropertyChanges { target: videoLibraryList } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: videoLibraryList - properties: "height" - easing.type: Easing.OutCubic - duration: 300 - } - } - } - - Rectangle { - id: imageLibraryPanel - Layout.preferredHeight: 40 - Layout.fillWidth: true - color: Kirigami.Theme.backgroundColor - - Controls.Label { - anchors.centerIn: parent - text: "Images" - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (selectedLibrary == "images") - selectedLibrary = "" - else - selectedLibrary = "images" - print(selectedLibrary) - } - } - } - - ListView { - id: imageLibraryList - Layout.fillHeight: true - Layout.fillWidth: true - state: "deselected" - - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "images") - PropertyChanges { target: imageLibraryList - height: 0 - Layout.fillHeight: false - visible: false - } - }, - State { - name: "selected" - when: (selectedLibrary == "images") - PropertyChanges { target: imageLibraryList } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: imageLibraryList - properties: "height" - easing.type: Easing.OutCubic - duration: 300 + Controls.ScrollBar.vertical: Controls.ScrollBar { + anchors.right: songLibraryList.right + anchors.leftMargin: 10 + active: hovered || pressed } } - } - Rectangle { - id: presentationLibraryPanel - Layout.preferredHeight: 40 - Layout.fillWidth: true - color: Kirigami.Theme.backgroundColor + Rectangle { + id: videoLibraryPanel + Layout.preferredHeight: 40 + Layout.fillWidth: true + color: Kirigami.Theme.backgroundColor - Controls.Label { - anchors.centerIn: parent - text: "Presentations" - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (selectedLibrary == "presentations") - selectedLibrary = "" - else - selectedLibrary = "presentations" - print(selectedLibrary) + Controls.Label { + anchors.centerIn: parent + text: "Videos" } - } - } - ListView { - id: presentationLibraryList - Layout.fillHeight: true - Layout.fillWidth: true - state: "deselected" - - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "presentations") - PropertyChanges { target: presentationLibraryList - height: 0 - Layout.fillHeight: false - visible: false - } - }, - State { - name: "selected" - when: (selectedLibrary == "presentations") - PropertyChanges { target: presentationLibraryList } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: presentationLibraryList - properties: "height" - easing.type: Easing.OutCubic - duration: 300 + MouseArea { + anchors.fill: parent + onClicked: { + if (selectedLibrary == "videos") + selectedLibrary = "" + else + selectedLibrary = "videos" + print(selectedLibrary) + } } } - } - Rectangle { - id: slideLibraryPanel - Layout.preferredHeight: 40 - Layout.fillWidth: true - color: Kirigami.Theme.backgroundColor + ListView { + id: videoLibraryList + Layout.fillHeight: true + Layout.fillWidth: true + state: "deselected" - Controls.Label { - anchors.centerIn: parent - text: "Slides" - } + states: [ + State { + name: "deselected" + when: (selectedLibrary !== "videos") + PropertyChanges { target: videoLibraryList + height: 0 + Layout.fillHeight: false + visible: false + } + }, + State { + name: "selected" + when: (selectedLibrary == "videos") + PropertyChanges { target: videoLibraryList } + } + ] - MouseArea { - anchors.fill: parent - onClicked: { - if (selectedLibrary == "slides") - selectedLibrary = "" - else - selectedLibrary = "slides" - print(selectedLibrary) - } - } - } - - ListView { - id: slideLibraryList - Layout.fillHeight: true - Layout.fillWidth: true - state: "deselected" - - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "slides") - PropertyChanges { target: slideLibraryList - height: 0 - Layout.fillHeight: false - visible: false - } - }, - State { - name: "selected" - when: (selectedLibrary == "slides") - PropertyChanges { target: slideLibraryList } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: slideLibraryList - properties: "height" - easing.type: Easing.OutCubic - duration: 300 + transitions: Transition { + to: "*" + NumberAnimation { + target: videoLibraryList + properties: "height" + easing.type: Easing.OutCubic + duration: 300 + } } } - } + Rectangle { + id: imageLibraryPanel + Layout.preferredHeight: 40 + Layout.fillWidth: true + color: Kirigami.Theme.backgroundColor + + Controls.Label { + anchors.centerIn: parent + text: "Images" + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (selectedLibrary == "images") + selectedLibrary = "" + else + selectedLibrary = "images" + print(selectedLibrary) + } + } + } + + ListView { + id: imageLibraryList + Layout.fillHeight: true + Layout.fillWidth: true + state: "deselected" + + states: [ + State { + name: "deselected" + when: (selectedLibrary !== "images") + PropertyChanges { target: imageLibraryList + height: 0 + Layout.fillHeight: false + visible: false + } + }, + State { + name: "selected" + when: (selectedLibrary == "images") + PropertyChanges { target: imageLibraryList } + } + ] + + transitions: Transition { + to: "*" + NumberAnimation { + target: imageLibraryList + properties: "height" + easing.type: Easing.OutCubic + duration: 300 + } + } + + } + Rectangle { + id: presentationLibraryPanel + Layout.preferredHeight: 40 + Layout.fillWidth: true + color: Kirigami.Theme.backgroundColor + + Controls.Label { + anchors.centerIn: parent + text: "Presentations" + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (selectedLibrary == "presentations") + selectedLibrary = "" + else + selectedLibrary = "presentations" + print(selectedLibrary) + } + } + } + + ListView { + id: presentationLibraryList + Layout.fillHeight: true + Layout.fillWidth: true + state: "deselected" + + states: [ + State { + name: "deselected" + when: (selectedLibrary !== "presentations") + PropertyChanges { target: presentationLibraryList + height: 0 + Layout.fillHeight: false + visible: false + } + }, + State { + name: "selected" + when: (selectedLibrary == "presentations") + PropertyChanges { target: presentationLibraryList } + } + ] + + transitions: Transition { + to: "*" + NumberAnimation { + target: presentationLibraryList + properties: "height" + easing.type: Easing.OutCubic + duration: 300 + } + } + + } + Rectangle { + id: slideLibraryPanel + Layout.preferredHeight: 40 + Layout.fillWidth: true + color: Kirigami.Theme.backgroundColor + + Controls.Label { + anchors.centerIn: parent + text: "Slides" + } + + MouseArea { + anchors.fill: parent + onClicked: { + if (selectedLibrary == "slides") + selectedLibrary = "" + else + selectedLibrary = "slides" + print(selectedLibrary) + } + } + } + + ListView { + id: slideLibraryList + Layout.fillHeight: true + Layout.fillWidth: true + state: "deselected" + + states: [ + State { + name: "deselected" + when: (selectedLibrary !== "slides") + PropertyChanges { target: slideLibraryList + height: 0 + Layout.fillHeight: false + visible: false + } + }, + State { + name: "selected" + when: (selectedLibrary == "slides") + PropertyChanges { target: slideLibraryList } + } + ] + + transitions: Transition { + to: "*" + NumberAnimation { + target: slideLibraryList + properties: "height" + easing.type: Easing.OutCubic + duration: 300 + } + } + + } + } } - /* Presenter.LibraryItem { */ - /* id: songLibrary */ - /* title: "Songs" */ - /* model: _songListModel */ - /* open: true */ - /* /\* type: "song" *\/ */ - /* width: parent.width */ - /* anchors.top: parent.top */ - /* } */ - - /* Presenter.LibraryItem { */ - /* id: ssongLibrary */ - /* title: "Songs" */ - /* model: _songListModel */ - /* open: false */ - /* width: parent.width */ - /* /\* type: "song" *\/ */ - /* anchors.top: songLibrary.bottom */ - /* } */ - } diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index 696c56e..9ca358c 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -11,6 +11,8 @@ import "./" as Presenter Controls.Page { id: mainPage padding: 0 + + // properties passed around for the slides property url imageBackground: "" property url videoBackground: "" property var song @@ -18,6 +20,9 @@ Controls.Page { property string songLyrics: "" property string songAuthor: "" property int blurRadius: 0 + property Item slideItem + + property var draggedLibraryItem Item { @@ -29,14 +34,11 @@ Controls.Page { anchors.fill: parent handle: Item{ implicitWidth: 6 - Rectangle { height: parent.height anchors.horizontalCenter: parent.horizontalCenter - implicitWidth: 2 + implicitWidth: 1 color: Controls.SplitHandle.hovered ? Kirigami.Theme.hoverColor : Kirigami.Theme.backgroundColor - //Controls.SplitHandle.pressed ? Kirigami.Theme.focusColor - //: (Controls.Splithandle.hovered ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor) } } @@ -46,15 +48,23 @@ Controls.Page { Controls.SplitView.preferredWidth: 200 Controls.SplitView.maximumWidth: 300 } - + Presenter.SongEditor { - id: rightMainArea + id: songEditor Controls.SplitView.fillHeight: true Controls.SplitView.fillWidth: true Controls.SplitView.preferredWidth: 700 Controls.SplitView.minimumWidth: 500 } + /* Presenter.Presentation { */ + /* id: presentation */ + /* Controls.SplitView.fillHeight: true */ + /* Controls.SplitView.fillWidth: true */ + /* Controls.SplitView.preferredWidth: 700 */ + /* Controls.SplitView.minimumWidth: 500 */ + /* } */ + Presenter.Library { id: library Controls.SplitView.fillHeight: true @@ -63,7 +73,6 @@ Controls.Page { } } - } Loader { @@ -76,14 +85,18 @@ Controls.Page { width: maximumWidth screen: secondScreen onClosing: presenting = false + Component.onCompleted: { presentationWindow.showFullScreen(); print(Qt.application.screens[1]) } + Presenter.Slide { id: presentationSlide imageSource: imageBackground videoSource: videoBackground + + Component.onCompleted: slideItem = presentationSlide } } } diff --git a/src/qml/presenter/Presentation.qml b/src/qml/presenter/Presentation.qml new file mode 100644 index 0000000..3ca05e6 --- /dev/null +++ b/src/qml/presenter/Presentation.qml @@ -0,0 +1,67 @@ +import QtQuick 2.13 +import QtQuick.Dialogs 1.0 +import QtQuick.Controls 2.15 as Controls +import QtQuick.Window 2.13 +import QtQuick.Layouts 1.2 +import QtAudioEngine 1.15 +import org.kde.kirigami 2.13 as Kirigami +import "./" as Presenter + +Item { + id: root + + GridLayout { + anchors.fill: parent + columns: 3 + rowSpacing: 5 + columnSpacing: 0 + + Controls.ToolBar { + Layout.fillWidth: true + Layout.columnSpan: 3 + id: toolbar + RowLayout { + anchors.fill: parent + + Controls.ToolButton { + text: "Grid" + } + Controls.ToolButton { + text: "Solo" + } + Controls.ToolSeparator {} + Item { Layout.fillWidth: true } + Controls.ToolSeparator {} + Controls.ToolButton { + text: "Effects" + icon.name: "image-auto-adjust" + onClicked: {} + } + Controls.ToolButton { + id: backgroundButton + text: "Background" + icon.name: "fileopen" + onClicked: backgroundType.open() + } + } + } + + Kirigami.Icon { + source: "arrow-left" + Layout.fillHeight: true + Layout.fillWidth: true + Layout.preferredWidth: 25 + } + + Presenter.Slide { + Layout.preferredWidth: 50 + } + + Kirigami.Icon { + source: "arrow-right" + Layout.fillHeight: true + Layout.fillWidth: true + Layout.preferredWidth: 25 + } + } +} diff --git a/src/qml/presenter/Slide.qml b/src/qml/presenter/Slide.qml index e94b561..de1cb8c 100644 --- a/src/qml/presenter/Slide.qml +++ b/src/qml/presenter/Slide.qml @@ -12,39 +12,25 @@ Item { id: root anchors.fill: parent - property real textSize: 26 + // Let's make this slide editable property bool editMode: false + + // These properties are for the slides visuals + property real textSize: 26 property bool dropShadow: false property url imageSource: imageBackground property url videoSource: videoBackground property string chosenFont: "Quicksand" property color backgroundColor + // These properties help to determine the state of the slide + property string itemType + Rectangle { id: basePrColor anchors.fill: parent color: "black" - /* MediaPlayer { */ - /* id: mediaPlayer */ - /* source: videoSource */ - /* loops: MediaPlayer.Infinite */ - /* autoPlay: editMode ? false : true */ - /* notifyInterval: 100 */ - /* } */ - - /* VideoOutput { */ - /* id: videoPlayer */ - /* anchors.fill: parent */ - /* source: mediaPlayer */ - /* /\* flushMode: VideoOutput.LastFrame *\/ */ - /* MouseArea { */ - /* id: playArea */ - /* anchors.fill: parent */ - /* onPressed: mediaPlayer.play(); */ - /* } */ - /* } */ - MpvObject { id: mpv objectName: "mpv" @@ -60,15 +46,17 @@ Item { MouseArea { id: playArea anchors.fill: parent + enabled: editMode onPressed: mpv.loadFile(videoSource.toString()); } - /* Controls.ProgressBar { */ - /* anchors.centerIn: parent */ - /* width: parent.width - 400 */ - /* value: mpv.position */ - /* to: mpv.duration */ - /* } */ + Controls.ProgressBar { + anchors.centerIn: parent + visible: editMode + width: parent.width - 400 + value: mpv.position + to: mpv.duration + } } Timer { @@ -111,7 +99,10 @@ Item { color: "#80000000" } } - } } + + function changeText(text) { + lyrics.text = text + } } diff --git a/src/qml/presenter/SongEditor.qml b/src/qml/presenter/SongEditor.qml index ce0ea12..f22aac7 100644 --- a/src/qml/presenter/SongEditor.qml +++ b/src/qml/presenter/SongEditor.qml @@ -3,7 +3,6 @@ import QtQuick.Dialogs 1.0 import QtQuick.Controls 2.15 as Controls import QtQuick.Window 2.13 import QtQuick.Layouts 1.2 -import QtMultimedia 5.15 import QtAudioEngine 1.15 import org.kde.kirigami 2.13 as Kirigami import "./" as Presenter @@ -65,11 +64,15 @@ Item { id: backgroundType x: backgroundButton.x y: backgroundButton.y + backgroundButton.height + 20 - width: 200 - height: 100 modal: true focus: true dim: false + background: Rectangle { + Kirigami.Theme.colorSet: Kirigami.Theme.Tooltip + color: Kirigami.Theme.backgroundColor + border.color: Kirigami.Theme.activeBackgroundColor + border.width: 2 + } closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent ColumnLayout { anchors.fill: parent @@ -92,79 +95,98 @@ Item { } } - Controls.TextField { - id: songTitleField - - Layout.preferredWidth: 300 - Layout.fillWidth: true - Layout.leftMargin: 20 - Layout.rightMargin: 20 - - placeholderText: "Song Title..." - text: songTitle - padding: 10 - } - - Rectangle { - id: slideBar - color: Kirigami.Theme.highlightColor - - Layout.preferredWidth: 700 - Layout.preferredHeight: songTitleField.height - Layout.rightMargin: 20 - } - - Controls.ScrollView { - id: songLyricsField - - Layout.preferredHeight: 3000 - Layout.fillWidth: true + Controls.SplitView { Layout.fillHeight: true - Layout.leftMargin: 20 - - rightPadding: 20 - - Controls.TextArea { - width: parent.width - - placeholderText: "Put lyrics here..." - persistentSelection: true - text: songLyrics - textFormat: TextEdit.MarkdownText - padding: 10 - onEditingFinished: song.lyricsSlides(text) - onPressed: editorTimer.running = true - } - } - - Presenter.SlideEditor { - id: slideEditor - Layout.preferredWidth: 700 - Layout.preferredHeight: 394 - Layout.bottomMargin: 30 - Layout.rightMargin: 20 - Layout.rowSpan: 2 - } - - Controls.TextField { - id: songAuthorField - Layout.fillWidth: true - Layout.preferredWidth: 300 - Layout.leftMargin: 20 - Layout.rightMargin: 20 + Layout.columnSpan: 2 - placeholderText: "Author..." - text: songAuthor - padding: 10 - } + ColumnLayout { + Controls.SplitView.fillHeight: true + Controls.SplitView.preferredWidth: 500 + Controls.SplitView.minimumWidth: 500 + + Controls.TextField { + id: songTitleField + + Layout.preferredWidth: 300 + Layout.fillWidth: true + Layout.leftMargin: 20 + Layout.rightMargin: 20 + + placeholderText: "Song Title..." + text: songTitle + padding: 10 + } + + Controls.ScrollView { + id: songLyricsField + + Layout.preferredHeight: 3000 + Layout.fillWidth: true + Layout.fillHeight: true + Layout.leftMargin: 20 + + rightPadding: 20 + + Controls.TextArea { + width: parent.width + + placeholderText: "Put lyrics here..." + persistentSelection: true + text: songLyrics + textFormat: TextEdit.MarkdownText + padding: 10 + onEditingFinished: song.lyricsSlides(text) + onPressed: editorTimer.running = true + } + } + Controls.TextField { + id: songAuthorField + + Layout.fillWidth: true + Layout.preferredWidth: 300 + Layout.leftMargin: 20 + Layout.rightMargin: 20 + + placeholderText: "Author..." + text: songAuthor + padding: 10 + } + + } + ColumnLayout { + Controls.SplitView.fillHeight: true + Controls.SplitView.preferredWidth: 500 + Controls.SplitView.minimumWidth: 300 + + Rectangle { + id: slideBar + color: Kirigami.Theme.highlightColor + + Layout.preferredWidth: 500 + Layout.preferredHeight: songTitleField.height + Layout.rightMargin: 20 + Layout.leftMargin: 20 + } + + Presenter.SlideEditor { + id: slideEditor + Layout.preferredWidth: 500 + Layout.preferredHeight: 292 + Layout.bottomMargin: 30 + Layout.rightMargin: 20 + Layout.leftMargin: 20 + } + + } } - Timer { - id: editorTimer - interval: 2000 - repeat: true - running: false - onTriggered: showPassiveNotification("updating song...") + } + Timer { + id: editorTimer + interval: 2000 + repeat: true + running: false + onTriggered: showPassiveNotification("updating song...") } } diff --git a/src/resources.qrc b/src/resources.qrc index 8645259..449f368 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -15,6 +15,7 @@ qml/presenter/Slide.qml qml/presenter/SlideEditor.qml qml/presenter/DragHandle.qml + qml/presenter/Presentation.qml assets/parallel.jpg diff --git a/src/serviceitem.cpp b/src/serviceitem.cpp deleted file mode 100644 index 22855bf..0000000 --- a/src/serviceitem.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "serviceitem.h" - -ServiceItem::ServiceItem(QObject *parent) - : QAbstractListModel(parent) -{ -} - -int ServiceItem::rowCount(const QModelIndex &parent) const -{ - // For list models only the root node (an invalid parent) should return the list's size. For all - // other (valid) parents, rowCount() should return 0 so that it does not become a tree model. - if (parent.isValid()) - return 0; - - // FIXME: Implement me! -} - -QVariant ServiceItem::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - // FIXME: Implement me! - return QVariant(); -} - -bool ServiceItem::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (data(index, role) != value) { - // FIXME: Implement me! - emit dataChanged(index, index, QVector() << role); - return true; - } - return false; -} - -Qt::ItemFlags ServiceItem::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - - return Qt::ItemIsEditable; // FIXME: Implement me! -} - -bool ServiceItem::insertRows(int row, int count, const QModelIndex &parent) -{ - beginInsertRows(parent, row, row + count - 1); - // FIXME: Implement me! - endInsertRows(); -} - -bool ServiceItem::removeRows(int row, int count, const QModelIndex &parent) -{ - beginRemoveRows(parent, row, row + count - 1); - // FIXME: Implement me! - endRemoveRows(); -} diff --git a/src/serviceitem.h b/src/serviceitem.h deleted file mode 100644 index 71d76c0..0000000 --- a/src/serviceitem.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef SERVICEITEM_H -#define SERVICEITEM_H - -#include - -class ServiceItem : public QAbstractListModel -{ - Q_OBJECT - -public: - explicit ServiceItem(QObject *parent = nullptr); - - // Basic functionality: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - // Editable: - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) override; - - Qt::ItemFlags flags(const QModelIndex& index) const override; - - // Add data: - bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - - // Remove data: - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - -private: -}; - -#endif // SERVICEITEM_H diff --git a/src/songtext.cpp b/src/songtext.cpp deleted file mode 100644 index ec4565a..0000000 --- a/src/songtext.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "songtext.h" - -SongText::SongText(QObject *parent) : - QObject(parent) -{ -} - -QString SongText::songText() -{ - return m_songText; -} - -void SongText::setSongText(const QString &songText) -{ - if (songText == m_songText) - return; - - QTextStream stream(&songText); - QString line = stream.readLine(); - qDebug() << line; - - m_songText = songText; - emit songTextChanged(); -} - diff --git a/src/songtext.h b/src/songtext.h deleted file mode 100644 index dcbc56d..0000000 --- a/src/songtext.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SONGTEXT_H -#define SONGTEXT_H - -#include -#include -#include - -class SongText : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString songText READ songText WRITE setSongText NOTIFY songTextChanged) - QML_ELEMENT - -public: - explicit SongText(QObject *parent = nullptr); - - QString songText(); - void setSongText(const QString &lyrics); - -signals: - void songTextChanged(); - -private: - QString m_songText; -}; - -#endif // SONGTEXT_H