From defb73c0af974dd1c6ea7fab021d9052637d8059 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Wed, 17 Apr 2024 15:58:25 -0500 Subject: [PATCH] trying to make a slide editing system --- src/qml/presenter/Library.qml | 151 +++++------------------------ src/qml/presenter/MainWindow.qml | 20 ++++ src/qml/presenter/SlideEditor.qml | 155 ++++++++++++++++++++++++++++++ src/qml/presenter/TextBox.qml | 13 +++ src/resources.qrc | 2 + src/rust/slides/mod.rs | 1 + src/rust/slides/slide.rs | 4 + src/rust/utils.rs | 2 +- 8 files changed, 220 insertions(+), 128 deletions(-) create mode 100644 src/qml/presenter/SlideEditor.qml create mode 100644 src/qml/presenter/TextBox.qml create mode 100644 src/rust/slides/mod.rs create mode 100644 src/rust/slides/slide.rs diff --git a/src/qml/presenter/Library.qml b/src/qml/presenter/Library.qml index cb8e2f6..d4052d4 100644 --- a/src/qml/presenter/Library.qml +++ b/src/qml/presenter/Library.qml @@ -124,141 +124,38 @@ Item { } - Rectangle { - id: slideLibraryPanel - Layout.preferredHeight: 40 - Layout.fillWidth: true + Presenter.LibraryItem { + id: slideLibrary Layout.alignment: Qt.AlignTop - color: Kirigami.Theme.backgroundColor - - Controls.Label { - anchors.centerIn: parent - text: "Slides" - } - - MouseArea { - anchors.fill: parent - onClicked: { - if (selectedLibrary == "slides") - selectedLibrary = "" - else - selectedLibrary = "slides" - console.log(selectedLibrary) - } - } - } - - Rectangle { - id: slideLibraryHeader - z: 2 - Layout.preferredHeight: 40 Layout.fillWidth: true - /* width: parent.width */ - color: Kirigami.Theme.backgroundColor - opacity: 1 - state: "deselected" + Layout.preferredHeight: parent.height - 280 + /* proxyModel: presProxyModel */ + innerModel: slideModel + libraryType: "slide" + headerLabel: "Slides" + itemIcon: "x-office-presentation-symbolic" + /* itemSubtitle: model.path */ + count: innerModel.count + newItemFunction: (function() { + if (!editMode) + editMode = true; + editSwitch(0, libraryType); + }) + } - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "slides") - PropertyChanges { target: slideLibraryHeader - Layout.preferredHeight: 0 - } - }, - State { - name: "selected" - when: (selectedLibrary == "slides") - PropertyChanges { target: slideLibraryHeader } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: slideLibraryList - properties: "preferredHeight" - easing.type: Easing.OutCubic - duration: 300 - } + ListModel { + id: slideModel + ListElement { + title: "test" + items: [] } - Kirigami.ActionToolBar { - height: parent.height - width: parent.width - display: Controls.Button.IconOnly - visible: selectedLibrary == "slides" - actions: [ - Kirigami.Action { - icon.name: "document-new" - text: "New Slide" - tooltip: "Add a new slide" - onTriggered: slideLibraryList.newSlide() - /* visible: selectedLibrary == "slides" */ - }, - - Kirigami.Action { - displayComponent: Component { - Kirigami.SearchField { - id: searchField - height: parent.height - width: parent.width - 40 - onAccepted: showPassiveNotification(searchField.text, 3000) - } - } - /* visible: selectedLibrary == "slides" */ - } - ] - - Behavior on height { - NumberAnimation { - easing.type: Easing.OutCubic - duration: 300 - } - } + ListElement { + title: "Cool Slide" + items: [] } } - ListView { - id: slideLibraryList - Layout.preferredHeight: parent.height - 240 - Layout.fillWidth: true - Layout.alignment: Qt.AlignTop - state: "deselected" - - states: [ - State { - name: "deselected" - when: (selectedLibrary !== "slides") - PropertyChanges { target: slideLibraryList - Layout.preferredHeight: 0 - } - }, - State { - name: "selected" - when: (selectedLibrary == "slides") - PropertyChanges { target: slideLibraryList } - } - ] - - transitions: Transition { - to: "*" - NumberAnimation { - target: slideLibraryList - properties: "preferredHeight" - easing.type: Easing.OutCubic - duration: 300 - } - } - - Controls.ScrollBar.vertical: Controls.ScrollBar { - /* anchors.right: videoLibraryList.right */ - /* anchors.leftMargin: 10 */ - /* anchors.left: videoLibraryList.right */ - active: hovered || pressed - } - - } } DropArea { diff --git a/src/qml/presenter/MainWindow.qml b/src/qml/presenter/MainWindow.qml index 8605470..06d379b 100644 --- a/src/qml/presenter/MainWindow.qml +++ b/src/qml/presenter/MainWindow.qml @@ -133,6 +133,12 @@ Controls.Page { visible: false anchors.fill: parent } + + Presenter.SlideEditor { + id: slideEditor + visible: false + anchors.fill: parent + } } Presenter.Library { @@ -284,6 +290,7 @@ Controls.Page { videoEditor.stop(); imageEditor.visible = false; presentationEditor.visible = false; + slideEditor.visible = false; songEditor.visible = true; songEditor.changeSong(item); currentWindow = songEditor; @@ -293,6 +300,7 @@ Controls.Page { songEditor.visible = false; imageEditor.visible = false; presentationEditor.visible = false; + slideEditor.visible = false; videoEditor.visible = true; videoEditor.changeVideo(item); currentWindow = videoEditor; @@ -303,6 +311,7 @@ Controls.Page { videoEditor.stop(); songEditor.visible = false; presentationEditor.visible = false; + slideEditor.visible = false; imageEditor.visible = true; imageEditor.changeImage(item); currentWindow = imageEditor; @@ -313,10 +322,21 @@ Controls.Page { videoEditor.stop(); songEditor.visible = false; imageEditor.visible = false; + slideEditor.visible = false; presentationEditor.visible = true; presentationEditor.changePresentation(item); currentWindow = presentationEditor; break; + case "slide" : + presentation.visible = false; + videoEditor.visible = false; + videoEditor.stop(); + songEditor.visible = false; + imageEditor.visible = false; + presentationEditor.visible = false; + slideEditor.visible = true; + currentWindow = slideEditor; + break; default: videoEditor.visible = false; videoEditor.stop(); diff --git a/src/qml/presenter/SlideEditor.qml b/src/qml/presenter/SlideEditor.qml new file mode 100644 index 0000000..82734b8 --- /dev/null +++ b/src/qml/presenter/SlideEditor.qml @@ -0,0 +1,155 @@ + +import QtQuick 2.15 +import QtQuick.Controls 2.15 as Controls +import QtQuick.Dialogs 1.3 +import QtQuick.Layouts 1.15 +import QtWebEngine 1.10 +import org.kde.kirigami 2.13 as Kirigami +import "./" as Presenter +import org.presenter 1.0 + +Item { + id: root + + property var creationObject + + GridLayout { + id: mainLayout + anchors.fill: parent + columns: 2 + rowSpacing: 5 + columnSpacing: 0 + + Controls.ToolBar { + Layout.fillWidth: true + Layout.columnSpan: 2 + id: toolbar + + RowLayout { + anchors.fill: parent + + Controls.TextField { + id: slideTitleField + implicitWidth: 300 + placeholderText: "Title..." + text: "idk" + padding: 10 + onEditingFinished: updateTitle(text); + background: Presenter.TextBackground { + control: fontBox + } + } + + Controls.ComboBox { + id: alignBox + model: ["Left", "Center", "Right", "Justify"] + implicitWidth: 100 + hoverEnabled: true + background: Presenter.TextBackground { + control: alignBox + } + indicator: Kirigami.Icon { + anchors {right: parent.right + verticalCenter: parent.verticalCenter + rightMargin: 2} + source: "arrow-down" + rotation: fontBox.down ? 180 : 0 + color: fontBox.pressed ? Kirigami.Theme.focusColor : Kirigami.Theme.textColor + + Behavior on rotation { + NumberAnimation { + easing.type: Easing.OutCubic + duration: 300 + } + } + } + } + Controls.ToolSeparator {} + Item { Layout.fillWidth: true } + Controls.ToolSeparator {} + Controls.ToolButton { + text: "Text Box" + icon.name: "insert-text-frame" + hoverEnabled: true + onClicked: creationObject = "text" + } + Controls.ToolButton { + id: backgroundButton + text: "Image" + icon.name: "insert-image" + hoverEnabled: true + onClicked: creationObject = "image" + } + + Controls.Popup { + id: backgroundType + x: backgroundButton.x + y: backgroundButton.y + backgroundButton.height + 20 + modal: true + focus: true + dim: false + background: Rectangle { + Kirigami.Theme.colorSet: Kirigami.Theme.Tooltip + color: Kirigami.Theme.backgroundColor + radius: 10 + border.color: Kirigami.Theme.activeBackgroundColor + border.width: 2 + } + closePolicy: Controls.Popup.CloseOnEscape | Controls.Popup.CloseOnPressOutsideParent + ColumnLayout { + anchors.fill: parent + Controls.ToolButton { + Layout.fillHeight: true + Layout.fillWidth: true + text: "Slide" + icon.name: "emblem-presentations-symbolic" + /* onClicked: slideFileDialog.open() & backgroundType.close() */ + } + Controls.ToolButton { + Layout.fillWidth: true + Layout.fillHeight: true + text: "Slide" + icon.name: "folder-pictures-symbolic" + /* onClicked: slideFileDialog.open() & backgroundType.close() */ + } + } + } + } + } + + Rectangle { + id: slideCanvas + Layout.fillHeight: true + Layout.fillWidth: true + /* Layout.minimumWidth: 300 */ + Layout.alignment: Qt.AlignCenter + Layout.columnSpan: 2 + color: "white" + + MouseArea { + id: canvasMouse + anchors.fill: parent + } + } + } + + function createObject(objectType) { + let component = Qt.createComponent("TextBox.qml"); + if (component.status === Component.Ready || component.status === Component.Error) { + finishCreation(component); + } else { + component.statusChanged.connect(finishCreation); + } + } + + function finishCreation(component) { + if (component.status === Component.Ready) { + var image = component.createObject(slideCanvas, {"x": 100, "y": 100}); + if (image === null) { + console.log("Error creating image"); + } + } else if (component.status === Component.Error) { + console.log("Error loading component:", component.errorString()); + } + } +} diff --git a/src/qml/presenter/TextBox.qml b/src/qml/presenter/TextBox.qml new file mode 100644 index 0000000..d1e8709 --- /dev/null +++ b/src/qml/presenter/TextBox.qml @@ -0,0 +1,13 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 as Controls +import QtQuick.Layouts 1.15 +import QtGraphicalEffects 1.15 +import org.kde.kirigami 2.13 as Kirigami +import "./" as Presenter +import org.presenter 1.0 + +Controls.TextArea { + id: root + padding: 10 + textFormat: TextEdit.PlainText +} diff --git a/src/resources.qrc b/src/resources.qrc index ad8a5fb..5664f19 100644 --- a/src/resources.qrc +++ b/src/resources.qrc @@ -14,6 +14,7 @@ qml/presenter/VideoEditor.qml qml/presenter/ImageEditor.qml qml/presenter/PresentationEditor.qml + qml/presenter/SlideEditor.qml qml/presenter/Slide.qml qml/presenter/SlidesListView.qml qml/presenter/SongEditorSlideList.qml @@ -26,6 +27,7 @@ qml/presenter/RangedSlider.qml qml/presenter/NewVideo.qml qml/presenter/TextBackground.qml + qml/presenter/TextBox.qml qml/presenter/LoadingSpinner.qml assets/parallel.jpg assets/black.jpg diff --git a/src/rust/slides/mod.rs b/src/rust/slides/mod.rs new file mode 100644 index 0000000..e9a6667 --- /dev/null +++ b/src/rust/slides/mod.rs @@ -0,0 +1 @@ +pub use slide; diff --git a/src/rust/slides/slide.rs b/src/rust/slides/slide.rs new file mode 100644 index 0000000..6fa1ce6 --- /dev/null +++ b/src/rust/slides/slide.rs @@ -0,0 +1,4 @@ +pub struct Slide {} + +#[cxx_qt::bridge] +mod slide {} diff --git a/src/rust/utils.rs b/src/rust/utils.rs index 0b63618..274c564 100644 --- a/src/rust/utils.rs +++ b/src/rust/utils.rs @@ -8,7 +8,7 @@ use tracing_subscriber::{ EnvFilter, }; -use self::utilities::QString; +use self::utilities::{QString, QUrl}; mod db { use diesel::{Connection, SqliteConnection};